ctf-forensics

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CTF Forensics & Blockchain

CTF取证与区块链分析

Quick reference for forensics challenges. For detailed techniques, see supporting files.
取证类挑战速查指南。如需详细技术内容,请参阅配套文件。

Additional Resources

额外资源

  • 3d-printing.md - 3D printing forensics (PrusaSlicer binary G-code, QOIF, heatshrink)
  • windows.md - Windows forensics (registry, SAM, event logs, recycle bin)
  • network.md - Network forensics (PCAP, SMB3, WordPress, credentials)

  • 3d-printing.md - 3D打印取证(PrusaSlicer二进制G代码、QOIF、heatshrink压缩)
  • windows.md - Windows系统取证(注册表、SAM、事件日志、回收站)
  • network.md - 网络取证(PCAP、SMB3、WordPress、凭证)

Quick Start Commands

快速入门命令

bash
undefined
bash
undefined

File analysis

File analysis

file suspicious_file exiftool suspicious_file # Metadata binwalk suspicious_file # Embedded files strings -n 8 suspicious_file hexdump -C suspicious_file | head # Check magic bytes
file suspicious_file exiftool suspicious_file # Metadata binwalk suspicious_file # Embedded files strings -n 8 suspicious_file hexdump -C suspicious_file | head # Check magic bytes

Disk forensics

Disk forensics

sudo mount -o loop,ro image.dd /mnt/evidence fls -r image.dd # List files photorec image.dd # Carve deleted files
sudo mount -o loop,ro image.dd /mnt/evidence fls -r image.dd # List files photorec image.dd # Carve deleted files

Memory forensics (Volatility 3)

Memory forensics (Volatility 3)

vol3 -f memory.dmp windows.info vol3 -f memory.dmp windows.pslist vol3 -f memory.dmp windows.filescan
undefined
vol3 -f memory.dmp windows.info vol3 -f memory.dmp windows.pslist vol3 -f memory.dmp windows.filescan
undefined

Log Analysis

日志分析

bash
undefined
bash
undefined

Search for flag fragments

Search for flag fragments

grep -iE "(flag|part|piece|fragment)" server.log
grep -iE "(flag|part|piece|fragment)" server.log

Reconstruct fragmented flags

Reconstruct fragmented flags

grep "FLAGPART" server.log | sed 's/.*FLAGPART: //' | uniq | tr -d '\n'
grep "FLAGPART" server.log | sed 's/.*FLAGPART: //' | uniq | tr -d '\n'

Find anomalies

Find anomalies

sort logfile.log | uniq -c | sort -rn | head
undefined
sort logfile.log | uniq -c | sort -rn | head
undefined

Windows Event Logs (.evtx)

Windows事件日志(.evtx)

Key Event IDs:
  • 1001 - Bugcheck/reboot
  • 1102 - Audit log cleared
  • 4720 - User account created
  • 4781 - Account renamed
RDP Session IDs (TerminalServices-LocalSessionManager):
  • 21 - Session logon succeeded
  • 24 - Session disconnected
  • 1149 - RDP auth succeeded (RemoteConnectionManager, has source IP)
python
import Evtx.Evtx as evtx
with evtx.Evtx("Security.evtx") as log:
    for record in log.records():
        print(record.xml())
关键事件ID:
  • 1001 - 系统崩溃/重启
  • 1102 - 审计日志被清除
  • 4720 - 用户账户创建
  • 4781 - 账户重命名
RDP会话ID(TerminalServices-LocalSessionManager):
  • 21 - 会话登录成功
  • 24 - 会话断开
  • 1149 - RDP认证成功(RemoteConnectionManager,包含源IP)
python
import Evtx.Evtx as evtx
with evtx.Evtx("Security.evtx") as log:
    for record in log.records():
        print(record.xml())

When Logs Are Cleared

当日志被清除时

If attacker cleared event logs, use these alternative sources:
  1. USN Journal ($J) - File operations timeline (MFT ref, timestamps, reasons)
  2. SAM registry - Account creation from key last_modified timestamps
  3. PowerShell history - ConsoleHost_history.txt (USN DATA_EXTEND = command timing)
  4. Defender MPLog - Separate log with threat detections and ASR events
  5. Prefetch - Program execution evidence
  6. User profile creation - First login time (profile dir in USN journal)
