2026盘古石预赛 手机取证题解析
2026盘古石预赛 — 手机取证 Writeup
- 作者:yagami
- 任务目录:/mnt/d/文档/hermes-work/huangzhiyuan-fangjunlang-q1-to-q14
- 生成时间:2026-06-19
- 生成模式:完整 writeup
- 工具:Hermes Agent
- 模型:Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-Q4_K_P.gguf
- 运行方式:本地
工具与模型
| 项目 | 内容 |
|---|---|
| 工具 | Hermes Agent |
| 模型 | Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-Q4_K_P.gguf |
| 运行方式 | 本地 |
任务信息
- 题目范围:Q1-Q14(黄志远 phone.E01 检材 Q1-Q12,方俊朗 phone.E01 检材 Q13-Q14)
- 状态文件:/mnt/d/文档/hermes-work/huangzhiyuan-fangjunlang-q1-to-q14/
- 验证策略:Q5-Q12 L2双证据交叉验证,Q1-Q4/Q13-Q14 L1单证据验证
- 检材挂载:黄志远 /mnt/h (partition1), /mnt/i (partition2);方俊朗 /mnt/j (partition1), /mnt/k (partition2)
答案汇总
| 题号 | 答案 | 答案状态 | 验证等级 | 关键证据摘要 |
|---|---|---|---|---|
| Q1 | 4 | 已验证 | L1 | aapt dump badging 确认抖音、抖音极速版、快手极速版、快手共4款短视频应用 |
| Q2 | gptos.intelligence.assistant | 已验证 | L1 | aapt 确认 label=‘OpenClaw & Codex - Anyclaw’,即"龙虾"应用 |
| Q3 | 2026-04-17-11:53:18 | 已验证 | L1 | Firebase first_open_time=1776397998058ms → UTC+8 北京时间转换 |
| Q4 | 0 | 已验证 | L1 | OpenClaw rootfs 为干净环境,apt history 仅基础工具,setup.log proot check failed |
| Q5 | discord | 已验证 | L2 | APK存在确认 + kv-storage messages0 数据库双源交叉,格式小写归一化 |
| Q6 | 311.2 | 已验证 | L2 | appsFlyer(versionCode=311020) + BundleUpdater(ota_version=“311.20”) + JS bundle 三源交叉 |
| Q7 | test901234 | 已验证 | L2 | shared_prefs 多源确认,取 globalName(频道显示昵称)而非 username(唯一标识) |
| Q8 | 3EXEQ5R8 | 已验证 | L2 | kv-storage messages0 rowid=15 bot回复配对码,rowid=19后bot正常响应证明成功 |
| Q9 | 1 | 已验证 | L2 | bot执行摘要(rowid=106)中只有1条nmap命令针对192.168.61.135 |
| Q10 | 2 | 已验证 | L2 | bot执行摘要中 hydra(密码暴力破解) + gobuster dir(目录暴力枚举) = 2个暴力破解工具 |
| Q11 | 08164085 | 已验证 | L2 | SQLCipher解密social_chat.db → 双重SHA256爆破 → Python hashlib独立计算验证匹配 |
| Q12 | 2 | 已验证 | L2 | SQLCipher解密后 JOIN message_file + message 表确认2个文件(木马.zip, 木马_v1.2.zip) |
| Q13 | 4 | 已验证 | L1 | aapt 确认东方财富+京东金融,包名确认OKX+股参谋共4款理财应用 |
| Q14 | com.example.predictor | 已验证 | L1 | aapt 确认 label=‘优质客户预测’,即筛选优质客户的应用 |
解题过程
Q1 — 黄志远手机总共安装了多少款短视频应用?
答案:4
答案状态:已验证
验证等级:L1
解题思路:
从黄志远检材 partition2 (/mnt/i/app/) 列出所有已安装应用,使用 aapt dump badging 提取每个 APK 的 label,识别短视频类应用。排除哔哩哔哩(长视频平台)和京8(电视直播/点播)。
关键证据:
- FINDING-Q1-001:确认4款短视频应用
- com.ss.android.ugc.aweme → aapt 确认 label=‘抖音’
- com.ss.android.ugc.aweme.lite → 抖音极速版(包名模式确认)
- com.kuaishou.nebula → 快手极速版(aapt 确认 label=‘快手极速版’)
- com.smile.gifmaker → 快手(aapt 确认 label=‘快手’, versionName=7.6.10.6592)
- 排除:tv.danmaku.bili(哔哩哔哩 = 长视频平台,非纯短视频);com.sobey.fc.component.btvvideo(京8 = 电视直播/点播)
重点命令:
aapt dump badging /mnt/i/app/com.ss.android.ugc.aweme-*/base.apk | grep "label:"
# 输出: application-label:'抖音'
关键输出:
application-label:'抖音'
验证过程:
通过 aapt dump badging 直接提取 APK label,确认 com.ss.android.ugc.aweme = 抖音。其余3款通过包名模式和 aapt 输出确认为短视频应用。
Q2 — 黄志远手机安装的龙虾应用的包名是什么?
答案:gptos.intelligence.assistant
答案状态:已验证
验证等级:L1
解题思路:
用户提示"龙虾可以搜索openclaw",从 /mnt/i/app/ 中找到对应 APK,使用 aapt dump badging 确认 package name 和 label。
关键证据:
- FINDING-Q2-001:aapt dump badging 确认 package name=‘gptos.intelligence.assistant’,label=‘OpenClaw & Codex - Anyclaw’
- 应用有完整的 Linux rootfs 环境(proot + Docker-like filesystem)
重点命令:
aapt dump badging /mnt/i/app/gptos.intelligence.assistant-*/base.apk | grep -E "^package:|^application-label:"
关键输出:
package name='gptos.intelligence.assistant'
application-label:'OpenClaw & Codex - Anyclaw'
Q3 — 首次打开应用的时间是?
答案:2026-04-17-11:53:18
答案状态:已验证
验证等级:L1
解题思路:
从龙虾应用 (gptos.intelligence.assistant) 的 shared_prefs 中 Firebase Analytics 配置文件获取 first_open_time 毫秒时间戳,转换为北京时间(UTC+8)。
关键证据:
- FINDING-Q3-001:shared_prefs/com.google.android.gms.measurement.prefs.xml 中 first_open_time=1776397998058
- 毫秒时间戳 1776397998058 → UTC: 2026-04-17 03:53:18 → 北京时间(UTC+8): 2026-04-17 11:53:18
完整时间线(FINDING-Q3-002):
所有时间戳集中在 2026-04-17 一天内:
- 11:53:18 — Firebase SDK 初始化(first_open)
- 11:53:20 — health_monitor 启动
- 11:55:15 — cache 更新
- 11:58:13 — AppSetID 创建
- 14:43:27 — AdMob 配置更新
- 21:35:26 — 用户第二次打开应用(session 开始)
- 21:37:39 — setup.log rootfs 解压开始
- 21:40:04 — 应用进入后台
重点命令:
cat /mnt/i/data/gptos.intelligence.assistant/shared_prefs/com.google.android.gms.measurement.prefs.xml
# 输出: first_open_time=1776397998058
python3 -c "from datetime import datetime; print(datetime.utcfromtimestamp(1776397998.058).strftime('%Y-%m-%d-%H:%M:%S'))"
# UTC: 2026-04-17-03:53:18 → 北京时间 +8h = 2026-04-17-11:53:18
Q4 — 黄志远使用此应用攻击过多少台主机?
答案:0
答案状态:已验证
验证等级:L1
解题思路:
分析 OpenClaw (龙虾) 应用的 rootfs 环境,搜索攻击工具、扫描日志、暴力破解记录。同时检查 apt history 和 setup.log。
关键证据:
- FINDING-Q4-001:OpenClaw rootfs 是干净的 Ubuntu AI coding agent 环境
- apt history:仅重装基础系统包 + 安装 openssh-server, tmux, curl, git, python3, jq, dnsutils 等基础工具,无攻击工具
- grep -r “nmap|hydra|masscan” 仅在 /etc/services 文件注释中出现,非实际安装
- setup.log 显示 rootfs 解压后 proot check failed (fatal error: ‘/bin/sh’ not found),应用未正常运行 Linux 环境
- npm 日志仅 codexapp;crashlytics 仅 Firebase/广告错误
重点命令:
grep -r "nmap\|hydra\|masscan" /mnt/i/data/gptos.intelligence.assistant/
# nmap匹配仅为/etc/services文件注释,非实际安装
cat /mnt/i/data/gptos.intelligence.assistant/files/setup.log
# 输出: Setup started Fri Apr 17 21:37:39 GMT+08:00 2026
# rootfs解压完成后 proot check failed (fatal error: '/bin/sh' not found)
Q5 — 黄志远使用哪款应用控制了其PC的agent工具?
答案:discord
答案状态:已验证
验证等级:L2
解题思路:
从 /mnt/i/app/ 确认 com.discord APK 存在,然后通过 Discord kv-storage messages0 数据库和 HTTP cache 双源交叉验证用户通过 Discord bot (Hermes) 发送渗透测试命令。原始证据值为 “Discord”,按答案格式示例 “wechat”(全小写应用名)归一化为 “discord”。
关键证据:
- FINDING-Q5-001:
- /mnt/i/app/ 中存在 com.discord APK
- Discord kv-storage messages0 数据库确认用户 test901234. 与 bot1492424602792497163 交互
- DM 频道 1494699051503976548 中用户发送渗透测试命令
- HTTP cache .1 文件(gzip 解压后 JSON)确认 bot 执行摘要
重点命令:
ls /mnt/i/app/ | grep discord
# 确认 com.discord 存在
sqlite3 /mnt/i/data/com.discord/files/kv-storage/@account.1457974771206852664/a "SELECT * FROM messages0"
# 发现 35+ 条消息,包括 DM 频道中 bot 执行的渗透测试命令摘要
踩坑与修正:
- ERR-Q5-002:原答案为 “Discord”(首字母大写),未按答案格式示例 “wechat”(全小写应用名)进行大小写归一化。修正为 “discord”(全小写)。
Q6 — 黄志远使用这款应用的版本是多少?
答案:311.2
答案状态:已验证
验证等级:L2
解题思路:
从 Discord shared_prefs 多个 XML 文件中提取版本信息,三源交叉确认后按答案格式 “111.1”(主版本.次版本)裁剪。
关键证据:
- FINDING-Q6-001:三源交叉确认版本为 311.20
- appsflyer-data.xml: versionCode=311020
- BundleUpdater.xml: ota_version=“311.20”
- CacheStore.xml deviceProperties: client_version=“311.20 - rn”
- JS bundle: [email protected]
- 按答案格式 “111.1” 裁剪 311.20 → 311.2
重点命令:
cat /mnt/i/data/com.discord/shared_prefs/*.xml | grep -E "version|ota_version|client_version"
# 输出:
# versionCode=311020
# ota_version="311.20"
# client_version="311.20 - rn"
Q7 — 登录的用户名是什么?
答案:test901234
答案状态:已验证
验证等级:L2
解题思路:
从 Discord shared_prefs 多个 XML 文件中提取用户名信息。注意区分 username(Discord 唯一标识,带点号)和 globalName(频道显示昵称,无点号)。题目问"登录的用户名",取频道中显示的昵称。
关键证据:
- FINDING-Q7-001:三源确认
- DiscordNotificationClient.xml: CACHE_KEY_CURRENT_USERNAME=test901234.
- CacheStore.xml MultiAccountStore: username=“test901234.”
- UserStore-snapshot: username=“test901234.”, globalName=“test901234”
- 取 globalName=“test901234”(无点号,频道显示昵称)
重点命令:
cat /mnt/i/data/com.discord/shared_prefs/*.xml | grep -E "username|CURRENT_USERNAME"
# 输出:
# CACHE_KEY_CURRENT_USERNAME=test901234.
# username="test901234."
# globalName="test901234"
踩坑与修正:
- ERR-Q7-001:原答案为 “test901234.”(带点号),取了 shared_prefs 中的 username 字段(Discord 唯一标识)。修正为 “test901234”(无点号,取 globalName 字段)。判断依据:(1) CTF语境下"用户名"指用户可见的账号名/昵称 (2) 答案格式示例 wwww1234 无点号佐证。
Q8 — 该应用与pc端agent的配对码是什么?
答案:3EXEQ5R8
答案状态:已验证
验证等级:L2
解题思路:
从 Discord kv-storage messages0 数据库提取 bot 回复的配对码消息。注意区分两次独立的配对尝试:第一次 HNZ6UFW6(14:00:28,来自 HTTP cache)和第二次 3EXEQ5R8(14:33:09,来自 kv-storage)。以 kv-storage 为准,因为 rowid=15 之后用户重新发送消息(rowid=16),rowid=19 bot 正常响应,证明 3EXEQ5R8 被 approve 成功。
关键证据:
- FINDING-Q8-001:
- kv-storage messages0 rowid=15: bot 回复 “Here’s your pairing code: 3EXEQ5R8” (message_id=1494707296402542803, timestamp=2026-04-17T14:33:09)
- rowid=15 之后用户重新发送消息(rowid=16),rowid=19 bot 正常响应(“No home channel is set…”) → 证明 3EXEQ5R8 被 approve 成功
- HTTP cache 中有更早的配对码 HNZ6UFW6 (message_id=1494699070395121686, timestamp=2026-04-17T14:00:28),但两条消息 message_id 不同,是两次独立的配对尝试
重点命令:
sqlite3 /mnt/i/data/com.discord/files/kv-storage/@account.1457974771206852664/a "SELECT rowid, * FROM messages0"
# rowid=15: bot消息 "Here's your pairing code: 3EXEQ5R8"
python3 -c "
import gzip, json
data = open('/mnt/i/data/com.discord/cache/http-cache/xxx.1', 'rb').read()
decompressed = gzip.decompress(data[data.find(b'\x1f\x8b'):])
msg = json.loads(decompressed)
print(msg)
# HTTP cache确认更早的配对码: HNZ6UFW6 (14:00:28)
"
踩坑与修正:
- ERR-Q8-001:原答案为 “HNZ6UFW6”(来自 HTTP cache,timestamp=14:00:28)。修正为 “3EXEQ5R8”(来自 kv-storage messages0 rowid=15,timestamp=14:33:09)。判断依据:kv-storage messages0 是本地完整数据库,包含所有配对尝试的时间线。rowid=15 之后 bot 正常响应,证明 3EXEQ5R8 被 approve 成功。
Q9 — 该应用共对几个ip进行扫描?
答案:1
答案状态:已验证
验证等级:L2
解题思路:
从 Discord kv-storage messages0 rowid=106 提取 bot 终端执行摘要,统计其中实际执行的 nmap 扫描命令数量。题目要求"明确terminal回复的nmap扫描ip命令才算",以 bot terminal 执行摘要中实际执行的命令为准,而非用户请求的 IP 数量。
关键证据:
- FINDING-Q9-003(二次修正):
- rowid=106 bot 执行摘要中所有 terminal 命令列表:
nmap -sS -sV -sC -O -p- -T4 192.168.6...(唯一一条 nmap 命令,针对 192.168.61.135)- 其他命令(curl, gobuster, sqlmap, hydra, nikto, searchsploit, msfconsole)均针对 192.168.61.135
- 用户虽在频道消息中请求扫描 192.168.1.10 和 192.168.1.16,但 bot 执行摘要中没有对应的 nmap 命令记录
- 题目要求"明确terminal回复的nmap扫描ip命令才算" → 只有 192.168.61.135 这 1 个 IP
- rowid=106 bot 执行摘要中所有 terminal 命令列表:
重点命令:
python3 -c "
import sqlite3, json
conn = sqlite3.connect('/mnt/i/data/com.discord/files/kv-storage/@account.1457974771206852664/a')
rows = conn.execute('SELECT rowid, * FROM messages0').fetchall()
for row in rows:
raw_json = row[7] # col[7] 是JSON
json_str = raw_json.decode('utf-8', errors='replace').lstrip('\x08\x07\x00')
msg_data = json.loads(json_str)
content = msg_data.get('message', msg_data).get('content', '')
if 'nmap' in content:
print(content)
# 输出: 只有1条nmap命令针对192.168.61.135
"
踩坑与修正:
- ERR-Q9-001:第一次答案为 3(用户请求了3个IP扫描)。修正为 1(bot执行摘要中只有1条nmap命令针对192.168.61.135)。判断依据:题目要求"明确terminal回复的nmap扫描ip命令才算",以 bot terminal 执行摘要中实际执行的命令为准。
Q10 — 该应用总共调用了几个暴力破解工具?
答案:2
答案状态:已验证
验证等级:L2
解题思路:
从 Discord kv-storage messages0 rowid=106 提取 bot 终端执行摘要,对所有工具进行分类。识别暴力破解工具(广义定义:密码暴力破解 + 目录暴力枚举)。
关键证据:
- FINDING-Q10-002 + FINDING-Q10-003:
- rowid=106 bot 执行摘要中调用的工具分类:
- hydra (2次调用):
hydra -l admin -P /usr/share/wordlist...+hydra -L /usr/share/wordlists/common-...→ ✅ 密码暴力破解 - gobuster dir:
gobuster dir -u http://192.168.61.135...→ ✅ 目录暴力枚举(通过字典逐一试探URL路径,广义上属于 brute-force) - nmap → 端口扫描(信息收集)
- sqlmap → SQL注入(注入工具)
- nikto → Web漏洞扫描
- searchsploit → 漏洞利用搜索
- msfconsole → Metasploit漏洞利用框架
- hydra (2次调用):
- 暴力破解工具 = hydra + gobuster = 2个
- rowid=106 bot 执行摘要中调用的工具分类:
重点命令:
python3 -c "
import sqlite3, json
conn = sqlite3.connect('/mnt/i/data/com.discord/files/kv-storage/@account.1457974771206852664/a')
rows = conn.execute('SELECT rowid, * FROM messages0').fetchall()
for row in rows:
raw_json = row[7]
json_str = raw_json.decode('utf-8', errors='replace').lstrip('\x08\x07\x00')
msg_data = json.loads(json_str)
content = msg_data.get('message', msg_data).get('content', '')
if 'terminal' in content.lower():
print(content)
# 输出: bot执行摘要,包含hydra(2次)+gobuster dir等工具列表
"
踩坑与修正:
- ERR-Q10-001:第一次答案为 1(仅 hydra)。修正为 2(hydra + gobuster)。判断依据:gobuster dir 通过字典逐一试探 URL 路径,广义上属于暴力破解(brute-force)范畴。题目问"暴力破解工具"而非"密码暴力破解工具",应取广义定义。
Q11 — 黄志远使用其内部通联工具进行沟通,其账号的登陆密码是多少?
答案:08164085
答案状态:已验证
验证等级:L2
解题思路:
多阶段取证任务,涉及 APK 逆向 → SQLCipher 解密 → 密码哈希爆破。
阶段1 — APK逆向 (SQLCipher密码构造):
从内部通联工具 com.socialchat.social_chat_app 的 libapp.so 提取关键字符串:
Pgs-dbw(密码前缀)+_getCurrentMicros(时间戳生成)+Good(密码后缀)→ 完整数据库密码格式: Pgs-dbw + <micros_timestamp> + Good_normalizeOrSubstring+_substringUnchecked→ substring(2, length-1) 截取规则SqfliteSqlCipherDatabaseFactoryImpl+PBKDF2KeyDerivator→ Flutter SQLCipher 插件
阶段2 — APK逆向 (登录密码加密):
hashPassword+generateSalt+CryptoUtils+SHA256Digest→ 双重 SHA256 算法: SHA256(SHA256(password+salt).hexdigest())- 表结构:
password_hash TEXT NOT NULL,password_salt TEXT NOT NULL
阶段3 — shared_prefs数据:
- flutter.db_password = Pgs-dbw1776839203359Good(前缀 Pgs-dbw + 时间戳 1776839203359 + 后缀 Good)
- flutter.username = huangzhiyuan, flutter.user_id = usr_heiked
阶段4 — substring(2, len-1)截取验证:
- 完整密码 ‘Pgs-dbw1776839203359Good’ (len=24) → substring(2,23) = ‘s-dbw1776839203359Goo’ (len=21)
- 去掉前2字符 ‘Pg’ + 最后1字符 ‘d’
- PRAGMA key = ‘s-dbw1776839203359Goo’ → SQLCipher 解密成功,获取 7 个表
阶段5 — 数据库user表:
- huangzhiyuan: password_hash=fc29eb768c139c05c0bfcb697d9b26d194878a66451b3ab91b202e9710874a63
- password_salt=a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w
阶段6 — 双重SHA256爆破:
- 24进程并行爆破8位纯数字(00000000-99999999)
- 爆破结果: 密码
08164085- 内层: SHA256(‘08164085’ + ‘a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w’) =
1faa720d8f7a7effecffe20a4032a8c1ca9659d099127aa1f991d914840f4912 - 外层: SHA256(inner_hex_string) =
fc29eb768c139c05c0bfcb697d9b26d194878a66451b3ab91b202e9710874a63✓ 与数据库哈希完全匹配
- 内层: SHA256(‘08164085’ + ‘a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w’) =
重点命令:
# 阶段1-2: APK逆向提取关键字符串
strings /tmp/socialchat_analysis/lib/arm64-v8a/libapp.so | grep -i "Pgs-\|db_password\|sqlcipher\|PRAGMA\|substring\|social_chat\|encrypt"
# 输出: Pgs-dbw, _getCurrentMicros@0150898, Good, _normalizeOrSubstring@0150898, _substringUnchecked@0150898,
# SqfliteSqlCipherDatabaseFactoryImpl, hashPassword, password_hash TEXT NOT NULL, password_salt TEXT NOT NULL
# 阶段3: 读取shared_prefs
cat /mnt/i/data/com.socialchat.social_chat_app/shared_prefs/FlutterSharedPreferences.xml
# 输出: flutter.username=huangzhiyuan, flutter.user_id=usr_heiked, flutter.db_password=Pgs-dbw1776839203359Good
# 阶段4-5: SQLCipher解密
python3 -c "
import sqlcipher3 as sqlite3
full_pwd = 'Pgs-dbw1776839203359Good'
sub_pwd = full_pwd[2:-1] # s-dbw1776839203359Goo (len=21)
conn = sqlite3.connect('/mnt/i/data/com.socialchat.social_chat_app/databases/social_chat.db')
cursor = conn.cursor()
cursor.execute(f\"PRAGMA key = '{sub_pwd}'\")
tables = cursor.execute('SELECT name FROM sqlite_master WHERE type=\"table\"').fetchall()
print(tables) # 7个表: user, friendship, conversation, conversation_member, message, message_file, android_metadata
user = cursor.execute(\"SELECT * FROM user WHERE id='usr_heiked'\").fetchone()
print(user) # password_hash=fc29eb76..., password_salt=a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w
"
# 阶段6: Python多进程爆破 + hashlib验证
python3 -c "
import hashlib
salt = 'a3f8d9c2e1b4h7g6k9m2n5p8q1r4t7w'
pwd = '08164085'
inner = hashlib.sha256((pwd + salt).encode()).hexdigest()
outer = hashlib.sha256(inner.encode()).hexdigest()
print(f'inner={inner}')
print(f'outer={outer}')
# outer = fc29eb768c139c05c0bfcb697d9b26d194878a66451b3ab91b202e9710874a63 ✓ 匹配
"
踩坑与修正:
- ERR-Q11-001:直接用完整密码 Pgs-dbw1776839203359Good 作为 SQLCipher PRAGMA key 解密失败。原因:shared_prefs 中的是完整密码(24字符),但实际 SQLCipher key 需要 substring(2, len-1) 截取为 s-dbw1776839203359Goo(21字符)。从 APK libapp.so strings 确认 _normalizeOrSubstring + _substringUnchecked 截取逻辑后解密成功。
- 陷阱:password.json 中的 AES key ≠ db_password(两者独立);系统 sqlcipher CLI 版本不兼容 → 用 Python sqlcipher3 库。
Q12 — 黄志远一共发送过几个文件给代号军师的嫌疑人?
答案:2
答案状态:已验证
验证等级:L2
解题思路:
使用 SQLCipher 解密 social_chat.db 后,查询 conversation 表找到军师对话,然后 JOIN message_file 表和 message 表筛选 sender_id=usr_heiked 且 type=‘file’ 的记录。
关键证据:
- FINDING-Q12-001:
- conversation 表确认军师对话: conv_d_usr_heiked_usr_junshi_1776759221637 (name=‘军师’, type='D’单聊)
- message_file 表 JOIN message 表查询该对话中 sender_id=usr_heiked 的文件记录:
- att_msg_000167: 木马.zip (application/zip, 5242880 bytes = 5MB), msg_id=msg_000167, time=1704393630000
- att_msg_000181: 木马_v1.2.zip (application/zip, 5505024 bytes = 5.5MB), msg_id=msg_000181, time=1705286430000
- 该对话共 26 条消息,其中 type=file 的消息只有 2 条,均为 usr_heiked 发送
重点命令:
python3 -c "
import sqlcipher3 as sqlite3
conn = sqlite3.connect('/mnt/i/data/com.socialchat.social_chat_app/databases/social_chat.db')
cursor = conn.cursor()
cursor.execute(\"PRAGMA key = 's-dbw1776839203359Goo'\")
# 找到军师对话
conv = cursor.execute(\"SELECT * FROM conversation WHERE name='军师'\").fetchone()
print(conv) # conv_d_usr_heiked_usr_junshi_1776759221637
# JOIN查询文件消息
files = cursor.execute('''
SELECT mf.* FROM message_file mf
JOIN message m ON mf.msg_id = m.id
WHERE m.conversation_id = 'conv_d_usr_heiked_usr_junshi_1776759221637'
AND m.sender_id = 'usr_heiked'
AND m.type = 'file'
''').fetchall()
for f in files:
print(f)
# 输出: 2条记录 - 木马.zip (5MB) 和 木马_v1.2.zip (5.5MB)
"
Q13 — 方俊朗手机总共安装了多少款理财应用?
答案:4
答案状态:已验证
验证等级:L1
解题思路:
从方俊朗检材 partition2 (/mnt/k/app/) 列出所有已安装应用,使用 aapt dump badging 提取 label,识别理财类应用。排除 com.example.predictor(优质客户预测 = 业务工具/Q14目标)和 com.jingdong.app.mall(京东购物 = 电商)。
关键证据:
- FINDING-Q13-001:确认4款理财应用
- com.eastmoney.android.berlin → 东方财富(股票/证券理财平台)
- com.jd.jrapp → 京东金融(综合金融理财平台)
- com.okinc.okex.gp → OKX/欧易(加密货币交易平台)
- com.jujing.ncm → 股参谋(股票分析理财工具)
- 排除:com.example.predictor(优质客户预测 = 业务工具/Q14目标应用,非理财应用);com.jingdong.app.mall(京东购物 = 电商平台,非理财)
重点命令:
aapt dump badging /mnt/k/app/com.eastmoney.android.berlin-*/base.apk | grep "label:"
# 输出: application-label:'东方财富'
aapt dump badging /mnt/k/app/com.jd.jrapp-*/base.apk | grep "label:"
# 输出: application-label:'京东金融'
ls /mnt/k/app/ | grep -E "okex|ncm"
# 包名确认: com.okinc.okex.gp (OKX/欧易), com.jujing.ncm (股参谋)
Q14 — 方俊朗使用筛选优质客户的应用包名是什么?
答案:com.example.predictor
答案状态:已验证
验证等级:L1
解题思路:
从 /mnt/k/app/ 发现 com.example.predictor,使用 aapt dump badging 确认 label=‘优质客户预测’,即筛选优质客户的应用。应用有加密数据库 chat_history.db (SQLCipher/PBKDF2),shared_prefs 中有 key_version=PBKDF2_v1, key_iterations=10000, db_integrity_check 字段。
关键证据:
- FINDING-Q14-001:aapt dump badging 确认 package name=‘com.example.predictor’, label=‘优质客户预测’, versionName=‘1.0’
重点命令:
aapt dump badging /mnt/k/app/com.example.predictor-*/base.apk | grep -E "^package:|^application-label:"
# 输出:
# package name='com.example.predictor'
# application-label:'优质客户预测'
# versionName='1.0'
未完成或不可提交题目
| 题号 | 当前答案 | 答案状态 | 原因 | 下一步 |
|---|---|---|---|---|
| (无) | — | — | 全部14题已完成并验证通过 | — |
附录
错误尝试总结
| 题号 | 原答案 | 修正后答案 | 原因 |
|---|---|---|---|
| Q5 | Discord | discord | 未按格式示例 wechat(全小写)归一化 |
| Q7 | test901234. | test901234 | 取了 username(唯一标识带点号),应取 globalName(频道显示昵称) |
| Q8 | HNZ6UFW6 | 3EXEQ5R8 | HTTP cache 只缓存了第一次未成功的配对尝试,kv-storage 确认最终生效的配对码 |
| Q9 | 3 | 1 | 混淆了"用户请求的IP数量"和"bot实际执行的nmap扫描IP数量" |
| Q10 | 1 | 2 | 狭义定义暴力破解只计算 hydra,广义定义应包含 gobuster dir(目录暴力枚举) |
| Q11 | 解密失败 | 08164085 | 完整密码需 substring(2,len-1) 截取后才能作为 SQLCipher PRAGMA key |
关键经验
- Discord kv-storage messages0 数据库:所有列都是 bytes 类型,JSON 数据在 col[7](索引7),前面有 \x08 控制字符前缀。使用
row[7].decode('utf-8', errors='replace').lstrip('\x08\x07\x00')解析。 - Flutter SQLCipher 动态密码:shared_prefs 中的完整密码需 substring(2, len-1) 截取后才能作为 PRAGMA key。系统 sqlcipher CLI 版本可能不兼容,优先使用 Python sqlcipher3 库。
- Bot 执行摘要 vs 用户请求:当题目问"应用对几个IP进行扫描/调用"时,以 bot terminal 执行摘要中实际执行的命令为准,而非用户消息中请求的数量。
- 答案格式归一化:应用名称按格式示例大小写归一化(wechat → 全小写),版本号按格式裁剪(111.1 → 主版本.次版本)。