[RE016] Malware Analysis: ModiLoader

 

1. Giới thiệu

Gần đây, tôi có tìm hiểu một dòng loader có tên là ModiLoader. Loader này được phát tán thông qua các dịch vụ Malspam để lừa người dùng thực thi mã độc. Tương tự như các dòng loader khác, ModiLoader cũng thông qua nhiều bước (stage) để tải về payload cuối cùng có nhiệm vụ đánh cắp thông tin của nạn nhân. Qua tìm hiểu một số sample, xét về mặt kĩ thuật thì dòng loader này khá cơ bản, không áp dụng các kĩ thuật anti-analysis như Anti-Debug, Anti-VM mà chúng tôi đã gặp ở các sample GuLoader/CloudEyE (1;2). Thay vào đó, để tránh bị phát hiện bởi các chương trình AV, loader này sử dụng chữ kí số, thực hiện giải mã các payload, Url, hàm làm nhiệm vụ inject code, và thực thi payload trực tiếp từ bộ nhớ.

Hiện tại, trên thế giới cũng như cũng như ở Việt Nam chưa có nhiều bài viết phân tích về dòng loader này. Do vây, trong bài viết này, tôi sẽ trình bày các kĩ thuật mà loader này sử dụng cũng như áp dụng công cụ mới công bố gần đây của FireEye là capa giúp nhanh chóng tìm ra đoạn code cần phân tích. Bài phân tích cũng tối đa hóa việc mô phỏng lại code của mã độc bằng python để phục vụ việc tự động trích xuất và giải mã payload, Url.

2. Thông tin sample

SHA256
: 9d71c01a2e63e041ca58886eba792d3fc0c0064198d225f2f0e2e70c6222365c

Bằng các chương trình PE Scanner cho thấy dòng loader này được viết bằng Delphi, có sử dụng Digital Signatures để qua mặt các chương trình AV đang hoạt động trên máy người dùng:





3. Phân tích kĩ thuật

3.1. Phân tích Stage 1


Ở bước đầu tiên này, loader (được xem là payload thứ nhất) thực hiện nhiệm vụ trích xuất dữ liệu, giải mã ra payload thứ hai (payload này có thể là dll hoặc exe), thực thi payload từ bộ nhớ.

Sử dụng IDA, sau khi kết thúc quá trình tự động phân tích, IDA đã nhận diện tới 5385 hàm:


Code tại start() của loader như sau:



Mặc dù số lượng hàm nhận diện được nhiều như trên, phần lớn trong đó là các hàm APIs của Windows cũng như các hàm thư viện của Delphi thì việc tìm ra đoạn code chính liên quan tới việc giải mã ra payload thứ hai cũng vẫn sẽ mất thời gian. Thông qua sự hỗ trợ của capa, tôi nhanh chóng tìm được đoạn code liên quan đến việc thực thi payload thứ hai và từ đó truy ngược về đoạn code thực hiện nhiệm vụ giải mã ra payload này.



Toàn bộ code tại sub_498CDC() sẽ thực hiện nhiệm vụ parse payload, mapping vào bộ nhớ và thực thi payload. Code tại hàm này trước và sau khi áp dụng các struct liên quan:



Truy ngược lên sẽ tới sub_4994EC(), hàm này thực hiện nhiệm vụ:

  • Đọc toàn bộ dữ liệu từ resource có tên "T__7412N15D" vào bộ nhớ.

  • Tìm chuỗi "OPPO" trong resource data để lấy dữ liệu của payload đã bị mã hóa.
  • Thực hiện giải mã ra payload thứ hai. Key để giải mã là một giá trị số.
  • Tìm chuỗi trong payload thứ hai và thay thế nó bằng chuỗi URL đã bị mã hóa.

Trong hình trên, key giải mã là một số nguyên được chuyển đổi từ chuỗi. Với sample này key giải mã có giá trị là 0x30. Công việc của đoạn code giải mã payload như hình dưới đây:


Toàn bộ đoạn code trên được viết lại bằng python như sau:


Sau khi giải mã ra payload, loader sẽ thực hiện tìm kiếm và thay thế chuỗi gồm 168 kí tự “z” bằng chuỗi URL đã bị mã hóa. Cuối cùng gọi sub_498CDC() để thực thi payload sau khi đã thay thế.

Toàn bộ quá trình phân tích kĩ thuật từ đầu đến giờ có thể hiện thực bằng python script để thu được payload thứ hai.


3.2. Phân tích Stage 2


Kiểm tra payload thu được ở bước trên, nó cũng được viết bằng Delphi:


Tương tự như trên, tôi tìm được sub_45BE08() có nhiệm vụ cấp phát vùng nhớ, mapping payload cuối cùng sau giải mã vào vùng nhớ này, rồi thực thi payload đã giải mã này.

