Có rất nhiều công cụ hỗ trợ quá trình dịch ngược, trong đó IDAPro là một công cụ tương đối mạnh và phổ biến. Ở bài viết lần này chúng ta sẽ tiến hành phân tích mã độc dựa trên việc sử dụng IDA PRO. Trước khi phân tích mã độc cần phải làm quen với các công cụ, việc quen thuộc với các tính năng của các công cụ sẽ hỗ trợ việc phân tích nhanh chóng và hiệu quả hơn. Phần 1 của chủ đề này sẽ lần lượt đi tìm hiểu các nội dung: Giao diện của IDA Pro; sử dụng các tham chiếu chéo; phân tích hàm.
IDA Pro (The Interactive Disassembler Professional) là một công cụ dịch ngược rất mạnh, được phân phối bởi Hex-Rays. IDA Pro không phải là công cụ dịch ngược duy nhất, nhưng nó là lựa chọn hàng đầu của nhiều chuyên gia phân tích mã độc, chuyên gia dịch ngược và nhà phân tích lỗ hổng.
IDA Pro hỗ trợ kiến trúc x86, x64 và một số kiến trúc khác. Nó cho phép dịch ngược nhiều định dạng file thực thi: PE, COFF, ELF và a.out. Ta sẽ tập trung vận dụng IDA Pro để phân tích các file thực thi PE trên kiến trúc x86 và x64.
IDA Pro sẽ dịch ngược toàn bộ một chương trình và thực hiện các tác vụ như khám phá hàm, xác định biến cục bộ,… Tất cả các chức năng của công cụ này đều có thể được chỉnh sửa, quản lý, sắp xếp lại hay định nghĩa lại, đúng với tính chất “tương tác” trong cái tên của nó. Một tính năng hay nhất của IDA Pro là khả năng lưu tiến trình phân tích: Ta có thể thêm chú thích, gắn nhãn cho dữ liệu, đặt tên cho các hàm và lưu lại tiến trình đang phân tích vào cơ sở dữ liệu của IDA (idb) để tiếp tục phân tích về sau. IDA Pro cũng hỗ trợ rất tốt cho các plug-in nên ta có thể tự viết các extension hoặc sử dụng các extension từ nhà phát triển khác.
Trong bài viết này tôi sẽ chỉ ra những bước khởi đầu vững chắc trong việc phân tích mã độc sử dụng IDA Pro. Để đào sâu khai thác công cụ này hiệu quả hơn, các bạn có thể tham khảo thêm cuốn The IDA Pro Book: The Unofficial Guide to the World’s Most Popular Disassembler, 2nd Edition của Chris Eagles.
Tải một file thực thi vào IDA Pro
Hình bên dưới thể hiện bước đầu tiên khi tải một file thực thi vào IDA Pro. Khi ta tải một file thực thi, IDA Pro sẽ cố gắng xác định định dạng file và kiến trúc vi xử lý mà file được sinh ra để phục vụ. Trong ví dụ này, file được phát hiện có định dạng PE (1) và kiến trúc Intel x86 (2). Trừ khi ta thực hiện phân tích một mã độc chạy trên thiết bị điện thoại chẳng hạn (hoạt động trên kiến trúc vi xử lý khác), ta thường không phải thay đổi thông tin hệ vi xử lý thường xuyên.
Khi tải một file vào IDA Pro (chẳng hạn PE file), chương trình sẽ nạp file đó vào bộ nhớ để phòng khi file đã được tải bởi OS loader. Để IDA dịch ngược file như một tập nhị phân thô, ta chọn tùy chọn Binary file trong hộp chọn trên cùng (3). Tùy chọn này có thể hữu ích vì mã độc đôi khi chứa shellcode, dữ liệu bổ sung, các đối số mã hóa hay thậm chí các file thực thi bổ sung và các dữ liệu kiểu này sẽ không được tải vào bộ nhớ khi mã độc thực thi bởi Windows hay được tải vào IDA Pro.
Các file PE được biên dịch để tải vào một địa chỉ đã được chỉ định sẵn trong bộ nhớ và nếu Windows loader không thể tải nó vào địa chỉ đã chỉ định đó (vì địa chỉ đó đã được sử dụng từ trước), loader sẽ thực hiện một thao tác gọi là rebasing. Thao tác này thường được áp dụng với các DLL vì chúng thường được tải vào những vùng khác với địa chỉ chỉ định sẵn. Ta sẽ tìm hiểu sâu về rebasing ở các phần sau. Còn bây giờ, nếu ta bắt gặp một DLL được tải vào một tiến trình mà khác với những gì ta thấy nó trong IDA Pro, chỉ cần biết đó có thể là kết quả của việc rebase. Khi điều này xảy ra, hãy chọn Manual Load trong danh sách checkbox của cửa sổ Load a new file (4) và ta sẽ thấy một hộp nhập đầu vào, nơi ta có thể chỉ định địa chỉ ảo mới để tải file.
Mặc định IDA Pro không đưa ra PE header hay resource section (nơi mà mã độc thường che giấu code độc hại) trong kết quả dịch ngược. Nếu ta chỉ định Manual Load, IDA Pro sẽ cho phép chọn phần nào để tải, từng phần một, bao gồm cả PE header, và ta sẽ không bỏ lỡ những manh mối quan trọng trong tiến trình phân tích mã độc.
Giao diện của IDA Pro
Sau khi tải một chương trình vào IDA Pro, ta sẽ được chuyển tới cửa sổ dịch ngược, không gian chính để quản lý và phân tích code hợp ngữ.
Các chế độ cửa sổ dịch ngược (IDA View)
Ta có thể hiển thị cửa sổ dịch ngược ở một trong hai chế độ: biểu đồ (mặc định) và text. Để chuyển giữa 2 chế độ, nhấn nút Space.
Chế độ biểu đồ
Trong chế độ này, IDA Pro đưa ra các thông tin chính xác mà ta nên hiển thị, chẳng hạn như số dòng và code thực thi. Để thay đổi các tùy chọn này, chọn Options > General, sau đó chọn Line prefixes và set Number of Opcode Bytes là 6. Vì hầu hết các lệnh đều chứa 6 hoặc ít hơn 6 byte, thiết lập này cho phép ta nhìn thấy các vùng nhớ và giá trị Opcode cho từng lệnh.
Trong chế độ Biểu đồ, màu và các chỉ dẫn mũi tên giúp biểu diễn luồng thực thi của chương trình trong khi phân tích. Màu của mũi tên cho ta biết luồng thực thi dựa trên các lựa chọn rẽ nhánh: màu đỏ nếu lệnh nhảy có điều kiện không được thực hiện, màu xanh lá cây nếu lệnh nhảy được thực hiện và màu xanh da trời cho các lệnh nhảy không điều kiện. Hướng của mũi tên cũng chỉ ra luồng thực thi của chương trình; mũi tên hướng ngược lên thường là ở vị trí vòng lặp.
Chế độ Text
Chế độ Text nhìn truyền thống hơn và ta phải sử dụng nó để xem vùng dữ liệu của một file nhị phân. Hình phía dưới minh họa chế độ text của một hàm đã được dịch ngược. Nó hiển thị địa chỉ nhớ (0040267E) và tên section (.text) mà trong đó opcode (8B450C) sẽ được lưu trong bộ nhớ (1).
Phần bên trái hiển thị các mũi tên thể hiện luồng thực thi không tuyến tính của chương trình. Các đường mũi tên liền đánh dấu lệnh nhảy không điều kiện và đường mũi tên nét đứt là lệnh nhảy có điều kiện. Mũi tên hướng lên trên đánh dấu một vòng lặp. Ví dụ này cũng bao minh họa bố trí của stack tại (2) và một chú thích (bắt đầu bằng dấu chấm phẩy) được thêm tự động bởi IDA Pro (3).
Nếu vẫn tiếp tục nghiên cứu code hợp ngữ, ta sẽ thấy chức năng tự động thêm chú thích của IDA Pro là rất hữu dụng. Để sử dụng tính năng này, chọn Options > General và chọn checkbox Auto comments.
Các cửa sổ phân tích hữu ích
Một số cửa sổ khác của IDA Pro nhấn mạnh các mục cụ thể trong file thực thi. Sau đây là các mục có ý nghĩa nhất cho mục đích phân tích.
- Cửa sổ hàm liệt kê tất cả các hàm trong file thực thi và thể hiện độ dài mỗi hàm. Ta có thể sắp xếp theo độ dài hàm kết hợp bộ lọc cho những hàm lớn và phức tạp mà có thể sẽ chứa nhiều thông tin hữu ích cho việc phân tích. Cửa sổ này cũng liên hệ các cờ với mỗi hàm (F, L, S,…), cờ hữu ích nhất là cờ L, biểu thị hàm thư viện. Cờ L giúp tiết kiệm thời gian phân tích vì ta có thể nhận biết và bỏ qua các hàm được tạo bởi trình biên dịch (compiler-generated). Để hiển thị cửa sổ hàm, chọn View > Open subviews >Functions hoặc đơn giản là nhấn tổ hợp phím Shift + F3.
- Cửa sổ tên liệt kê mọi địa chỉ với một tên, bao gồm các hàm, đoạn code được đặt tên, dữ liệu được đặt tên và các chuỗi string. Để hiển thị cửa sổ tên, trong Open subviews chọn Names hoặc nhấn tổ hợp Shift + F4.
- Cửa sổ Strings hiển thị tất cả các chuỗi string. Trong Open subviews, chọn Strings hoặc nhấn tổ hợp Shift + F12 để gọi cửa sổ Strings. Mặc định, IDA chỉ liệt kê các string dạng ASCII dài hơn 5 ký tự. Ta có thể thay đổi thiết lập này bằng cách chuột phải trong cửa sổ Strings và chọn Setup.
- Cửa sổ Imports Liệt kê các Import, tương tự chức năng của PEiD hay DIE.
- Cửa sổ Exports Liệt kê các hàm export, tương tự PEiD hay DIE, hữu ích khi phân tích các DLL.
- Cửa sổ cấu trúc Liệt kê bố trí của tất cả các cấu trúc dữ liệu. Cửa sổ này cũng cung cấp khả năng tạo mới các cấu trúc dữ liệu của mình và sử dụng như các memory layout template.
Các cửa sổ này cũng cung cấp tính năng tham chiếu chéo (cross-reference) đặc biệt hữu dụng khi định vị đoạn code quan trọng. Ví dụ, để tìm tất cả các đoạn code cùng gọi đến một hàm Import nào đó, ta có thể sử dụng cửa sổ Imports, click đúp vào hàm mà ta quan tâm rồi dùng tham chiếu chéo để xác định các lời gọi import trong danh sách code.
Quay lại các cửa sổ mặc định
Giao diện của IDA Pro đa dạng đến nỗi sau khi nhấn vài tổ hợp phím hay click vào thứ gì đó, ta đã có thể “bị lạc” mất giao diện chính. Trong trường hợp này, chỉ cần chọn Windows > Reset desktop để quay lại giao diện mặc định. Chọn tùy chọn này sẽ không hủy (undo) bất kì nhãn hay tiến trình dịch ngược nào mà ta đã thực hiện trước đó; nó chỉ đơn giản là khôi phục các cửa sổ và thành phần giao diện về như thiết lập mặc định. Bởi lẽ ấy, nếu tùy chỉnh giao diện mà thấy thích những gì đang được hiển thị, ta có thể lưu giao diện mình thích lại bằng việc chọn Windows > Save desktop.
Điều hướng trong IDA Pro
Như vừa thấy, IDA Pro có thể được điều hướng một các linh hoạt. Nhiều cửa sổ được liên kết với cửa sổ IDA View. Ví dụ, click đúp vào một entry trong cửa sổ Imports hay cửa sổ Strings sẽ dẫn ta đến dòng code trong cửa sổ dịch ngược của entry đó.
Sử dụng Liên kết và Tham chiếu chéo
Một cách khác để điều hướng trong IDA Pro là dùng các liên kết trong cửa sổ IDA View, chẳng hạn như các liên kết trong hình phía dưới. Click đúp vào bất kì liên kết (1) nào sẽ hiển thị vị trí đích trong cửa sổ IDA View.
Các loại liên kết phổ biến thường là:
- Sub links là liên kết đến khởi đầu hàm chẳng hạn như sub_403BD6 hay sub_4043B6.
- Loc links là liên kết đến đích của lệnh nhảy như loc_4049EF hay loc_404AF3.
- Offset links là liên kết đến một offset trong bộ nhớ.
Các tham chiếu chéo (cross-reference, hiển thị tại (2) trong hình phía trên và hình phía dưới) rất hữu dụng để hiển thị vùng tham chiếu: 0x4043B6 trong ví dụ này (lệnh jnz loc_404ADC tại địa chỉ 0x4043B6 thực hiện nhảy có điều kiện đến vị trí loc_404ADC, là vị trí mà ta đang xét ở đây).
Các chuỗi strings cũng thường là các tham chiếu và liên kết điều hướng.
Sử dụng lịch sử
Nút Forward và Back giúp ta dễ dàng chuyển trạng thái trong lịch sử, tương tự như hai nút Forward và Back trong trình duyệt web. Mỗi lần ta chuyển hướng tới một vị trí mới trong cửa sổ IDA View, vị trí đó sẽ được lưu vào lịch sử. |
Dải điều hướng
Dải màu nằm ngang dưới thanh công cụ là Dải điều hướng, sử dụng các màu khác nhau để minh họa tuyến tính không gian địa chỉ của của các file nhị phân liên quan được tải vào bộ nhớ. Các màu sắc cho phép nhìn nhanh vào nội dung trong từng vùng của file:
- Màu xanh da trời nhạt là các code thư viện được ghi nhận bởi F.L.I.R.T.
- Màu đỏ là các code sinh ra bởi trình biên dịch (compiler-generated code).
- Màu xanh tối là code viết bởi tác giả mã độc.
Ta chỉ cần thực hiện phân tích đối với vùng màu xanh tối. Khi cảm thấy mất phương hướng trong đống code lộn xộn, dải điều hướng có thể giúp ta định hướng lại. Màu mặc định cho vùng dữ liệu trong IDA Pro là màu hồng cho các Imports, màu xám cho các dữ liệu được định nghĩa và màu nâu đối với các dữ liệu chưa được định nghĩa.
Nếu sử dụng các phiên bản cũ của IDA Pro, các chữ ký F.L.I.R.T có thể không được cập nhật dẫn đến việc nhiều code thư viện được tính là code viết bởi tác giả mã độc. F.L.I.R.T là không hoàn hảo, thỉnh thoảng nó không ghi nhận và gắn nhãn được hết tất cả các code thư viện một cách chính xác.
Nhảy đến một vùng nhớ
Để nhảy đến bất cứ địa chỉ bộ nhớ ảo nào, đơn giản là nhấn nút G khi đang ở trong cửa sổ IDA View. Một hộp thoại sẽ xuất hiện, yêu cầu nhập địa chỉ bộ nhớ ảo hoặc tên của vùng nhớ (nếu nó đã được đánh tên), chẳng hạn như sub_403BD6.
Để nhảy tới một offset của một file nhị phân thô, chọn Jump > Jump to File Offset. Chẳng hạn, nếu ta xem xét một file PE trong một hex editor và phát hiện điều gì đó khả nghi, như một string hay một shellcode, ta có thể sử dụng tính năng nhảy của IDA Pro để nhảy tới raw offset đó vì khi file được tải vào IDA Pro, nó sẽ được nạp vào bộ nhớ như thể nó đã được tải bởi OS loader.
Tìm kiếm
Chọn Search trong menu để hiển thị các tùy chọn cho phép chuyển vị trí con trỏ chuột trong màn hình IDA View:
- Chọn Search > Next Code để chuyển tới vùng nhớ tiếp theo chứa lệnh mà ta muốn tìm.
- Chọn Search > Text để tìm kiếm một chuỗi string nào đó trong toàn bộ cửa sổ IDA Vew.
- Chọn Search > Sequence of Bytes để thực hiện tìm kiếm nhị phân trong cửa sổ Hex View cho một chuỗi byte cụ thể. Tùy chọn này có thể hữu ích khi tìm kiếm dữ liệu cụ thể hoặc Opcode.
Ví dụ sau biểu diễn phân tích dòng lệnh đối với file nhị phân password.exe. Mã độc này yêu cầu nhập đúng password để tiếp tục thực thi và sẽ in ra chuỗi “Bad key” nếu ta nhập sai password (test).
—————————————————————————————————————————-
C:\>password.exe
Enter password for this Malware: test
Bad key
—————————————————————————————————————————-
Ta tải file nhị phân này vào IDA Pro, thử sử dụng tính năng tìm kiếm và liên kết để mở khóa chương trình này. Ta bắt đầu bằng việc tìm kiếm cho tất cả các chuỗi “Bad key” trong chương trình và phát hiện chuỗi này được sử dụng tại địa chỉ 0x401104. Ta sẽ nhảy đến vị trí đó trong cửa sổ IDA View bằng cách click đúp vào entry của nó trong cửa sổ tìm kiếm.
Tìm kiếm trong cửa sổ hợp ngữ, trước chuỗi “Bad key”, ta thấy một phép so sánh tại 0x4010F1 để kiểm tra kết quả của một hàm strcmp. Một trong các tham số của hàm strcmp là một chuỗi string, $mab, có thể nó chính là password.
—————————————————————————————————————————-
004010E0 push offset aMab ; “$mab”
004010E5 lea ecx, [ebp+var_1C]
004010E8 push ecx
004010E9 call strcmp
004010EE add esp, 8
004010F1 test eax, eax
004010F3 jnz short loc_401104
004010F5 push offset aKeyAccepted ; “Key Accepted!\n”
004010FA call printf
004010FF add esp, 4
00401102 jmp short loc_401118
00401104 loc_401104 ; CODE XREF: _main+53j
00401104 push offset aBadKey ; “Bad key\n”
00401109 call printf
—————————————————————————————————————————-
Ví dụ dưới đây biểu diễn kết quả của việc nhập password mà ta vừa phát hiện ra, $mab:
—————————————————————————————————————————-
C:\>password.exe
Enter password for this Malware: $mab
Key Accepted!
The malware has been unlocked
—————————————————————————————————————————-
Ví dụ này chứng minh ta có thể sử dụng tính năng tìm kiếm và liên kết trong IDA Pro để thu thập thông tin về mẫu nhị phân cần phân tích nhanh chóng như thế nào.
Sử dụng tham chiếu chéo
Một tham chiếu chéo, trong IDA Pro gọi là xref, giúp ta xác định một hàm được gọi từ đâu hay một string được sử dụng ở đoạn nào. Nếu ta xác định được một hàm hữu ích và muốn biết các tham số được gọi cùng hàm đó, ta có thể dùng thàm chiếu chéo để nhanh chóng định hướng tới vùng mà các tham số đó được đặt trong stack. Các biểu đồ trực quan cũng có thể được tạo dựa trên các tham chiếu chéo.
Tham chiếu chéo code
Hình bên dưới minh họa một tham chiếu chéo tại (1) cho thấy hàm này (sub_40264F) được gọi từ hai vị trí bên trong hàm sub_40254B: offset 0x29 và offset 0x62. Tham chiếu chéo code tại (2) chỉ ra lệnh nhảy nào sẽ nhảy tới vị trí này, cụ thể là lệnh jmp tại offset 0x102 của hàm sub_40254B (3) (địa chỉ 0x40264D).
Mặc định, IDA Pro chỉ đưa ra một vài tham chiếu chéo cho bất kì hàm nào. Để hiển thị tất cả các tham chiếu chéo cho một hàm, click vào tên hàm và nhấn nút X trên bàn phím. Cửa sổ hiện ra liệt kê tất cả vùng nhớ mà hàm này được gọi. Danh sách tham chiếu của cửa sổ Xrefs liệt kê các tham chiếu chéo của hàm sub_402457, ta có thể thấy hàm này được gọi 4 lần.
Click đúp vào bất kì entry nào trong cửa sổ Xrefs để chuyển tới vị trí tham chiếu tương ứng trong cửa sổ IDA View.
Tham chiếu chéo dữ liệu
Tham chiếu chéo dữ liệu thường được dùng để theo dõi cách mà dữ liệu được truy cập trong một file nhị phân. Tham chiếu dữ liệu có thể liên kết bất kỳ byte dữ liệu nào trong code thông qua một tham chiếu bộ nhớ. Ví dụ, ta có thể thấy tham chiếu chéo dữ liệu tới offet loc_405887. Dữ liệu này được sử dụng trong vị trí offset 0x44 của hàm sub_40583C.
Ngay từ chương 1 ta đã thấy tìm kiếm các chuỗi string là điểm khởi đầu tốt cho việc phân tích tĩnh, như một suy nghĩ tự nhiên. Nếu thấy bất kì một string nào khả nghi, ta có thể dùng tính năng tham chiếu chéo của IDA Pro để xem chính xác chuỗi string đó được sử dụng ở vị trí nào và được sử dụng như thế nào trong code.