Phân tích mẫu APT nhắm vào GOV từ 1937CN hay OceanLotus hay Lazarus

Sugi_b3o

Moderator
Thành viên BQT
30/08/2016
317
446 bài viết
Phân tích mẫu APT nhắm vào GOV từ 1937CN hay OceanLotus hay Lazarus
Bài phân tích của a Kienmanowar chia sẻ về cách RE để phát hiện các mã shellcode trong file doc về APT vào chính phủ VN

1.PNG

Vô tình bắt gặp trên twitter của @blu3_team (Tôi không rõ sao acc này lại rất hay có được những mẫu target vào VN), tôi tò mò muốn biết kĩ thuật đằng sau nó là gì bởi tôi thấy nó tương tự như một bài mà tôi đã đọc https://medium.com/@Sebdraven/malicious-document-targets-vietnamese-officials-acb3b9d8b80a, và vì xem comment, người nghi ngờ là OceanLotus, người khẳng định là 1937CN Team

Xin lỗi vì bài viết khá dài, tôi cũng không biết làm thế nào để cho nó ngắn hơn :D, nếu bạn không có thời gian để đọc hết thì bấm một like rồi chuyển trang khác. Phần tôi, một là do tôi thích viết, mặt khác cũng là cách tôi tự rèn kĩ năng … phần nữa là vì tôi biết rằng chỉ khi mình thực sự bắt tay vào phân tích mới thấy nó khác xa với những gì mình đọc bằng mắt và tưởng tượng….


2.PNG