如果攻击者清除了事件日志,可使用以下替代数据源:
  1. USN日志($J) - 文件操作时间线(MFT引用、时间戳、操作原因)
  2. SAM注册表 - 通过键的最后修改时间戳查看账户创建记录
  3. PowerShell历史 - ConsoleHost_history.txt(USN DATA_EXTEND记录命令执行时间)
  4. Defender MPLog - 独立日志,包含威胁检测和ASR事件
  5. Prefetch - 程序执行证据
  6. 用户配置文件创建时间 - 首次登录时间(USN日志中的配置文件目录)

Steganography

隐写术

bash
steghide extract -sf image.jpg
zsteg image.png              # PNG/BMP analysis
stegsolve                    # Visual analysis
bash
steghide extract -sf image.jpg
zsteg image.png              # PNG/BMP分析
stegsolve                    # 可视化分析

PDF Analysis

PDF分析

bash
exiftool document.pdf        # Metadata (often hides flags!)
pdftotext document.pdf -     # Extract text
strings document.pdf | grep -i flag
binwalk document.pdf         # Embedded files
bash
exiftool document.pdf        # Metadata (often hides flags!)
pdftotext document.pdf -     # Extract text
strings document.pdf | grep -i flag
binwalk document.pdf         # Embedded files

Memory Forensics

内存取证

bash
vol3 -f memory.dmp windows.info
vol3 -f memory.dmp windows.pslist
vol3 -f memory.dmp windows.cmdline
vol3 -f memory.dmp windows.netscan
vol3 -f memory.dmp windows.dumpfiles --physaddr <addr>
bash
vol3 -f memory.dmp windows.info
vol3 -f memory.dmp windows.pslist
vol3 -f memory.dmp windows.cmdline
vol3 -f memory.dmp windows.netscan
vol3 -f memory.dmp windows.dumpfiles --physaddr <addr>

Disk Image Analysis

磁盘镜像分析

bash
undefined
bash
undefined

Mount

Mount

sudo mount -o loop,ro image.dd /mnt/evidence
sudo mount -o loop,ro image.dd /mnt/evidence

Autopsy / Sleuth Kit

Autopsy / Sleuth Kit

fls -r image.dd # List files icat image.dd <inode> # Extract by inode
fls -r image.dd # List files icat image.dd <inode> # Extract by inode

Carving

Carving

photorec image.dd foremost -i image.dd
undefined
photorec image.dd foremost -i image.dd
undefined

VM Forensics (OVA/VMDK)

虚拟机取证(OVA/VMDK)

bash
undefined
bash
undefined

OVA = TAR archive

OVA = TAR archive

tar -xvf machine.ova
tar -xvf machine.ova

7z reads VMDK directly

7z reads VMDK directly

7z l disk.vmdk | head -100 7z x disk.vmdk -oextracted "Windows/System32/config/SAM" -r
undefined
7z l disk.vmdk | head -100 7z x disk.vmdk -oextracted "Windows/System32/config/SAM" -r
undefined

Windows Password Hashes

Windows密码哈希

python
from impacket.examples.secretsdump import LocalOperations, SAMHashes

localOps = LocalOperations('SYSTEM')
bootKey = localOps.getBootKey()
sam = SAMHashes('SAM', bootKey)
sam.dump()  # username:RID:LM:NTLM:::
bash
undefined
python
from impacket.examples.secretsdump import LocalOperations, SAMHashes

localOps = LocalOperations('SYSTEM')
bootKey = localOps.getBootKey()
sam = SAMHashes('SAM', bootKey)
sam.dump()  # username:RID:LM:NTLM:::
bash
undefined

Crack with hashcat

Crack with hashcat

hashcat -m 1000 hashes.txt wordlist.txt
undefined
hashcat -m 1000 hashes.txt wordlist.txt
undefined

Bitcoin Tracing

