Phân tích thành phần rootkit VideoAti0.sys của mẫu Nailuj(Allinone)
Mở đầu: Tiếp tục với loạt bài phân tích mã độc ở mức kernel, hôm nay chúng ta sẽ phân tích một mẫu rootkit khá nổi tiếng là thành phần của nailuj hay allinone. Nailuj là một file thực thi có đuôi exe (còn gọi là dropper-cài đặt rootkit), khi thực thi, nó sẽ thực hiện cài đặt và khởi động rootkit, có 3 file quan trong được cài vào là VideoAti0.sys, VideoAti0.dll, VideoAti0.exe. Sau khi thực hiện cài đặt, file exe này sẽ tự xóa. Chúng ta sẽ phân tích thành phần kernel VideoAti0.sys này để xem hành vi và các kỹ thuật mà malware này thực hiện.
File cần phân tích: VideoAti0.sys.
MD5: 7A9691D46BB010CB533C6D7FB26E92D5
Công cụ sử dụng: IDA, WinDbg.
MD5: 7A9691D46BB010CB533C6D7FB26E92D5
Công cụ sử dụng: IDA, WinDbg.
Yêu cầu bạn đọc:
- Có kiến thức cơ bản về kernel windows, Windows Drivers, Rootkit, Assembly
- Có kiến thức cơ bản về sử dụng tool IDA, WinDbg
Mã:
|
Sau đó nó sẽ tìm kiếm module Nt trong hệ thống, rootkit sẽ duyệt toàn bộ danh sách các driver được tải lên nói trên, sau đó tìm kiếm. Nếu tên của module có chứa xâu “krnl” thì rootkit xác định đó là Nt module. Đoạn mã thể hiện việc duyệt danh sách như sau:
Mã:
|
Sau đây là một số hành vi chính của rootkit:
1. Ẩn giấu registry
Để có thể ẩn giấu được khóa registry của rootkit, nhằm không cho người dùng phát hiện ra, rootkit thực hiện hook (móc vào) một hàm dùng để duyệt registry của hệ thống, ở đây là hàm CmEnumerateKey nằm ở module Nt, hàm CmEnumerateKey có chữ kí như sau:
Sử dụng lệnh u Nt!CmEnumerateKey trong WinDbg ta được kết quả:
Mã:
|
Ta thấy 2 lệnh push và ret, lệnh push thực hiện đẩy tham số trong lệnh vào stack, còn lệnh ret sẽ lấy giá trị đỉnh của stack và thực hiện lệnh có địa chỉ là giá trị đỉnh của stack. Khi thực hiện lênh trên, số phần tử trong stack giảm đi 1. Tham số trong lệnh push là offset VideoAti0+0x12d4,là một địa chỉ bên trong module VideoAti0, là module của rootkit, như vậy ta thấy rằng hàm CmEnumerateKey đã được chuyển hướng để gọi tới hàm của rootkit, kĩ thuật này là kĩ thuật Inline Hook. Theo kĩ thuật này, 6 byte đầu tiên của hàm sẽ bị ghi đè, trong đó byte đầu tiên là 68h là mã hexa của lệnh push, 4 byte tiếp theo là địa chỉ của hàm sẽ chuyển tới, byte cuối cùng là C3 là mã hexa của lệnh ret. Để có thể chuyển hướng hàm bằng kĩ thuật này, rootkit tắt chức năng Write Protection của windows, bằng cách xóa cờ WP của thanh ghi CR0. Đoạn mã xóa cờ WP như sau:
Mã:
|
Một số hành vi trong hàm được chuyển hướng từ hàm CmEnumerateKey:
- Che giấu với các tiến trình fhs.exe và knlsc13.exe, nếu tiến trình gọi hàm có tên là một trong 2 chuỗi “fhs.exe” và “knlsc13.exe” thì hàm.
- Che giấu key, rootkit che giấu 2 key là LEGACY_VIDEOATI0 và VideoAti0.
Trước khi quay về hàm ban đầu của windows, rootkit sẽ khôi phục lại 6 byte như cũ để đảm bảo không nảy sinh vòng lặp gọi hàm vô hạn.
2. Thay đổi một số hàm majorfunction của file system
Mục đích: ẩn giấu file của rootkit cùng một số file khác.
Thứ tự thực hiện hành vi của rootkit:
- Lấy địa chỉ của NTFS, FastFat.
- Hook IRP_MJ_CREATE.
- Hook IRP_MJ_DIRECTORY_CONTROL.
Ví dụ một đoạn mã hook các hàm của NTFS và FastFat:
Mã:
|
trong đó a1 là chỉ số của hàm trong bảng majorfunction, a1 có thể là IRP_MJ_CREATE hoặc IRP_MJ_DIRECTORY_CONTROL, a3 là địa chỉ hàm của rootkit để thay vào.
Với hàm bị chuyển hướng ở vị trí IRP_MJ_CREATE: hàm của rootkit sẽ trả lại STATUS_ACCESS_DENIED khi mở một trong các file: FastFat.sys, Ntfs.sys, Ntfs.sys, tmp.hiv. Đoạn mã thực hiện hành vi này của rootkit như sau:
Mã:
|
Với hàm bị chuyển hướng ở vị trí IRP_MJ_DIRECTORY_CONTROL: hàm mới của rootkit thực hiện hành vi ẩn giấu file VideoAti.sys, VideoAti.dll, VideoAti.exe. Mỗi khi hàm ở ở vị trí IRP_MJ_DIRECTORY_CONTROL của Ntfs và FastFat được gọi, ta sẽ lấy được một danh sách liên kết các cấu trúc định nghĩa như sau:
Mã:
|
trong đó trường NextEntryOffset là vị trí của phần tử tiếp theo trong danh sách liên kết. Với danh sách này, rootkit thực hiện duyệt từng phần tử để kiểm tra, nếu gặp phần tử chưa tên file cần ẩn giấu thì rootkit thực hiện loại bỏ nó khỏi danh sách bằng cách gán giá trị trường NextEntryOffset của phần tử đứng trước nó thành giá trị trường NextEntryOffset của trường cần loại bỏ.
3. Tự ẩn giấu
Rootkit sẽ tự ẩn mình khỏi hệ thống, nghĩa là người dùng sẽ không thể thấy được rootkit đang hoạt động. Như ở trên, rootkit đã lấy được PsLoadedModuleList, là danh sách các driver được tải lên. Một phần tử trong danh sách có cấu trúc:
Mã:
|
trong đó trường le_mod có kiểu được định nghĩa:
Mã:
|
Trường Flink trỏ tới phần tử kế tiếp trong danh sách, còn trường Blink trỏ tới phần tử đứng ngay trước trong danh sách. Rootkit duyệt danh sách PsLoadedModuleList này, nếu gặp phần tử có trường driver_Name chứa xâu “VideoAti0” thì thực hiện loại bỏ phần tử này khỏi danh sách. Việc loại bỏ này giống như việc loại bỏ một phần tử khỏi danh sách liên kết đôi.
4. Tự khởi động cùng windows
Rootkit thực hiện đăng kí một hàm callback bằng cách gọi hàm PsSetCreateProcessNotifyRoutine().
v7 = PsSetCreateProcessNotifyRoutine(NotifyRoutine, 0);
Bằng cách gọi hàm này, thì hàm callback của rootkit sẽ được gọi mỗi khi một tiến trình được tạo hay bị xóa. Bên trong hàm callback này, lại có một hàm con nữa, hàm sẽ được gọi khi tiến trình có tên là “userinit.exe” được tạo ra. Hàm con này thực hiện ghi key khởi động của rootkit, key này có đường dẫn:
HKLMSOFTWAREMicrosoftWindowsCurrentVersionRun. Bên trong key, rootkit tạo ra một khóa tên AtiCardInit với giá trị khóa là VideoAti0.exe.
Mã:
|
Trên đây là bài viết phân tích mẫu rootkit VideoAti0.sys thành phần kernel của Nailuj. Mong nhận được góp ý, đóng góp từ bạn đọc ./.