1. Môi trường thực hiện
1. Máy ảo REMnux (https://remnux.org/): sử dụng để phân tích files, giả lập Internet services và capture network traffic.

2. Máy ảo Win10x64 (tự build): sử dụng cho Static & Dynamic Analysis

a. Cài đặt sẵn các cộng cụ debugger & disassembler: OllyDbg, x64dbg, IDA …

b. Cài đặt sẵn Office 2013.

c. Enable tải khoản Administrator (mặc định tài khoản này bị disable) và đăng nhập bằng tải khoản này để thực hiện phân tích.

2. Phân tích theo hành vi
Khi mở tài liệu trên máy ảo Win10, sẽ thấy ứng dụng EQNEDT32.exe được gọi, sau đó xuất hiện thêm hai tiến trình khác là QcConsol.exedllhst3g.exe:

3.PNG

Trên máy ảo REMnux chạy Wireshark để capture traffic từ máy ảo Win10, thu được kết quả kết nối tới C2 server là login[dot]dangquanwatch[dot]com:

4.PNG
5.PNG

Log của Noriben (https://github.com/Rurik/Noriben) cung cấp:

6.PNG

3. Phân tích sample trên REMnux
Sample nhận được là một file có định dạng RTF:

7.PNG

Sử dụng rtfobj (https://github.com/decalage2/oletools), biết được sample này có 3 objects:

8.PNG

Object tại id 0 có FileName là 8.t, khi mở tài liệu thì file này sẽ được drop vào thư mục Temp trên máy. Hai object còn lại được nhận diện là “Not a well formed ole object”.

Dùng luôn rtfobj để dump toàn bộ các objects này:

9.PNG

Kiểm tra thông tin từng file. Đầu tiên là b45087ad4f7d84758046e9d6eb174530fee98b069105a78f124cbde1ecfb0415_8.t:

10.PNG

Theo data như trên hình thì khả năng file này đã bị mã hóa và sẽ được giải mã sau khi drop vào thự mục Temp.

Với file b45087ad4f7d84758046e9d6eb174530fee98b069105a78f124cbde1ecfb0415_object_000C11FB.raw:

11.PNG

Căn cứ vào dấu hiệu như trên hình thì khả năng file RTF có thể sẽ sử dụng exploit CVE-2017–11882(https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-11882).

Kiểm tra file còn lại là b45087ad4f7d84758046e9d6eb174530fee98b069105a78f124cbde1ecfb0415_object_000C11E9.raw:

12.PNG
File này khả năng sẽ chứa đoạn shellcode để thực hiện sau khi máy nạn nhân bị exploit. Thông tin sợ bộ là như vậy, tiếp theo ta sẽ thực hiện debug sample này để xem file 8.t được sử dụng như thế nào.

4. Debug maldoc trên Windows10
Liên quan tới exploit CVE-2017–11882, khi chạy sample, Winword.exe sẽ gọi tiến trình EQNEDT32.exe để handle OLE object. Tuy nhiên, Winword.exe không phải là process cha của EQNEDT32.exe, tiến trình EQNEDT32.exeđược gọi bởi Winword.exe thông qua việc sử dụng COM Object như hình dưới đây:

13.PNG

https://embedi.com/blog/skeleton-closet-ms-office-vulnerability-you-didnt-know-about/
Như vậy, bằng cách nào đó ta phải attach được EQNEDT32.exe vào debugger để debug. Ở đây, tôi sử dụng một kĩ thuật của M$ là Image File Execution Options (IFEO: https://blogs.msdn.microsoft.com/mithuns/2010/03/24/image-file-execution-options-ifeo/).

Vào Registry, tạo một key như sau hoặc nếu cài Word2013 trở lên thì khả năng có sẵn key này (vì tôi thấy trên máy tôi có sẵn):

14.PNG

Tiếp theo, tạo một string value để khởi chạy debugger khi EQNEDT32.exe được thực thi, qua đó sẽ attach đươc debugger vào tiến trình của EQNEDT32.exe.

15.PNG

Với thiết lập như trên, kiểm tra lại bằng Autoruns sẽ như sau:

16.PNG

Lưu ý: khi thiết lập IFEO, các thiết lập sẽ tự động bộ giữa hai key: HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution OptionsHKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options

Tiếp theo, mở WINWORD.EXE, sau đó từ Winword mở tài liệu malicious rtf. Lúc này, tiến trình EQNEDT32.exe cũng sẽ được khởi chạy và được attach vào debugger:

17.PNG

18.PNG

Tại debugger, ta đang dừng lại tại EP(Entry Point) của EQNEDT32.exe:

19.PNG

Kiểm tra ta thấy file 8.t đã được drop vào thư mục Temp:

20.PNG

Đặt BP tại API CreatFileW, sau đó nhấn F9 để thực thi, ta thấy chương trình sẽ thực hiện mở file 8.t để đọc nội dung:

21.PNG

Trace qua hàm này và return, sẽ tới shellcode của exploit:

22.PNG

Gọi hàm GetFileSize để lấy kích thước của 8.t:

23.PNG

24.PNG

Sau đó, gọi hàm VirtualAlloc để thực hiện cấp phát một vùng nhớ:

25.PNG

Vùng nhớ được cấp phát trỏ bởi thanh ghi EAX, follow theo vùng nhớ này để xem code sẽ tác động gì lên nó:

26.PNG

27.PNG

Hàm ReadFile được gọi để đọc ra nội dung của 8.t:

28.PNG

Toàn bộ nội dung của 8.t được đọc vào vùng nhớ đã được cấp phát ở trên:

29.PNG

Tiếp tục trace sẽ tới đoạn shellcode thực hiện giải mã toàn bộ nội dung của file 8.t trong memory tại 0x4F70000:

30.PNG

Sau vài lần trace code sẽ thấy được dấu hiệu MZ, nhưng vậy file 8.t sau khi giải mà sẽ là một PE file:

31.PNG

Cho thực hiện xong toàn bộ vòng lặp giải mã trên sẽ có được một PE hoàn chỉnh trong bộ nhớ:

32.PNG

Dump PE mới này và lưu lại để thực hiện phân tích sau:

33.PNG

File dump được là một exe file:

34.PNG

Tiếp tục debug, shellcode gọi tiếp hàm VirtualAlloc để cấp phát một vùng nhớ khác tại địa chỉ 0x5170000:

35.PNG

PE được giải mã tại vùng nhớ 0x4F70000 sẽ được copy vào vùng nhớ mới được cấp phát ở trên:

36.PNG

Dump vùng mem trên ra bộ nhớ, và vì file này đã được mapping trên memory và có thay đổi, nên sử dụng cộng cụ pe_unmapper của hasherezade(https://github.com/hasherezade/pe_recovery_tools/tree/master/pe_unmapper) để chuyển đổi từ virtual format về định dạng raw:

37.PNG

Debug tiếp, shellcode gọi hàm GetModuleFileNameA được gọi để lấy đường dẫn của EQNEDT32.exe:


38.PNG
39.PNG
Sử dụng CreateProcessA (CreateProcessInternalA) để tạo một process EQNEDT32.exe khác ở trạng thái Suspended. Do đang thiết lập tính năng IFEO nên ta sẽ thấy process của debugger thay vì là process EQNEDT32.exe:

40.PNG

41.PNG

Note: Nếu thực hiện lại, tới bước này thì sử dụng Autoruns để bỏ việc sử dụng IFEO và cho thực hiện hàm CreateProcessA, ta sẽ có được kết quả đúng như hình:

42.PNG

Đoạn code tiếp theo sẽ lấy thread context bằng GetThreadContext, đọc dữ liệu từ vùng nhớ với hàm ReadProcessMemory, gọi VirtualProtectEx (PAGE_EXECUTE_READWRITE 0x40) để thay đổi trang thái của vùng nhớ trên Suspend process, và cuối cùng shellcode ghi đè lên bằng PE tại địa chỉ 0x5170000:

43.PNG

Thực hiện đặt lại thread context bằng SetThreadContext, cuối cùng shellcode thực hiện hàm ResumeThread để launch PE mới:

44.PNG

Tổng kết lại, toàn bộ quá trình thực hiện của shellcode là giải mã file 8.t thành một PE mới, sau đó thực hiện nhân bản sang một vùng nhớ khác, thực hiện tạo một fork process mới là EQNEDT32.exe, cuối cùng áp dụng kĩ thuật runPE để launch EQNEDT32.exe mới đã bị ghi đè code bởi nội dung của file 8.t.

5. Phân tích binary đã dump
Như đã biết khi phân tích dynamic, sau khi resume thread thì malware sẽ drop ra disk các file sau: QcConsol.exe; QcLite.dll; stdole.tlb vào thư mục %AppData%\Microsoft\Windows\Printer Shortcuts.

Ở trên tôi có 2 file đã dump là _04F70000.memdrop_bin.exe (được unmap bằng công cụ pe_unmapper). Tuy nhiên, chỉ có file _04F70000.mem là thực thi được bình thường, còn file drop_bin.exe thì bị crash (mặc dù lúc fix, kiểm tra bằng PE bear thấy mọi thứ đều ok. Tôi có chat hỏi về vấn đề này thì nhận được trả lời của hasherezade như sau: “dumped samples may not always work, so it is normal”).

Mở IDA và load file _04F70000.exe (đổi tên lại từ file .mem), dừng lại tại WinMain():

45.PNG
Binary lấy đường dẫn tới thư mục %AppData%\Microsoft\Windows\Printer Shortcuts:

46.PNG
Cấu thành đường dẫn của các file:

47.PNG

Tới đoạn code thực hiện call sub_331860 3 lần để thực hiện drop các file trên vào thư mục chỉ định. Tôi đổi tên sub này thành thành drop_file như hình:

48.PNG

Đi sâu vào hàm này sẽ gặp vòng lặp xor thực hiện decode bytes, sau đó là đoạn code thực hiện WriteFile vào thư mục:

49.PNG



Kết quả sau khi thực hiện hàm drop_file đầu tiên, có được file QcConsol.exe:

50.PNG

Đây là một file hợp lệ, có chữ kí và được phát triển bởi hãng McAfee, Inc.:

51.PNG

52.PNG

Lời gọi hàm drop_file thứ 2 sẽ drop ra file QcLite.dll, file này không có thông tin gì về Signature cũng như info, như vậy malicious code sẽ nằm ở file này:

53.PNG

54.PNG

Lời gọi hàm drop_file thứ 3 sẽ drop ra file stdole.tlb. Thông tin về .tlb có thể xem tại đây (https://docs.microsoft.com/en-us/windows/desktop/midl/com-dcom-and-type-libraries):

55.PNG
Tiếp tục, cấu thành một command như sau:

56.PNG

Cuối cùng, gọi hàm WinExec để thực thi QcConsol.exe với tham số là “-LowIntegrityServer”:

57.PNG

Như vậy, với việc thực thi thành công, QcConsol.exe chắc chắn sẽ phải load QcLite.dll vào để thưc thi malicious code.

6. DLL hijacking — Phân tích file QcConsol.exe
Load file vào IDA nhận được thông báo:

58.PNG

Để nạp được QcLite.dll, QcConsol.exe sử dụng API LoadLibraryW và sau đó gọi GetProcAddress để lấy địa chỉ của hàm. Về bản chất khi thực hiện nạp module thì đồng thời code của dll cũng sẽ được thực hiện bắt đầu từ DllMain:

59.PNG

7. Phân tích sơ bộ file QcLite.dll
Gọi hàm VirtualAlloc để cấp phát một vùng nhớ:

60.PNG

Lấy đường dẫn đầy đủ tới QcLite.dll:

61.PNG
Dll này sẽ load file .tlb:

62.PNG

Gọi hàm CreatFileW để mở file này (lpFileName trỏ tới stdole.tlb):

24c64-1zfj7ra3iyao7kslp8f7xdq.png

63.PNG

Lấy kích thước của stdole.tlb:


64.PNG

Đọc dữ liệu từ stdole.tlb và lưu vào vùng nhớ đã cấp phát ở trên:

65.PNG

Thực hiện vòng lặp sử dụng xor để decode toàn bộ dữ liệu của stdole.tlb đã được copy lên memory:

66.PNG

Kết quả có được sau khi decode, nghi ngờ khả năng đây có thể sẽ là một PE file khác:

67.PNG

Qua rất nhiều rop_chain (tôi đoán thế :D) thì sẽ nhảy tới vùng nhớ trên để thực thi code (Cách nhanh nhất thì các bạn có thể đặt một HWBP on Execute tại 4 bytes đầu 0x50 0x68 0xA7 0x45; sau đó nhấn F9 là tới):

68.PNG

Shellcode tại 0x01A10000 sẽ truy cập PEB (Process Environment Block) để lấy ra địa chỉ base address của kernel32.dll:

69.PNG

70.PNG


Sau khi có được base address của kernel32.dll, shellcode sẽ tìm địa chỉ của hàm API GetProcAddress:

71.PNG

72.PNG

Với hàm API GetProcAddress, shellcode sẽ lấy địa chỉ của các hàm API khác là LoadLibraryA, VirtualAlloc, FreeLibraryA, Sleep:

73.PNG

Sử dụng hàm VirtualAlloc để cấp phát một vùng nhớ và gọi hàm decode_data() để decode bytes trong shellcode vào vùng nhớ cấp phát:

74.PNG

75.PNG

Tiếp tục sử dụng VirtualAlloc để cấp phát thêm một vùng nhớ khác với kích thước lấy từ vùng nhớ trên (dwSize = SizeOfImage = PE_header + 0x50) và thiết lập vùng nhớ mới này là PAGE_EXECUTE_READWRITE:

76.PNG

Sau khi lấy được section header tại vùng nhớ 0x01880000 ở trên, thực hiện vòng lặp để copy toàn bộ các section data sang vùng nhớ mới được cấp phát:

77.PNG

Tiến hành resolve toàn bộ địa chỉ API ghi lại vào IAT của vùng nhớ mới:

78.PNG

Sau khi lấy địa chỉ của toàn bộ các API cần thiết, sử dụng lệnh call để nhảy tới vùng nhớ để thực hiện lệnh:

79.PNG

Tiếp tục debug xuyên qua nhiều lớp call sẽ tới đoạn gọi hàm CreateThread để tạo một thread mới:

80.PNG

Đi tới ThreadFunction tại địa chỉ 0x01EE35D0. Code tại đây thực hiện lấy thông tin binary có sẵn của Windows là dllhst3g.exe:

81.PNG
Xem tổng quan code thì thấy có đoạn code liên quan đến C2 (login[dot]dangquanwatch[dot]com):

82.PNG

Tạo một thread khác làm nhiệm vụ tạo Persistent trong Registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run:

83.PNG

84.PNG
Gọi hàm WritePrivateProfileStringW để ghi string vào file tại “C:\ProgramData\desktop.ini”:

85.PNG

Thiết lập thuộc tính cho file với hàm SetFileAttributesW:


86.PNG
Tạo một Mutex {986AFDE7-F299–4A7D-BBF4-CA756FC01F1B65027208}, tuy nhiên handle tới mutext này sẽ bị đóng ngay sau đó:

87.PNG

Tiếp tục sử dụng bộ API CreateFileW, GetFileSize, VirtualAlloc, ReadFile để một lần nữa đọc ra nội dung được lưu trong file %AppData%\Microsoft\Windows\Printer Shortcuts\stdole.tlb và thực hiện decode dữ liệu giống như đã nói ở bước trước:

88.PNG

Thực hiện kĩ thuật inject code bằng cách gọi hàm CreateProcessW để khởi động tiến trình dllhst3g.exe ở trạng thái Suspended:


89.PNG

Cấp phát vùng nhớ trong tiến trình này thông qua hàm VirtualAllocEx:

90.PNG

Gọi hàm WriteProcessMemory để ghi dữ liệu từ 0x00F90000 (buffer chứa data đã decode của stdole.tlb) vào vùng nhớ đã cấp phát tại tiến trình dllhst3g.exe, đặt lại thread context và resume thread. Lúc này dllhst3g.exe sẽ thực thi bình thường và thực thi luôn malicious code:

95.PNG
8. Debug dllhst3g.exe
Hoàn thành xong việc inject code vào dllhst3g.exe sẽ gọi ExitProcess để kết thúc tiến trình QcConsol.exe và tiếp tục thực thi tiến trình dllhst3g.exe. Do dllhst3g.exe bị inject code của file stdole.tlb sau khi decode trên bộ nhớ, nên cách thức hoạt động cũng tương tự. Để có thể debug xem dllhst3g.exe sẽ làm gì thì trước khi thực hiện bước WriteProcessMemory ở trên, sửa 2 bytes đầu là 0x50 0x68 thành 0xEB 0xFE. Sau khi resume thread, mở một debugger khác để attach và khôi phục lại 2 bytes đã bị sửa.

Lúc này, debug sẽ thấy code tạo một mutext và đọc lại nội dung từ file “C:\ProgramData\desktop.ini” và decode string trong file này thành:

96.PNG

Gắn thêm tham số: 0206F4E4 00D80B30 UNICODE “”C:\Users\REM\AppData\Roaming\Microsoft\Windows\Printer Shortcuts\QcConsol.exe” –LowIntegrityServer và gọi hàm WinExec để thực thi

97.PNG

Tiến trình mới này sẽ kết nối tới C2 (Ở đây tôi đang lái traffic về REMnux):

98.PNG

Tại máy REMnux, sử dụng wireshark sẽ capture được thông tin như hình:

99.PNG
9. IOCs
Domain: login[dot]dangquanwatch[dot]com / IP: 185.77.129.142

RTF: b45087ad4f7d84758046e9d6eb174530fee98b069105a78f124cbde1ecfb0415

8.t: 6328dd14eda2ef983810c0c7b3af47298b5998e4fa52d97b204be2818f08bb69

Binary:

QcConsol.exe: 9f3114e48dd0245467fd184bb9655a5208fa7d13e2fe06514d1f3d61ce8b8770

QcLite.dll: 5b652205b1c248e5d5fc0eb5f53c5754df829ed2479687d4f14c2e08fbf87e76

Others:

stdole.tlb: ba620bad026f25ba6decc4bdcefc6415b563503cf9eaddc4e1137a5871d5cee2

desktop.ini: 31c2be9ca29fb2bd8096720c221ee9682f013eee119b02d390d6efc12684392d

Registry:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run & HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

ValueName: Windows HD Audio Manager

Data: %AppData%\MICROS~1\Windows\PRINTE~1\QcConsol.exe -LowIntegrityServer
Link bài gốc
Sugi_b3o
WhiteHat.vn​
 
Chỉnh sửa lần cuối bởi người điều hành:
Kiến thức chuyên sâu, đọc hoa cả mắt, thank bạn
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Đỉnh của đỉnh <3
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Bài này có một cách rất hay về attack debug
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Thẻ
1937cn apt doc lazarus malware ocenlotus reverse engineering
Bên trên