比特币追踪

  • Use mempool.space API:
    https://mempool.space/api/tx/<TXID>
  • Peel chain: ALWAYS follow LARGER output
  • Look for consolidation transactions
  • Round amounts (5.0, 23.0 BTC) indicate peels
  • 使用mempool.space API:
    https://mempool.space/api/tx/<TXID>
  • 剥离链追踪: 始终跟随金额更大的输出
  • 查找合并交易
  • 整数金额(如5.0、23.0 BTC)表示剥离操作

Coredump Analysis

核心转储分析

bash
gdb -c core.dump
(gdb) info registers
(gdb) x/100x $rsp
(gdb) find 0x0, 0xffffffff, "flag"
bash
gdb -c core.dump
(gdb) info registers
(gdb) x/100x $rsp
(gdb) find 0x0, 0xffffffff, "flag"

Uncommon File Magic Bytes

不常见文件魔数

MagicFormatExtensionNotes
OggS
Ogg container
.ogg
Audio/video
RIFF
RIFF container
.wav
,
.avi
Check subformat
%PDF
PDF
.pdf
Check metadata & embedded objects
GCDE
PrusaSlicer binary G-code
.g
,
.bgcode
See 3d-printing.md
魔数格式扩展名说明
OggS
Ogg容器
.ogg
音频/视频
RIFF
RIFF容器
.wav
,
.avi
检查子格式
%PDF
PDF
.pdf
检查元数据与嵌入对象
GCDE
PrusaSlicer二进制G代码
.g
,
.bgcode
参阅3d-printing.md

Common Flag Locations

常见Flag位置

  • PDF metadata fields (Author, Title, Keywords)
  • Image EXIF data
  • Deleted files (Recycle Bin
    $R
    files)
  • Registry values
  • Browser history
  • Log file fragments
  • Memory strings
  • PDF元数据字段(作者、标题、关键词)
  • 图片EXIF数据
  • 已删除文件(回收站
    $R
    文件)
  • 注册表值
  • 浏览器历史记录
  • 日志文件片段
  • 内存字符串

VMware Snapshot Forensics

VMware快照取证

Converting VMware snapshots to memory dumps:
bash
undefined
将VMware快照转换为内存转储:
bash
undefined

.vmss (suspended state) + .vmem (memory) → memory.dmp

.vmss (suspended state) + .vmem (memory) → memory.dmp

vmss2core -W path/to/snapshot.vmss path/to/snapshot.vmem
vmss2core -W path/to/snapshot.vmss path/to/snapshot.vmem

Output: memory.dmp (analyzable with Volatility/MemprocFS)

Output: memory.dmp (analyzable with Volatility/MemprocFS)


**Malware hunting in snapshots (Armorless):**
1. Check Amcache for executed binaries near encryption timestamp
2. Look for deceptive names (Unicode lookalikes: `ṙ` instead of `r`)
3. Dump suspicious executables from memory
4. If PyInstaller-packed: `pyinstxtractor` → decompile `.pyc`
5. If PyArmor-protected: use PyArmor-Unpacker

**Ransomware key recovery via MFT:**
- Even if original files deleted, MFT preserves modification timestamps
- Seed-based encryption: recover mtime → derive key
```bash
vol3 -f memory.dmp windows.mftparser | grep flag

**快照中的恶意软件排查(无防护场景):**
1. 检查Amcache中加密时间点附近执行的二进制文件
2. 查找欺骗性文件名(Unicode相似字符:如`ṙ`替代`r`)
3. 从内存中转储可疑可执行文件
4. 若为PyInstaller打包:使用`pyinstxtractor` → 反编译`.pyc`文件
5. 若为PyArmor保护:使用PyArmor-Unpacker

**通过MFT恢复勒索软件密钥:**
- 即使原始文件已删除,MFT仍保留修改时间戳
- 基于种子的加密:恢复修改时间戳 → 推导密钥
```bash
vol3 -f memory.dmp windows.mftparser | grep flag

mtime as Unix epoch → seed for PRNG → derive encryption key

mtime为Unix时间戳 → PRNG种子 → 推导加密密钥

undefined
undefined

TFTP Netascii Decoding

TFTP Netascii解码

