Mustang Panda và một số biến thể của mã độc PlugX được sử dụng phổ biến trong thời gian gần đây - Phần III

Mẫu THOR

Hình 48: Thông tin về biến thể Thor trên Virustotal

Mã độc là một tệp dll (log.dll) đi kèm với 2 tệp, một tệp exe (bdreinit.exe) có chữ ký hợp lệ của BitDefender và một tệp chứa shellcode và cấu hình (log.dat) của MustangPanda. Mã độc sử dụng kỹ thuật DLL Side-Loading để thực thi hàm độc hại bên trong tệp dll. Tệp dll có nhiệm vụ giải mã tệp payload tiếp theo, đồng thời giải mã tệp cấu hình để kết nối đến máy chủ của nhóm tấn công. Luồng thực thi của mã độc có thể được biểu diễn như hình bên dưới:

Hình 49: Luồng thực thi của mã độc

Mã thực thi trong tệp dll được nhóm Mustang Panda làm rối bằng các công cụ như OLLVM để gây khó khăn trong quá trình dịch ngược mã độc.

Phân tích Loader

Tệp .dat chính là biến thể Thor của PlugX được nhóm MustangPanda sử dụng trong các chiến dịch trước đây. Biến thể này đã từng được đề cập trong bài viết: https://unit42.paloaltonetworks.com/thor-plugx-variant/.

Shellcode của tệp .dat này sẽ được bắt đầu sau byte NULL đầu tiên.

Hình 50: Phần màu xanh là đoạn văn bản đầu tệp .dat, sau đó là đoạn shellcode của Thor

Shellcode sử dụng đồng thời hàm giải mã riêng của biến thể Thor PlugX và RtlDecompress với tham số COMPRESSION_FORMAT_LZNT1 để giải mã ra một tệp PE mới.

Hình 51: Thuật toán giải mã tiếp payload của mã độc

Tệp PE được giải mã sẽ bị huỷ đi phần header và thay thế bằng các ký tự vô nghĩa.

Hình 52: file PE bị huỷ thông tin header

Sau khi giải mã, cấu hình của mã độc sẽ bao gồm các thông tin sau:

  • Địa chỉ máy chủ điều khiển.
  • Thời gian kết nối.
  • Tên registry hoặc service để giữ quyền truy cập trên máy.
  • Khóa để giải mã cấu hình.
  • Danh sách địa chỉ DNS để truy ra địa chỉ ip từ hostname.
  • Các địa chỉ máy chủ điều khiển, cổng để kết nối và cách kết nối.
  • Thời gian nhận phản hồi kể từ khi kết nối đến máy chủ điều khiển.
  • Campaign ID
Hình 53: Cấu hình của biến thể THOR

Phân tích luồng thực của THOR

Mã độc thực hiện điều chỉnh các đặc quyền SeDebugPrivilege và SeTcbPrivilege cho chính tiến trình của nó nhằm leo thang đặc quyền cho tiến trình. Sau đó, mã độc tạo một thread chính được đặt tên là “bootProc” dùng để thực thi các chức năng chính.

Hình 54: Luồng thực thi chính của biến thể Thor Variant

Luồng “bootProc” sẽ giải mã cấu hình ở trong tệp .dat để lấy các thông tin cần thiết để thực thi mã độc. Nếu tiến trình có đủ quyền, hàm sẽ khởi tạo service hoặc thực hiện autorun. Nếu cờ “flag_no_service” trong cấu hình khác 0, mã độc sẽ không khởi tạo bất kỳ service nào.

Hình 55: Hàm kiểm tra quyền và tạo service

Nếu tiến trình hiện tại không đủ quyền, mã độc sẽ sử dụng kỹ thuật bypass UAC bằng cách sử dụng IARPUninstallStringLauncher. Thông tin về kỹ thuật được diễn giải chi tiết tại: https://github.com/3gstudent/Use-COM-objects-to-bypass-UAC/blob/master/IARPUninstallStringLauncher.cpp

