Malware Analysis

1. Tầm quan trọng

  • Khi dump ra một file thực thi nghi ngờ là malware trong lúc điều tra, rất có khả năng xảy ra vấn đề file bị hỏng ở một số section, dẫn đến việc khó khăn trong quá trình phân tích tĩnh và động. Vì vậy để khai thác, phân tích malware đạt hiểu quả, việc hiểu rõ cấu trúc file PE rất quan trọng.

2. Các thuật ngữ cần chú ý

  • VA (Virtual Address) là địa chỉ ảo khi chương trình được load vào bộ nhớ.
  • Base address là địa chỉ cở sở khi chương trình được nạp vào bộ nhớ, được thể hiện trong trường ImageBase của NT additional section.
  • RVA (Ralative Virtual Address) là địa chỉ ảo tương đối của file, giá trị này được tính toán như sau:

    RVA = VA – Base Address

  • File offset là thuật ngữ dùng để chỉ vị trí của một trường, hoặc một giá trị trong raw file.

    File_offset = (RVA – pSect->VirtualAddress) + pSect->PointerToRawData

3. Chi tiết các phần trong PE file

DOS MZ HEADER

DOS MZ header (64 bytes) chứa các thông tin cơ bản về của một PE file hợp lệ.

Với Header này, trường e_lfanew tại offset 0x3C là quan trọng, nó chứa offset bắt đầu của PE header.

PE HEADER

Header này bắt đầu từ offset được chỉ tại trường e_lfanew. Một số trường cần chú ý:

  • Machine: xác định loại machine của file (Intel 386, Intel 64, MIPS, ARM, …).
  • Number of Sections: số lượng section trong section table.
  • SizeOfOptionalHeader: kích thước của Optional header.
  • Characteristics: xác định đặc điểm của file (exe, dll, …).

OPTIONAL HEADER

STANDARD FIELDS

Các trường cần chú ý:

  • Magic: là một số nguyên không dấu xác định trạng thái của file, 0x10B cho 32bit, 0x20B cho 64bit.
  • AddressOfEntryPoint: Đây là một trường quan trọng, lưu trữ địa chỉ ảo tương đối (RVA) của câu lệnh đầu tiên mà chương trình thực thi.
  • SizeOfCode: kích thước của code thực thi.
  • SizeOfInitializedData: kích thước của dữ liệu được khởi tạo.
  • BaseOfCode: chứa địa chỉ RVA của phần code.

NT ADDITIONAL FIELDS

  • ImageBase: Địa chỉ được ưu tiên nạp vào memory cho PE file, mặc định là 0x00400000.
  • SectionAlignment: Phần liên kết các các section trong bộ nhớ, tức là một section luôn luôn bắt đầu bằng bội số của SectionAlignment. Ví dụ section thứ nhất là 0x00401000 thì section thứ hai sẽ là 0x00402000.
  • FileAlignment: Phần liên kết các section trong file, tương tự như SectionAlignment như sử dụng trong raw file.
  • SizeOfImage: Toàn bộ kích thước của file trong bộ nhớ bao gồm cả header, sẽ là bội của SectionAlignment.
  • SizeOfHeaders: kích thước của toàn bộ header, bao gồm: MS-DOS header, PE file header, PE optional header, và PE section header.
  • NumberOfRvaAndSizes: xác định kích thước của Data Directory.
  • DataDirectory: là nơi chứa các thông tin thực thi quan trọng của file. DataDirectory là một mảng cấu trúc IMAGE_DATA_DIRECTORY được cấp phát tại phần kết thúc của Optional Header.

Section Header

Section chứa các nội dung chính của file, bao gồm code, data, resources, và các thông tin thực thi khác. Mỗi section sẽ 40 bytes và được chia thành hai phần: header, data.

  • Name: tên section, có thể trống.
  • PhysicalAddress / Virtual Size: kích thước data thực tế của section (bytes). Nó có thể nhỏ hơn kích thước của section trên disk.
  • SizeOfRawData: kích thước data của section trên disk.
  • PointerToRawData: chứa offset tại điểm bắt đầu data của section.