Problem: TFTP netascii mode corrupts binary transfers; Wireshark doesn't auto-decode.
Fix exported files:
python
undefined
问题: TFTP netascii模式会损坏二进制传输;Wireshark不会自动解码。
修复导出文件:
python
undefined

Replace netascii sequences:

Replace netascii sequences:

0d 0a → 0a (CRLF → LF)

0d 0a → 0a (CRLF → LF)

0d 00 → 0d (escaped CR)

0d 00 → 0d (escaped CR)

with open('file_raw', 'rb') as f: data = f.read() data = data.replace(b'\r\n', b'\n').replace(b'\r\x00', b'\r') with open('file_fixed', 'wb') as f: f.write(data)
undefined
with open('file_raw', 'rb') as f: data = f.read() data = data.replace(b'\r\n', b'\n').replace(b'\r\x00', b'\r') with open('file_fixed', 'wb') as f: f.write(data)
undefined

TLS Traffic Decryption via Weak RSA

基于弱RSA的TLS流量解密

Pattern (Tampered Seal): TLS 1.2 with
TLS_RSA_WITH_AES_256_CBC_SHA
(no PFS).
Attack flow:
  1. Extract server certificate from Server Hello packet (Export Packet Bytes →
    public.der
    )
  2. Get modulus:
    openssl x509 -in public.der -inform DER -noout -modulus
  3. Factor weak modulus (dCode, factordb.com, yafu)
  4. Generate private key:
    rsatool -p P -q Q -o private.pem
  5. Add to Wireshark: Edit → Preferences → TLS → RSA keys list
After decryption:
  • Follow TLS streams to see HTTP traffic
  • Export objects (File → Export Objects → HTTP)
  • Look for downloaded executables, API calls