Hình 56: Bên trái là đoạn mã bên trong mã độc và bên phải là đoạn mã

Tiếp theo, mã độc sẽ tiến hành tạo tiến trình svchost.exe và chèn mã độc vào.

Hình 57: Mã độc tiêm vào svchost.exe

Sau khi được chèn vào svchost, mã độc tiến hành tạo mutex có giá trị là “Global\DelSelf(<PID>)”, với PID là PID của tiến trình đang chạy. Sau đó, mã độc sẽ ngắt tiến trình gốc ban đầu. Nếu “flag_delete_proc_bin” có giá trị khác 0 trong cấu hình, mã độc sẽ tiến hành xoá cả file thực thi ban đầu.

Hình 58: Mã độc tạo mutex và ngắt tiến trình gốc

Từ luồng “bootProc”, luồng “SiProc” sẽ tìm các tiến trình có thể lấy được token. Nếu như lấy được token thì mã độc sẽ tạo một bản sao của token rồi leo thang đặc quyền bằng cách sử dụng SID: S-1-16-12288.

Hình 59: Lấy token từ tiến trình khác

Sau khi leo thang đặc quyền, mã độc sẽ tạo tiến trình “userinit.exe” với tham số “userinit.exe <PID> 609”, với PID là ID của tiến trình đang chạy và tự chèn bản thân vào tiến trình vừa tạo đó.

Hình 60: Mã độc tự chèn bản thân vào tiến trình userinit.exe

Mã độc nằm trong tiến trình userinit.exe có nhiệm vụ chạy plugin (được mô tả bên dưới) và tạo pipe để giao tiếp giữa các luồng của mã độc.

Các hàm sẽ được khởi tạo và lưu vào một biến rồi truyền vào các thành phần mở rộng thông qua vùng nhớ có tên “PI[<PID>]”, với PID là mã chương trình đang chạy. Các phần mở rộng có trong mã độc bao gồm:

Plugin Hằng số Chức năng
Disk 0x20120325 Lấy thông tin; tạo, xóa tệp, các thư mục và thông tin về môi trường (path enviroment)
Keylog 0x20120324 Theo dõi thao tác bàn phím và lưu vào tệp .dat
NetHood 0x20120213 Lấy thông tin về tài nguyên và chia sẻ cho một nhóm người trong cùng mạng
NetStat 0x20120215 Đặt trạng thái cho TCP hoặc lấy bảng TCP hoặc UDP của từng tiến trình
Option 0x20120128 Tắt, khóa, khởi động lại máy tính
PortMap 0x20120325 Mở cổng để thực hiện port forwading giúp dễ dàng kết nối từ bên ngoài hơn
Process 0x20120204 Đọc thông tin và xóa chương trình đang chạy
RegEdit 0x20120315 Tạo, chỉnh sửa và xóa registry
Screen 0x20120220 Chụp màn hình máy tính
Service 0x20120117 Tạo, dừng, thay đổi và xóa service trên máy
Shell 0x20120305 Kết nối đến shell từ bên ngoài
SQL 0x20120323 Lấy cơ sở dữ liệu SQL rồi thực thi câu lệnh SQL
Telnet 0x20120225 Kết nối đến telnet
<không có tên> 0x20180209 Được sử dụng để làm khóa cho thuật toán mã hóa của Thor.

Từ luồng “bootProc”, mã độc tạo luồng thực thi mới với tên “OlProc” và đợi luồng này hoàn thành.

Luồng “OlProc” có chức năng tạo service ẩn bên trong services.exe nếu “flag_hidden_service” khác 0 và mã độc có đủ quyền thực thi.

Hình 61: Mã độc tìm tới tiến trình service.exe và ẩn thân vào bên trong

Luồng OlProc tiếp tục tạo luồng mới có tên “OlProcNotify” để kết nối đến máy chủ của nhóm tấn công. “OlProcNotify” sẽ thử kết nối đến từng host_name bên trong cấu hình. Trong trường hợp không kết nối được, mã độc sẽ thử kết nối đến địa chỉ của máy chủ điều khiển thông qua proxy bên trong cấu hình. Trong trường hợp cả tất cả địa chỉ đều không kết nối được, luồng sẽ giải mã lại cấu hình xem cấu hình có cập nhật gì và lặp lại bước trên.

