dexisworking/Project_Helix_Write-up
GitHub: dexisworking/Project_Helix_Write-up
这是一个详尽的数字取证 CTF 解题文档,展示了从 NTFS MFT 恢复被删文件元数据到捕获并解码射频信号(FSK)的完整调查流程。
Stars: 0 | Forks: 0
# 🧬 Project Helix — CTF 数字取证 Write-Up
**平台:** TCM Security CTF
**类别:** Digital Forensics (数字取证)
**难度:** 困难 (Hard)
**Flag:** `TCM{V01D_S1GN4L_4U7H3N71C473D}`
**作者:** [Dibyanshu Sekhar](https://github.com/dexisworking)
**日期:** 2026 年 3 月 12 日
## 🗂️ 目录
- [场景](#-scenario)
- [快速总结](#-quick-summary)
- [攻击链](#-attack-chain)
- [阶段 1 — 识别取证对象](#phase-1--identifying-the-forensic-artifact)
- [阶段 2 — LNK 快捷方式分析](#phase-2--lnk-shortcut-analysis)
- [阶段 3 — MFT 分析与 Zone.Identifier 恢复](#phase-3--mft-analysis--zoneidentifier-recovery)
- [阶段 4 — 恢复 freq.txt](#phase-4--recovering-and-analyzing-freqtxt)
- [阶段 5 — 捕获信号](#phase-5--capturing-the-signal)
- [阶段 6 — 解码 FSK 信号](#phase-6--decoding-the-fsk-signal)
- [阶段 7 — 佐证证据](#phase-7--corroborating-evidence)
- [阶段 8 — 破解归档](#phase-8--cracking-the-archive)
- [使用工具](#-tools-used)
- [关键要点](#-key-takeaways)
- [仓库结构](#-repo-structure)
## 🔬 场景
三天前,首席遗传学家 **Dr. Owens** 发送了最后一条紧急传输,声称他截获了一个生物广播——一个重复的信号,他认为这是一个表现为射频干扰的合成 RNA 序列。
Owens 违反了第 4 号协议,开始对高风险标本进行未经授权的测试。此后不久,所有通讯均告中断。对他实验室的安全扫描确认他已失踪。他的工作站被发现处于开机状态,但**所有研究资料已被擦除**。
**任务:** 恢复被删除的笔记,并找到解锁其加密标本归档的基于 RNA 的密钥。
## ⚡ 快速总结
| 发现 | 数值 |
|---|---|
| 恢复的文件 | `freq.txt` (通过 NTFS MFT Zone.Identifier ADS) |
| 下载 URL | `https://ctf.tcmsecurity.com/3c7d7997c1a7/freq.txt` |
| 广播频率 | `3817.3 Hz` |
| 信号编码 | 4 频率 FSK → RNA 碱基 → 四进制 → ASCII |
| 解码密钥 | `\|RNAPolymeraseSlip\|` |
| Flag | `TCM{V01D_S1GN4L_4U7H3N71C473D}` |
## 🔗 攻击链
```
NTFS Triage Image
│
▼
LNK Shortcut ──────────────► freq.txt existed in Downloads
│
▼
$MFT Parser ──────────────► Zone.Identifier ADS → Download URL
│
▼
curl freq.txt ──────────────► Lab logs + 3817.3 Hz frequency
│
▼
WebSocket Capture ──────────► 164s raw PCM audio
│
▼
FFT + FSK Decode ───────────► |RNAPolymeraseSlip|
│
▼
pyzipper AES-256 ───────────► TCM{V01D_S1GN4L_4U7H3N71C473D}
```
## 阶段 1 — 识别取证对象
`/home/dex/Projects/C/` 处的取证对象是一个提取的 NTFS 评估镜像——不是完整的磁盘转储,但内容足以进行工作。
```
$Boot — NTFS boot sector
$MFT — Master File Table (134 MB)
$LogFile — Journal
$Secure_$SDS
ProgramData/
Users/
└── drowens/ — Dr. Owens' profile
Windows/
```
经典的 NTFS 布局。一个真实用户:`drowens`。
## 阶段 2 — LNK 快捷方式分析
`%APPDATA%\Microsoft\Windows\Recent` 中的 Windows `.lnk` 文件即使在目标文件被删除后仍然保留。它们包含原始文件路径和机器名称。
```
find /home/dex/Projects/C/Users/drowens -name "*.lnk" 2>/dev/null
# → .../Recent/freq.lnk
strings .../freq.lnk
# → freq.txt
# → C:\Users\drowens\Downloads\freq.txt
# → helix
```
**发现:** 一个名为 `freq.txt` 的文件曾位于 Owens 的下载文件夹中。机器名称:`helix`。
## 阶段 3 — MFT 分析与 Zone.Identifier 恢复
### 为什么 MFT 很重要
当文件在 NTFS 上被删除时,MFT 记录不会立即消失——只有**使用中标志 (in-use flag)** 被清除。元数据(包括**备用数据流 (ADS)**)通常会保留下来。
`Zone.Identifier` ADS 附加到每个互联网下载的文件上,并包含一个 `HostUrl` 字段——即确切的源 URL。
### MFT 解析器
完整脚本请参阅 [`scripts/mft_parser.py`](scripts/mft_parser.py)。核心逻辑:
1. 遍历 `$MFT` 中所有 1024 字节的 `FILE` 记录
2. 应用 USA 修复(扇区保护)
3. 提取 `0x30`(文件名)和 `0x80`(数据)属性
4. 筛选 `freq.txt`,提取 `Zone.Identifier` ADS
### 结果
```
Record 41: freq.txt [DELETED]
$DATA (resident): Zone.Identifier stream
[ZoneTransfer]
ZoneId=3
HostUrl=https://ctf.tcmsecurity.com/3c7d7997c1a7/freq.txt
```
实际的文件数据簇已被擦除——但 ADS 足够小,以内联方式存储在 MFT 记录中。删除操作没有触及它。
## 阶段 4 — 恢复和分析 freq.txt
```
curl -o /tmp/freq.txt "https://ctf.tcmsecurity.com/3c7d7997c1a7/freq.txt"
```
这个 441 KB 的文件包含两部分:
### Owens 的实验室日志
```
LOG_086: Found a hum. It's too constant... did I just discover the next WOW signal??
Not a machine. Too rhythmic. Too... wet. Like a heartbeat in the wires.
LOG_087: It's getting louder... it repeats|it repeats|it repeats
Every 78 seconds.
LOG_088: It speaks in strands. A four-fold tongue. I saw it on the waterfall today.
A... C... G... U... quaternary? If I start counting from 0 it starts to make sense.
LOG_089: Black van in the driveway again. They know what I found.
THEY ARE TRANSCRIBING ME. STAY OFF THE LADDER.
```
### 频率扫描
从 1000.0 到 5000.0 Hz 的扫描,除了一个之外全部为 `(X)`:
```
3817.3 (?) ← THE ONE
```
### 编码方案(来自 LOG_088)
| RNA 碱基 | 四进制值 |
|---|---|
| A | 0 |
| C | 1 |
| G | 2 |
| U | 3 |
4 碱基密码子的公式:
```
ASCII = b0×64 + b1×16 + b2×4 + b3
```
示例:`CCAG` = 1(64) + 1(16) + 0(4) + 2 = **82** = `'R'`
## 阶段 5 — 捕获信号
CTF 无线电页面暴露了一个 WebSocket 端点:
```
wss://ctf.tcmsecurity.com/3c7d7997c1a7?freq={freq}
```
音频格式:44100 Hz 采样率的原始 `Int16` PCM,单声道。
捕获脚本请参阅 [`scripts/capture_signal.py`](scripts/capture_signal.py)。关键决策:**捕获 165 秒**(超过 2 个完整的 78 秒周期)。
## 阶段 6 — 解码 FSK 信号
完整的解调器请参阅 [`scripts/fsk_decoder.py`](scripts/fsk_decoder.py)。
**方法:**
1. 将原始 PCM 加载到 numpy 中
2. 滑动 FFT 窗口(N=2048,hop=1024)以查找每帧的主导频率
3. 将连续的相同频率帧合并为片段
4. 丢弃小于 0.15s 的片段(噪声)
5. 将静音间隙之间的片段分组为 4 碱基密码子
### FSK 频率映射表
| 频率 | RNA 碱基 | 四进制 |
|---|---|---|
| 1000 Hz | A | 0 |
| 2000 Hz | C | 1 |
| 3000 Hz | G | 2 |
| 4000 Hz | U | 3 |
每个碱基:~0.85s · 静音分隔符:~0.75s
### 完整密码子表(一个周期)
| # | 密码子 | 计算 | 字符 |
|---|---|---|---|
| 1 | CUUA | 1(64)+3(16)+3(4)+0 = 124 | `\|` |
| 2 | CCAG | 1(64)+1(16)+0(4)+2 = 82 | `R` |
| 3 | CAUG | 1(64)+0(16)+3(4)+2 = 78 | `N` |
| 4 | CAAC | 1(64)+0(16)+0(4)+1 = 65 | `A` |
| 5 | CCAA | 1(64)+1(16)+0(4)+0 = 80 | `P` |
| 6 | CGUU | 1(64)+2(16)+3(4)+3 = 111 | `o` |
| 7 | CGUA | 1(64)+2(16)+3(4)+0 = 108 | `l` |
| 8 | CUGC | 1(64)+3(16)+2(4)+1 = 121 | `y` |
| 9 | CGUC | 1(64)+2(16)+3(4)+1 = 109 | `m` |
| 10 | CGCC | 1(64)+2(16)+1(4)+1 = 101 | `e` |
| 11 | CUAG | 1(64)+3(16)+0(4)+2 = 114 | `r` |
| 12 | CGAC | 1(64)+2(16)+0(4)+1 = 97 | `a` |
| 13 | CUAU | 1(64)+3(16)+0(4)+3 = 115 | `s` |
| 14 | CGCC | 101 | `e` |
| 15 | CCAU | 1(64)+1(16)+0(4)+3 = 83 | `S` |
| 16 | CGUA | 108 | `l` |
| 17 | CGGC | 1(64)+2(16)+2(4)+1 = 105 | `i` |
| 18 | CUAA | 1(64)+3(16)+0(4)+0 = 112 | `p` |
| 19 | CUUA | 124 | `\|` |
**解码结果:** `|RNAPolymeraseSlip|`
## 阶段 7 — 佐证证据
### Windows 搜索数据库
```
sqlite3 /tmp/Windows_search.db \
"SELECT System_ItemName FROM SystemIndex WHERE System_ItemName LIKE '%freq%';"
# → freq.txt
```
删除前已建立索引。确认文件曾存在。
### 注册表 (NTUSER.DAT)
```
OpenSavePidlMRU\* → 0 = freq.txt
RecentDocs → 0 = freq.txt / freq.lnk
FileExts\.TS\UserChoice → Hash = xKeyJTOPm78= ← red herring (standard Windows UserChoice hash)
OneDrive → HostNameCollection = helix
```
## 阶段 8 — 破解归档
```
curl -o /tmp/flag.zip "https://ctf.tcmsecurity.com/3c7d7997c1a7/flag.zip"
# AES-256 encrypted, requires pyzipper (standard unzip can't handle it)
```
### 密码墓地
| 尝试 | 原因 |
|---|---|
| `eraseSlip\|\|RNAPolym` | 错误帧的单周期解码 |
| `eraseSlipRNAPolym` | 无竖线分隔符 |
| `RNAPolymeraseSlippage` | 完整的生物学术语 |
| `RNAPolymeraseSlip` | 文本正确,**缺少定界符** |
| `3817.3` | 频率 |
| `helix` / `HELIX` | 机器名称 |
| `drowens` | 用户名 |
| `xKeyJTOPm78=` | 注册表红鲱鱼(误导项) |
### 获胜者
```
import pyzipper
with pyzipper.AESZipFile('/tmp/flag.zip') as z:
z.setpassword(b'|RNAPolymeraseSlip|')
print(z.read('flag.txt').decode())
# TCM{V01D_S1GN4L_4U7H3N71C473D}
```
参见 [`scripts/decrypt_flag.py`](scripts/decrypt_flag.py)。
## 🛠️ 使用工具
| 工具 | 用途 |
|---|---|
| `strings` | 从 LNK 文件中提取可读文本 |
| `Python 3` | MFT 解析、WebSocket 捕获、FFT 解码 |
| `curl` | 从 CTF 服务器下载文件 |
| `numpy` | FFT 计算和信号处理 |
| `websockets` | 连接到音频 WebSocket 流 |
| `python-registry` | 解析 NTUSER.DAT 注册表配置单元 |
| `sqlite3` | 查询 Windows 搜索数据库 |
| `pyzipper` | 处理 AES-256 加密的 zip 文件 |
安装依赖:
```
pip install numpy websockets python-registry pyzipper
```
## 💡 关键要点
1. **`Zone.Identifier` ADS 非常有用。** 即使文件的数据簇已经消失,下载 URL 仍可在 MFT 记录中幸存。它作为一个小的常驻流内联存储——删除操作通常不会触及它。
2. **捕获的信号要比你需要的更多。** 一个周期不足以识别消息的开始和结束。两个完整的周期使边界变得显而易见。
3. **定界符可以是数据。** `|` 字符看起来像是格式符号——它们实际上是显式编码为密码子 `CUUA` 的,并且是密码本身的一部分。
4. **仔细阅读叙事文本。** 每一个线索都在 Owens 的日志中:周期(78s)、字母表(A/C/G/U)、编码(四进制)和起始索引(0)。CTF 设计者添加背景故事不仅仅是为了装饰。
5. **不要在红鲱鱼(误导项)上花费太多时间。** 注册表哈希 `xKeyJTOPm78=` 看起来很有希望,但只是一个标准的 Windows UserChoice 哈希。如果某件事在几分钟内行不通,就继续往下做。
## 📁 仓库结构
```
Project-Helix-Writeup/
├── README.md ← Main technical write-up
├── C/ ← NTFS triage artifact set
├── docs/
│ ├── writeup.md ← Full narrative write-up
│ └── Project_Helix_CTF_WriteUp.pdf ← PDF export
├── scripts/
│ ├── mft_parser.py ← NTFS $MFT parser with USA fixup
│ ├── capture_signal.py ← WebSocket audio capture (165s)
│ ├── fsk_decoder.py ← FFT-based FSK demodulator + RNA decoder
│ └── decrypt_flag.py ← AES-256 zip decryption
└── artifacts/
└── codon_table.md ← Full codon decode reference
```
*— Dibyanshu Sekhar · 2026 年 3 月*
标签:ADS, AES解密, DAST, DOS头擦除, FSK解码, LNK分析, MFT, NTFS, Python, RF信号捕获, SecList, TCM Security, Zone.Identifier, 云资产清单, 内存取证, 取证挑战, 密码破解, 恶意软件分析, 数字取证, 数据恢复, 无后门, 无线电, 电子取证, 脚本工具, 自动化脚本, 逆向工具, 逆向工程, 隐写术