特征(篡改证书): 使用
TLS_RSA_WITH_AES_256_CBC_SHA
的TLS 1.2(无PFS)。
攻击流程:
  1. 从Server Hello数据包中提取服务器证书(导出数据包字节 →
    public.der
  2. 获取模数:
    openssl x509 -in public.der -inform DER -noout -modulus
  3. 分解弱模数(使用dCode、factordb.com、yafu)
  4. 生成私钥:
    rsatool -p P -q Q -o private.pem
  5. 添加到Wireshark:编辑 → 首选项 → TLS → RSA密钥列表
解密后操作:
  • 追踪TLS流查看HTTP流量
  • 导出对象(文件 → 导出对象 → HTTP)
  • 查找下载的可执行文件、API调用

Browser Credential Decryption

浏览器凭证解密

Chrome/Edge Login Data decryption (requires master_key.txt):
python
from Crypto.Cipher import AES
import sqlite3, json, base64
Chrome/Edge登录数据解密(需master_key.txt):
python
from Crypto.Cipher import AES
import sqlite3, json, base64

Load master key (from Local State file, DPAPI-protected)

Load master key (from Local State file, DPAPI-protected)

with open('master_key.txt', 'rb') as f: master_key = f.read()
conn = sqlite3.connect('Login Data') cursor = conn.cursor() cursor.execute('SELECT origin_url, username_value, password_value FROM logins') for url, user, encrypted_pw in cursor.fetchall(): # v10/v11 prefix = AES-GCM encrypted nonce = encrypted_pw[3:15] ciphertext = encrypted_pw[15:-16] tag = encrypted_pw[-16:] cipher = AES.new(master_key, AES.MODE_GCM, nonce=nonce) password = cipher.decrypt_and_verify(ciphertext, tag) print(f"{url}: {user}:{password.decode()}")
undefined
with open('master_key.txt', 'rb') as f: master_key = f.read()
conn = sqlite3.connect('Login Data') cursor = conn.cursor() cursor.execute('SELECT origin_url, username_value, password_value FROM logins') for url, user, encrypted_pw in cursor.fetchall(): # v10/v11 prefix = AES-GCM encrypted nonce = encrypted_pw[3:15] ciphertext = encrypted_pw[15:-16] tag = encrypted_pw[-16:] cipher = AES.new(master_key, AES.MODE_GCM, nonce=nonce) password = cipher.decrypt_and_verify(ciphertext, tag) print(f"{url}: {user}:{password.decode()}")
undefined

Common Encodings

常见编码解码

bash
echo "base64string" | base64 -d
echo "hexstring" | xxd -r -p
bash
echo "base64string" | base64 -d
echo "hexstring" | xxd -r -p

ROT13: tr 'A-Za-z' 'N-ZA-Mn-za-m'

ROT13: tr 'A-Za-z' 'N-ZA-Mn-za-m'

undefined
undefined

WMI Persistence Analysis

WMI持久化分析

Pattern (Backchimney): Malware uses WMI event subscriptions for persistence (MITRE T1546.003).
Analysis tool:
bash
undefined
特征(Backchimney): 恶意软件使用WMI事件订阅实现持久化(MITRE T1546.003)。
分析工具:
bash
undefined

PyWMIPersistenceFinder on OBJECTS.DATA file

PyWMIPersistenceFinder on OBJECTS.DATA file

python PyWMIPersistenceFinder.py OBJECTS.DATA

**What to look for:**
- FilterToConsumerBindings with CommandLineEventConsumer
- Base64-encoded PowerShell in consumer commands
- Event filters triggered on system events (logon, timer)
python PyWMIPersistenceFinder.py OBJECTS.DATA

**排查要点:**
- 带有CommandLineEventConsumer的FilterToConsumerBindings
- 消费者命令中包含Base64编码的PowerShell脚本
- 由系统事件(登录、定时器)触发的事件过滤器

Deleted Partition Recovery

已删除分区恢复

Pattern (Till Delete Do Us Part): USB image with deleted partition table.
Recovery workflow:
bash
undefined
特征(Till Delete Do Us Part): USB镜像的分区表已被删除。
恢复流程:
bash
undefined

Check for partitions

Check for partitions

fdisk -l image.img # Shows no partitions
fdisk -l image.img # Shows no partitions

Recover partition table

Recover partition table

testdisk image.img # Interactive recovery
testdisk image.img # Interactive recovery

Or use kpartx to map partitions

Or use kpartx to map partitions

kpartx -av image.img # Maps as /dev/mapper/loop0p1
kpartx -av image.img # Maps as /dev/mapper/loop0p1

Mount recovered partition

Mount recovered partition

mount /dev/mapper/loop0p1 /mnt/evidence
mount /dev/mapper/loop0p1 /mnt/evidence

Check for hidden directories

Check for hidden directories

ls -la /mnt/evidence # Look for .dotfolders find /mnt/evidence -name ".*" # Find hidden files

**Flag hiding:** Path components as flag chars (e.g., `/.Meta/CTF/{f/l/a/g}`)
ls -la /mnt/evidence # Look for .dotfolders find /mnt/evidence -name ".*" # Find hidden files

**Flag隐藏方式:** 路径组件为Flag字符(例如`/.Meta/CTF/{f/l/a/g}`)

USB Audio Extraction from PCAP

从PCAP中提取USB音频

Pattern (Talk To Me): USB isochronous transfers contain audio data.
Extraction workflow:
bash
undefined
特征(Talk To Me): USB等时传输包含音频数据。
提取流程:
bash
undefined

Export ISO data with tshark

Export ISO data with tshark

tshark -r capture.pcap -T fields -e usb.iso.data > audio_data.txt
tshark -r capture.pcap -T fields -e usb.iso.data > audio_data.txt

Convert to raw audio and import into Audacity

Convert to raw audio and import into Audacity

Settings: signed 16-bit PCM, mono, appropriate sample rate

Settings: signed 16-bit PCM, mono, appropriate sample rate

Listen for spoken flag characters

Listen for spoken flag characters


**Identification:** USB transfer type URB_ISOCHRONOUS = real-time audio/video

**识别方式:** USB传输类型URB_ISOCHRONOUS = 实时音频/视频

PowerShell Ransomware Analysis

PowerShell勒索软件分析

Pattern (Email From Krampus): PowerShell memory dump + network capture.
Analysis workflow:
  1. Extract script blocks from minidump:
bash
python power_dump.py powershell.DMP
特征(Email From Krampus): PowerShell内存转储 + 网络捕获。
分析流程:
  1. 从minidump中提取脚本块:
bash
python power_dump.py powershell.DMP

Or: strings powershell.DMP | grep -A5 "function|Invoke-"

Or: strings powershell.DMP | grep -A5 "function|Invoke-"


2. Identify encryption (typically AES-CBC with SHA-256 key derivation)

3. Extract encrypted attachment from PCAP:
```bash

2. 识别加密方式(通常为AES-CBC + SHA-256密钥推导)

3. 从PCAP中提取加密附件:
```bash

Filter SMTP traffic in Wireshark

Filter SMTP traffic in Wireshark

Export attachment, base64 decode

Export attachment, base64 decode


4. Find encryption key in memory dump:
```bash

4. 在内存转储中查找加密密钥:
```bash

Key often generated with Get-Random, regex search:

Key often generated with Get-Random, regex search:

strings powershell.DMP | grep -E '^[A-Za-z0-9]{24}$' | sort | head

5. Find archive password similarly, decrypt layers
strings powershell.DMP | grep -E '^[A-Za-z0-9]{24}$' | sort | head

5. 类似方式查找归档密码,逐层解密

Linux Attack Chain Forensics

Linux攻击链取证

Pattern (Making the Naughty List): Full attack timeline from logs + PCAP + malware.
Evidence sources:
bash
undefined
特征(Making the Naughty List): 从日志、PCAP、恶意软件中还原完整攻击时间线。
证据来源:
bash
undefined

SSH session commands

SSH session commands

grep -A2 "session opened" /var/log/auth.log
grep -A2 "session opened" /var/log/auth.log

User command history

User command history

cat /home/*/.bash_history
cat /home/*/.bash_history

Downloaded malware

Downloaded malware

find /usr/bin -newer /var/log/auth.log -name "ms*"
find /usr/bin -newer /var/log/auth.log -name "ms*"

Network exfiltration

Network exfiltration

tshark -r capture.pcap -Y "tftp" -T fields -e tftp.source_file

**Common malware pattern:** AES-ECB encrypt + XOR with same key, save as .enc
tshark -r capture.pcap -Y "tftp" -T fields -e tftp.source_file

**常见恶意软件模式:** AES-ECB加密 + 同密钥XOR,保存为.enc文件

Firefox Browser History (places.sqlite)

Firefox浏览器历史记录(places.sqlite)

Pattern (Browser Wowser): Flag hidden in browser history URLs.
bash
undefined
特征(Browser Wowser): Flag隐藏在浏览器历史URL中。
bash
undefined

Quick method

Quick method

strings places.sqlite | grep -i "flag|MetaCTF"
strings places.sqlite | grep -i "flag|MetaCTF"

Proper forensic method

Proper forensic method

sqlite3 places.sqlite "SELECT url FROM moz_places WHERE url LIKE '%flag%'"

**Key tables:** `moz_places` (URLs), `moz_bookmarks`, `moz_cookies`
sqlite3 places.sqlite "SELECT url FROM moz_places WHERE url LIKE '%flag%'"

**关键表:** `moz_places`(URL)、`moz_bookmarks`、`moz_cookies`

DTMF Audio Decoding

DTMF音频解码

Pattern (Phone Home): Audio file contains phone dialing tones encoding data.
bash
undefined
特征(Phone Home): 音频文件包含电话拨号音编码的数据。
bash
undefined

Decode DTMF tones

Decode DTMF tones

sox phonehome.wav -t raw -r 22050 -e signed-integer -b 16 -c 1 - |
multimon-ng -t raw -a DTMF -

**Post-processing:** Phone number may contain octal-encoded ASCII after delimiter (#):
```python
sox phonehome.wav -t raw -r 22050 -e signed-integer -b 16 -c 1 - |
multimon-ng -t raw -a DTMF -

**后处理:** 电话号码中可能包含分隔符(#)后的八进制编码ASCII:
```python

Convert octal groups to ASCII

Convert octal groups to ASCII

octal_groups = ["115", "145", "164", "141"] # M, e, t, a flag = ''.join(chr(int(g, 8)) for g in octal_groups)
undefined
octal_groups = ["115", "145", "164", "141"] # M, e, t, a flag = ''.join(chr(int(g, 8)) for g in octal_groups)
undefined