Hình 62: Kết nối đến các hostname bên trong cấu hình

Tùy thuộc vào cấu hình của struct_ip mà mã độc lựa chọn phương thức kết nối đến địa chỉ của máy chủ điều khiển. Mã độc sử dụng đoạn ký tự “Protocol:<cách kết nối>, Host: <địa chỉ>, Proxy: <cổng proxy>:<địa chỉ proxy>:<Tên người dùng>” để dễ dàng biết được luồng kết nối của mã độc. Bên dưới là phương thức kết nối tương ứng với vị trí của các bit.

Vị trí của bit Giao thức kết nối
1 TCP
2 HTTP
3 UDP
4 ICMP

Nếu mã độc kết nối thông qua giao thức HTTP, luồng “SxWorkProc” sẽ được tạo và giao tiếp với máy chủ điều khiển. Cấu trúc của gói tin gửi tới máy chủ điều khiển có dạng như sau:

  • UserAgent: “Mozilla/4.0 (compatible; MSIE ;  Window NT ”
  • Các thông tin từ: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent\Post Platform và HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\User Agent\Post Platform

Header của post requests còn bao gồm 4 tham số sau:

  • utmcn: luôn là 0
  • utmcs: luôn là 0
  • utmsr: luôn là 0xF010, độ dài để chứa dữ liệu gửi đi và nhận được
  • utmsc: luôn là 0
Hình 63: Khởi tạo UserAgent
Hình 64: Khởi tạo Header cho yêu cầu Post

Với kết nối TCP, mã độc sẽ sử dụng DNS server trong cấu hình để phân giải hostname bên trong cấu hình. Kết nối TCP không có header nhưng nếu proxy có tồn tại trong cấu hình thì mã độc sẽ tạo header để kết nối thông qua proxy:

  • Proxy-Authorization: Basic <Base64 của Username và Password>
  • Proxy-Connection: Keep-Alive
  • Content-Type: text/html
  • Content-length: 0
  • CONNECT <địa chỉ proxy>:<cổng proxy> HTTP/1.1
Hình 65: Khởi tạo header để kết nối qua proxy

Dữ liệu dùng để giao tiếp với máy chủ điều khiển đều được mã hoá/giải mã thông qua RtlCompressBuffer, sau đó mã độc sử dụng thuật toán giống với thuật toán giải mã cấu hình nhưng thay đổi hằng số hoặc các phép cộng trừ.

Hình 66: Hàm mã hóa dữ liệu để gửi tới máy chủ điều khiển

Tùy thuộc vào ID câu lệnh bên trong dữ liệu trả về mà mã độc sẽ thực thi các hàm tương ứng:

ID Chức năng
1 Lấy thông tin máy tính và gửi cho máy chủ điều khiển
2 Lấy lại câu lệnh thực thi
3 Tạo luồng “OlProcManager” để làm việc với các phần mở rộng
4 Thực thi lại kết nối
5 Xóa đi cơ chế giữ quyền truy cập trên máy tính
6 Gửi cấu hình đến máy chủ điều khiển
7 Lấy thông tin cấu hình mới về máy tính

Luồng hoạt động của mã độc có thể được tổng quát hóa bằng sơ đồ sau:

Hình 67: Luồng hoạt động của mã độc

Tổng kết

MITRE ATT&CK

Kỹ thuật Thông tin
T1547.001 - Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder Tạo cơ chế giữ quyền truy cập qua registry key với tên ở trong cấu hình
T1543.003 - Create or Modify System Process: Windows Service Tạo service để giữ quyền truy cập của mã độc, đồng thời có khả năng chỉnh sửa, xóa và thêm service
T1574.002 - Hijack Execution Flow: DLL Side-Loading Sử dụng DLL Side-Loading nhằm tránh các phần mềm diệt vi-rút
T1055.001 - Process Injection: Dynamic-link Library Injection Chèn mã độc vào tiến trình svchost.exe nhằm leo thang đặc quyền
T1134.001 - Access Token Manipulation: Token Impersonation/Theft Đánh cắp token từ tiến trình có quyền cao hơn để leo thang đặc quyền
T1134.002 - Access Token Manipulation: Create Process with Token Từ token đánh cắp được, tạo tiến trình có quyền cao hơn bằng token và chèn mã độc vào tiến trình mới đó
T1548.002 - Abuse Elevation Control Mechanism: Bypass User Account Control Sử dụng COM Object để leo thang đặc quyền
T1140 - Deobfuscate/Decode Files or Information Sử dụng RtlDecompressBuffer và hàm mã hóa riêng để giải mã cấu hình và Thor payload
T1564.005 - Hide Artifacts: Hidden File System Ẩn tệp để người dùng không nhìn thấy tệp độc hại
T1112 - Modify Registry Thêm, xóa và thay đổi registry
T1027 - Obfuscated Files or Information Sử dụng lệnh gọi API qua PEB và sử dụng OLLVM để làm rối mã thực thi của mã độc nhằm tránh bị phát hiện
T1056.001 - Keylogging Theo dõi thao tác bàn phím của người dùng
T1083 - File and Directory Discovery Lấy thông tin tệp và thư mục của máy nạn nhân
T1135 - Network Share Discovery Lấy thông tin về tài nguyên mạng
T1049 - System Network Connections Discovery Lấy thông tin về bảng UDP hoặc TCP của các tiến trình
T1057 - Process Discovery Lấy thông tin về các tiến trình đang chạy
T1012 - Query Registry Lấy thông tin của registry
T1113 - Screen Capture Chụp ảnh màn hình của máy nạn nhân
T1071.004 - Application Layer Protocol: DNS Sử dụng DNS trong cấu hình để phân giải IP của hostname
T1071.001 - Application Layer Protocol: Web Protocols Kết nối và giao tiếp với máy chủ điều khiển thông qua giao thức HTTP
T1132.002 - Data Encoding: Non-Standard Encoding Truyền dữ liệu thông qua thuật toán riêng và RtlDecompressBuffer
T1095 - Non-Application Layer Protocol Thực hiện TCP và UDP với máy chủ điều khiển
T1090 - Proxy Kết nối tới máy chủ điều khiển qua Proxy
T1041 - Exfiltration Over C2 Channel Gửi các dữ liệu thu thập được tới máy chủ điều khiển

So sánh các biến thể của Mustang Panda

Điểm giống nhau

  • Các mẫu của Mustang Panda đều sử dụng kỹ thuật DLL-Side Loading, lợi dụng một tệp thực thi sạch thực thi một tệp DLL độc hại. Khi được thực thi, tệp DLL sẽ tiến hành giải mã tệp dữ liệu đính kèm (thông thường là tệp .dat).
  • Dữ liệu sau khi giải mã đều là PlugX.

Điểm khác nhau

Đề mục Xor Variant Xor 2 Variant Thor Variant
Cách giải mã Sử dụng thuật toán XOR để giải mã PlugX Sử dụng thuật toán riêng để giải mã đoạn payload bị nén và RtlDecompressBuffer để giải nén PlugX
Giải mã cấu hình Giải mã cấu hình bằng cách XOR với key 123456789 Sử dụng thuật toán riêng để giải mã cấu hình
Mã hoá/giải mã dữ liệu được nhận và gửi từ máy chủ điều khiển Sử dụng thuật toán XOR và LZNT1 Sử dụng RC4 với key sV!e@T#L$PH% và LZNT1 Sử dụng thuật toán riêng cùng với LZNT1.
Các plugin của PlugX Sử dụng các plugin mới được viết vào năm 2019 Sử dụng các plugin được viết vào năm 2012

Danh sách IOC

https://github.com/vcs-ti/indicator/blob/main/Mustang%20Panda/iocs.md

Tài liệu tham khảo