Bằng việc truy ngược code, tôi tìm thấy đoạn mã bắt đầu tại TForm1_Timer1Timer (do IDA nhận diện được thông qua signature) tại địa chỉ 0x45CC10. Code tại đây thực hiện giải mã ra Url và kiểm tra kết nối Internet bằng cách thử kết nối tới Url đã giải mã là https://www.microsoft.com, trước khi gọi f_main_loader() tại địa chỉ 0x45C26C.

Thuật toán giải mã kí tự tại hàm f_decode_char_and_concat_str() đơn giản như sau: dec_char = (enc_char >> 4) | (0x10 * enc_char);



Tại f_main_loader(), mã độc cũng sử dụng hàm tương tự như trên để giải mã ra chuỗi "Yes". Chuỗi này được sử dụng làm xor_Key cho việc giải mã ra Url để tải về payload cuối (Url bị mã hóa chính là chuỗi ở bước thay thế đã mô tả ở trên) cũng như giải mã payload tải về. Hàm f_decode_url_and_payload(void *enc_buf, LPSTR szKey, void *dec_buf) nhận ba tham số truyền vào:

  • Tham số đầu tiên enc_buf là nơi chứa dữ liệu bị mã hóa.
  • Tham số thứ hai szKey là chuỗi "Yes" dùng để giải mã.
  • Tham số thứ ba dec_buf là nơi chứa dữ liệu đã giải mã.

Đi sâu vào hàm giải mã này sẽ thấy nó thực hiện vòng lặp giải mã toàn bộ dữ liệu, mỗi lần lặp lấy 2 bytes, chuyển đổi chuỗi sang số nguyên, sau đó đem
xor với kí tự lấy ra từ key giải mã. Dữ liệu sau giải mã được lưu vào vùng nhớ.


Toàn bộ hàm giải mã này được viết lại bằng python như sau:


Quay trở lại f_main_loader(), đầu tiên nó sẽ giải mã ra Url của payload cuối:


Thực hiện giải mã bằng đoạn code python ở trên, thu được Url như hình dưới đây:


Tiếp theo, mã độc sử dụng WinHTTP WinHttpRequest COM object để tải payload đã mã hóa từ Url trên. Việc thay đổi sang sử dụng COM object có thể nhằm tránh bị phát hiện bởi các chương trình AV so với việc sử dụng các hàm Internet APIs thuộc thư viện Wininet ở một số sample khác.


Ở đây, tôi sử dụng wget để tải payload về, kiểm tra thấy nó được lưu dưới dạng các chuỗi hex tương tự như chuỗi Url bị mã hóa ở trên.


Payload sau khi tải về sẽ được đảo ngược dữ liệu và giải mã bằng chính hàm f_decode_url_and_payload với cùng key giải mã là "Yes". Bằng kĩ thuật tương tự, payload này cũng được mapping vào bộ nhớ và thực thi.


Với payload đã tải về cùng với đoạn code python ở trên, tôi có thể giải mã và thu được payload cuối cùng. Payload này là một file dll, cũng được viết bằng Delphi:


3.3. Phân tích Stage 3


Payload trên khá phức tạp, nó thực hiện nhiệm vụ sau:
  • Đọc dữ liệu từ resource có tên "DVCLAL" vào bộ nhớ.
  • Giải mã resource, sau đó dựa vào dấu hiệu “*()%@5YT!@#G__T@#$%^&*()__#@$#57$#!@” để đọc các dữ liệu đã giải mã vào các biến tương ứng.
  • Lấy thông tin thư mục của người dùng thông qua biến môi trường %USERPROFILE% và cấu thành đường dẫn tới thư mục %USERPROFILE%\AppData\Local.
  • Tạo các file Vwnt.urlVwntnet.exe (bản sao của loader) tại thư mục %USERPROFILE%\AppData\Local nếu các file này chưa tồn tại, sau đó thiết lập giá trị “Vwnt” tại “HKCU\Software\Microsoft\Windows\CurrentVersion\Run” trỏ tới file %USERPROFILE%\AppData\Local\Vwnt.url. Ghi vào file Vwnt.url với nội dung trỏ tới Vwntnet.exe:

  • Thực hiện kết hợp các data đã giải mã từ resource ở trên để giải mã ra một payload mới.


  • Giải mã ra hàm thực hiện nhiệm vụ inject payload. Kiểm tra nếu có "C:\Program Files (x86)\internet explorer\ieinstal.exe", sẽ thực hiện inject payload vào ieinstal.exe.

  • Dựa vào các strings có trong payload đã inject vào ieinstal.exe có thể khẳng định nó thuộc dòng Warzone RAT. Một dòng RAT khá nổi tiếng, được cung cấp trực tuyến cũng như quảng bá trên nhiều diễn đàn của tội phạm mạng.


4. Tham khảo


Click here for English version



Tran Trung Kien (aka m4n0w4r) 

R&D Center - VinCSS (a member of Vingroup)



No comments:

Post a Comment