Các section thường gặp nhất như:

  • .text section: chứa mã thực thi, IAT của chương trình. Vì Windows NT sử dụng hệ thống quản lý bộ nhớ ảo dựa trên trang (page), do đó sẽ rất khó quản lý nếu như tách các đoạn mã thành từng phần riêng biệt.
  • .bss section: chứa các dữ liệu chưa được khởi tạo.
  • .data section: chứa các dữ liệu đã được khởi tạo (read-only) trên hệ thống.
  • .rsrc section: chứa các thông tin resource.
  • .edata section: chứa các export directory của application hoặc DLL.
  • .idata section: chứa các thông tin về import functions, bao gồm import directory và import address table (IAT).
  • .tls section: trường này chứa các thông tin về Threat Local Storage (đây là một section rất quan trọng trong phân tích mã độc).

Export Directory section

Export là các function và giá trị trong một module được khai báo để chia sẻ với các module khác.

Section này phổ biến trong các tệp DLL. DLL có thể export function trong hai cách: function name hoặc oridinal number.

  • Name: chứa địa chỉ RVA trỏ đến internal name của module.
  • Base: Chứa số thứ tự sẽ bắt đầu.
  • NumberOfFunctions: tổng số function được export bởi module.
  • NumberOfNames: Số function được export bằng tên.
  • AddressOfFunctions: chứa địa chỉ ảo (RVA) trỏ đến một mảng RVA của funtion trong module (EAT).
  • AddressOfNames: chứa địa chỉ RVA trỏ đến một mảng RVA của tên các function trong module (ENT).
  • AddressOfNameOrdinals: chứa địa chỉ RVA trỏ đến mảng 16 bit chứa thứ tự của các function được đặt tên (EOT).

Import Directory

Đây là section quan trọng nhất trong quá trình sửa lại PE file, chứa các thông tin về tất cả các funtion được import vào file.

Mỗi cấu trúc của nó là 20 bytes, được mô tả như sau:

  • OriginalFirstThunk: chứa địa chỉ RVA của Import Lookup Table (ILT) hoặc Import Name Table (INT). ILT chứa thông tin cách mà import sẽ được xử lý bằng Name hoặc Ordinal.
  • Name: chứa địa chỉ RVA đến tên của module (DLL).
  • FirstThunk: chứa địa chỉ RVA đến một cấu trúc IMAGE_THUNK_DATA, còn được gọi là Import Address Table (IAT).

Thêm một section mới vào PE file?

Ở phần trước tôi đã đề cập thông tin cơ bản về cấu trúc của một PE file. Phần này để cụ thể hóa vấn đề tôi sẽ hướng dẫn cách thêm một section mới vào file PE.

Thêm section mới vào tệp thực thi, vậy nhưng offset nào sẽ thay đổi? Làm sao để đảm bảo cho file vẫn hợp lệ? Section mới được nạp vào bộ nhớ đúng cách?

Lưu ý: Chúng ta có thể tìm thấy công cụ để thực hiện điều này một cách dễ dàng và nhanh chóng. Tuy nhiên việc làm bằng tay giúp ta học và hiểu nhiều hơn về định dạng file PE.

Tôi sẽ sử dụng một ứng dụng quen thuộc với tất cả chúng ta trong bài viết này

UniKeyNT.exe

Đầu tiên ta xem thông tin các section hiện có:

Như hình, ta thấy file UniKeyNT.exe hiện đang có 7 sections cùng với các thông tin liên quan tới từng section này. Tiếp theo ta mở với chế độ hex editer. Giả sử tôi sẽ thêm một section mới có độ dài 110h bytes:

    Thêm 110h bytes 00 vào file thực thi. (đây là thông tin section, có thể thay bằng đoạn shellcode tùy chỉnh)

    Sửa PE Header:

  • Tăng số sections (tại offset 06 bắt đầu từ PE Header).
  • Tăng Image Size.
  • Thêm section mới vào section table.

Đây là kết quả thêm section thành công:

Cảm ơn và hẹn gặp lại.

                                  (dt97_Malware_Analysis)

Chia sẻ