# The Saint Bat >Difficulty: Medium https://github.com/Azr43lKn1ght/DFIR-LABS/tree/main/The%20Saint%20Bat >Description >The Saint Batman Azrael was sent a confidential file by a secret agent but it was a stealthy malware that made him lose what he was holding. The malware seems to be very sophisticated and the Saint Bat needs your help to recover the lost data of bane's whereabouts to get back at bane for breaking batman's back. well help him get it! Note: This challenge doesn't have any questions but the flag itself! File Password : vOCorthoAGESeNsivEli Kiểm tra process list và file scan ta tiến hành dump file confidential.exe có dấu hiệu ra ![image](https://hackmd.io/_uploads/SkxpqhXNxl.png) ``` └[ mnt »  »  » Memchall ] ❯ file confidential.exe confidential.exe: PE32+ executable for MS Windows 6.00 (console), x86-64, 6 sections ``` check signature file đây là một file PE32+ ![image](https://hackmd.io/_uploads/S1YSohQNlx.png) check file với IDA tiến hành static analysis ![image](https://hackmd.io/_uploads/H18AjnmVle.png) Ta thấy hàm sub_140002D50 có vẻ rất ấn tượng ![image](https://hackmd.io/_uploads/rkbM62QExl.png) Trong hàm chứ 1 anti debug and một AddVectoredExceptionHandler theo logic code thì attacker sẽ gây ra exception để đưa chương trình tới trình Handler xử lý main logic Handler -> (DWORD64)sub_1400020F0 đây là hàm chứa logic chính ## Tại sub_1400020F0 Ta lấy chương trình sẽ load một Resource trong chính nó có ID 0x45 -> 69 và Name là STUB sau đo sẽ decrypt malicious code với RC4 PKGA nhưng key có vẻ đã bị obfuscation để làm cho khó phân tích tĩnh nên tôi đã debugging để lấy key Sau khi decrypted(unpacked) nó được load vào explorer.exe if 32bit thì folder path : C:\\Windows\\SysWOW64\\explorer.exe, còn nếu 64bit thì C:\Windows\explorer.exe sau nó sẽ chạy file bằng CreateProcessA Mục tiêu debug là bypass anti debug và pass Exception đặt break tại handler và sub_1400020F0 ![image](https://hackmd.io/_uploads/rJe-4amVee.png) Tại đây tôi sẽ skip để bypass anti debug ![image](https://hackmd.io/_uploads/B1Q44TXNlg.png) Tại đây gây ra exception với lệnh call Sleep Tại sao lại xảy ra Exception? ``` Using VirtualProtect with PAGE_GUARD and Sleep can trigger an access violation exception when the protected memory is accessed, even if the access is not directly from the code that called VirtualProtect. This occurs because the OS handles the exception generated by the guard page, and the Sleep call can indirectly cause this access. Here's a breakdown: 1. VirtualProtect and PAGE_GUARD: VirtualProtect with the PAGE_GUARD flag modifies the protection attributes of a memory page. When the page is accessed (read or written), a STATUS_GUARD_PAGE_VIOLATION exception is raised. 2. Implicit Access: The Sleep function itself doesn't directly cause the exception. However, when a thread is in a waiting state, the OS might need to access the thread's stack or other data structures to manage the waiting state. If this access involves a page protected by PAGE_GUARD, the exception will be triggered. 3. Exception Handling: The exception is handled by the operating system, and if a handler is registered (e.g., using AddVectoredExceptionHandler), the handler function can then execute. ``` và được xử lý để nhảy vào hàm sub_1400020F0 ![image](https://hackmd.io/_uploads/ryOoVT7Nle.png) ![image](https://hackmd.io/_uploads/Sk_nBpQExg.png) Tại đây v15 lưu một đỉa chỉ stack chứa key ### key : }zr#llKn]gh~_hides_the_key?idk ## Decrypt STUB ![image](https://hackmd.io/_uploads/SJLzUamExl.png) Sau khi lấy key và decrypt thi ta tiến hành reverse file STUB ``` int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { HANDLE FileW; // esi DWORD FileSize; // eax DWORD v6; // ebx int v7; // eax int v8; // eax bool v9; // cf HANDLE v10; // esi DWORD NumberOfBytesRead; // [esp+Ch] [ebp-850h] BYREF _BYTE Buffer[2048]; // [esp+10h] [ebp-84Ch] BYREF WCHAR FileName[2]; // [esp+810h] [ebp-4Ch] BYREF wchar_t **v15; // [esp+820h] [ebp-3Ch] int v16; // [esp+824h] [ebp-38h] int v17; // [esp+828h] [ebp-34h] int v18; // [esp+82Ch] [ebp-30h] int v19; // [esp+830h] [ebp-2Ch] int v20; // [esp+834h] [ebp-28h] int v21; // [esp+838h] [ebp-24h] int v22; // [esp+83Ch] [ebp-20h] int v23; // [esp+840h] [ebp-1Ch] int v24; // [esp+844h] [ebp-18h] int v25; // [esp+848h] [ebp-14h] int v26; // [esp+84Ch] [ebp-10h] int v27; // [esp+850h] [ebp-Ch] __int16 v28; // [esp+854h] [ebp-8h] wmemcpy(FileName, L"C:\\Users", 8); v28 = 0; v15 = &off_41005C; v16 = 7471226; v17 = 3342388; v18 = 6029420; v19 = 7274564; v20 = 7209079; v21 = 7274604; v22 = 6553697; v23 = 6029427; v24 = 3604582; v25 = 6750305; v26 = 7602222; v27 = 7602296; FileW = CreateFileW(FileName, 0x80000000, 3u, 0, 3u, 0, 0); NumberOfBytesRead = 0; FileSize = GetFileSize(FileW, 0); v6 = FileSize + 32; v7 = ((_BYTE)FileSize + 32) & 0xF; if ( v7 ) v6 += 16 - v7; v8 = 0; v9 = 1; do { if ( !v9 ) __report_rangecheckfailure(); Buffer[v8++] = 0; v9 = (unsigned int)v8 < 0x800; } while ( v8 < 2048 ); ReadFile(FileW, Buffer, v6, &NumberOfBytesRead, 0); CryptProtectMemory(Buffer, v6, 0); CloseHandle(FileW); v10 = CreateFileW(FileName, 0x40000000u, 2u, 0, 3u, 0, 0); WriteFile(v10, Buffer, v6, &NumberOfBytesRead, 0); CloseHandle(v10); MessageBoxA(0, "Warning: Error code 42069", "Security Warning", 0x30u); return 0; } ``` ## Main code - Đọc file đường dẫn : C:\Users\<username>\Downloads\f7ag.txt - say đó sử dụng CryptProctecMemory để mã hóa dữ liệu trong memory - Để decrypt ta phải có được g_SHAhash và g_RandomSalt và Cookie, CreateTime - Trong đó g_SHAhash,Cookie,CreateTime sẽ dùng tạo key và g_RanDomSalt là IV - vì sao nó sử dụng AES mà không phải 3DES ![image](https://hackmd.io/_uploads/ByW3eTX4ex.png) Tại đây mỗi block là 16 cho AES128 và 3DES mỗi block là 8 https://blog.slowerzs.net/posts/cryptdecryptmemory/ đây là blog bạn có thể tham khảo về decrypt CryptProctectMemory ## Kernel Debug WinDBG để thuận tiện tôi sẽ sử dụng WinDBG để debug kernels và load các symbols ![image](https://hackmd.io/_uploads/rkzkz6QNll.png) đây là các thông tin ta cần ``` from Crypto.Cipher import AES from Crypto.Hash import SHA1 import struct # === INPUT FROM MEMORY DUMP === g_sha = bytes.fromhex("d4 63 5e c5 ba 9c 00 f0 67 b4 57 b3 d7 03 3f 93 1c 14 51 fa b4 4f ec 30") cookie = 0xbc1c6a1a createtime = 0x01db69dc687cacd6 salt = bytes.fromhex("75 54 c7 57 94 18 f0 54 17 0f 4c 3c cd 56 b0 e3") # IV # === READ ENCRYPTED DATA === with open("f7ag.txt", "rb") as f: enc = f.read() # === AES128 CBC DECRYPTION === ctx = SHA1.new() ctx.update(g_sha) ctx.update(struct.pack("<LQ", cookie, createtime)) aes_key = ctx.digest()[:16] cipher = AES.new(aes_key, AES.MODE_CBC, iv=salt) dec = cipher.decrypt(enc) print(f"key : {aes_key.hex()}") print(f"iv: {salt.hex()}") Output: PS D:\CTFchall\Memchall> python .\key.py key : faa8db02422c737fce649f4f09169ec3 iv: 7554c7579418f054170f4c3ccd56b0e3 ``` ![image](https://hackmd.io/_uploads/r1O0G6QVgx.png) PS: Nếu các bạn có thắc mắc gì có thể inbox cho mình