2026数字中国数字安全赛道网络安全团体赛决赛WP
Reverse
- Re手因身体原因未到现场,但因现场题就Re较为简单,其他方向题目比较难,导致团队未能获奖,Re手表示非常抱歉未能到现场。
FlagVault
这题题目说的很明确了,加密在Native层

定位到关键函数
发现整体逻辑较为简单,且有用函数为getFlag
用Bandizip解压apk(这里主要是我没到现场,队员说问ai用apktool解压,但她没有,所以有点小可惜)

定位到getflag
发现加密很简单

SystemMonitor
这道题题目明确说明是个恶意软件
且丢到IDA发现没有明显flag相关函数
可以合理怀疑是把敏感信息换为了flag,然后传到恶意网站或服务器

大概看了下主要函数
这两个很可疑
审阅后可以发现 sub_1400015FE()为关键函数
这个函数行数较多,可以丢给本地ai进行分析,也完全能跑出来流程

然后就可以大胆猜测是把flag传出去了,打个断点动态调试即可

以上两道题就是线下赛解出的Re题了,我也是在模拟离线环境下做出来的,非常可惜,如果拿到这两个题的解最少也是个
铜奖银奖了(悲)
ChatA
这道题题目说了要分析通讯
把apk丢到jadx中发现有好多base64编码
主要是StringFog中的解密
看了一下就是两个base64异或
然后就没什么头绪了

只找到了个flag的关键字
大概率也是要去翻native层

丢给GPT进行分析
加密方式为AES-256-ECB

加个flag头就行了应该
不知道正常解是不是这么解,对于ai是怎么分析出来这块我还是很疑惑怎么分析出来的,奈何现在GPT也被限制了,希望有师傅可以解惑
还是说我是做题经验太少,这是经验问题

后记,2026.06.22
- 继上文分析

- 这里可以看到初始段有两个解密函数
- 肯定是后面要用到的
- 现在看JNI_OnLoad函数
- 发现是ollvm的混淆,完全看不懂在干什么
- 在ai辅助下找到sub_1AA4C80函数(我知道线下赛用不了ai,但我是在复现并学习,我为了绕开更多弯路所必须要做的,没人手把手教我,只有ai,参考wp也找不到)

- 可以看到这里有很多有趣的函数

- 模仿初始化阶段来写解密脚本,解出部分字符串
1 |
|
- 这是模板,小改一下就可以解字符串了
- 可以看出这个assets/index.js很重要,但是打开却发现根本看不懂
- 就可以知道这被加密了
- 继续分析发现sub_1AA3C30函数很关键
- 虽然也是很乱,看不出来是什么东西,但可以发现sub_1AAFEE0函数内有aes字样

- 就可以合理推断出这个js脚本是被aes-256-ecb加密的
- 密钥的话大概率是这四段

- 并且可以发现初始化阶段它们的解密是独立的

- 就可以顺利解出密钥

1 |
|
- 然后解密环节就和之前一样了
Bridge
这是一个鸿蒙系统下的程序
需要用到abc-decompiler工具

找到了Flag的关键函数
第一步就是获取用户的token

在com.hmos.exam5.pkg/entry/ets/model/DatabaseUtil中也给了admin账户和密码
也给了盐,生成token使用了sha256

回到解密,第一步,再次使用sha256

取前32个hex,51a8f50d751a48550f90b3c49439afbe,作为key
下一步是解sm4
返回到com.hmos.exam5.pkg/entry/ets/model/FlagUtil
看了一下调取的函数#*#readLocalFlagCipher就是5a52339fbdb9b11b330ed4ffd6f06b453e0d3fb96a624a71b16124065c2d9e3362fa1d5941b0995e559002b759cf91a9

sm4的相关信息也给了

就可以得出flag了!!!
其实这里面还可以进行sql注入

但没什么鸟用
也可以在解压的文件夹中看到

Dedebug
这道题做的我好痛苦
怎么弄也绕不过这个检测
用了apktool把apk改成了这样子

还是绕不过去
实在没招,问了ai,说初始化段也有反调试

不听GPT,改来改去,改不动了
还是看看GPT给的静态分析吧
GPT应该是分析的x86_64下的so库



- 这是GPT给我的一把梭脚本
1 | from pathlib import Path |
当然,根据这道题的题意肯定是让选手绕过调试解出flag的
用GPT分析了下需要patch的点,但让那个用apktool修改也是需要做得(以x86_64为例)
1 | # ============================================================ |
- Frida脚本
1 | ; |
- 安卓逆向经验欠佳,试了很久也不能出flag,所以用ai来总结
后记,2026.06.23
- 还是先把apk放在jadx中分析

- 很明显,发现有个root检测
- 使用
java -jar .\apktool_3.0.2.jar d -r dedebug.apk -o debugme_src把apk编回smali文件
- 装回后发现依旧有检测,怀疑是native层面的检测
- 看了看native层的checkflag,发现无法直接逆向

- 开始分析反调试检测
- 来到初始化阶段

- 发现只有这一个函数,点开看看
- 审阅后发现是三个kill

- 也就对应三次检测
- 改下jmp就可以了
- 然后继续分析,发现还是有检测,注释一下,然后patch就行了,也就是nop和改一下jmp

- 后面发现sub_EE0,sub_1B60,sub_2170这三个检测函数也调用了kill
- 所以直接让它们三个retn就好
- hook代码还是上面的,怎么写出来的我还得再学习学习
DC
一个core文件
查了一下是Core 文件记录了程序在发生异常那一刻的内存映像、寄存器状态和堆栈信息。
用ai一把梭吧,找不到主函数(前几个题的wp写的有点燃尽了)
0x00 文件识别
拿到题目文件 dc.core,先看一下是什么:
1 | $ file dc.core |
是一个 ELF 64-bit core dump 文件。Core dump 是程序运行时内存的快照,通常包含了程序的代码段、数据段以及当时的栈/堆状态。
strings 能看到一些有意思的东西:
1 | /tmp/ctf_%08x # 写入 /tmp 目录,疑似成功时输出 flag |
用 IDA Pro 打开 core dump,设置基址为 0x55C62414E000。
0x01 定位主逻辑
Core dump 中有很多 libc 函数,真正的程序代码在 0x55C62414F000 附近。从 survey_binary 可以看到几个关键函数都在这个区域。
函数清单
| 地址 | 功能 |
|---|---|
0x55C62414F2C9 |
XOR 循环 |
0x55C62414F31A |
初始化函数(解密数据) |
0x55C62414F370 |
RC4 KSA(密钥调度) |
0x55C62414F45C |
RC4 加/解密 |
0x55C62414F5F8 |
自定义 Base64 编码 |
0x55C62414F86C |
主验证逻辑 |
0x55C62414F786 |
成功回调(写 flag 到 /tmp) |
0x02 初始化函数 — XOR 解密
首先吸引注意的是 sub_55C62414F31A,它调用了三次同一个 XOR 函数:
1 | __int64 sub_55C62414F31A() |
sub_55C62414F2C9 的逻辑非常简单:
1 | for (i = 0; i < size; ++i) |
这说明程序在编译时将关键数据 XOR 加密存储,运行时通过 init 函数解密。三块数据的 XOR 密钥各不相同:
0x55C624152040(64 字节)← XOR 0x42
0x55C6241520A0(53 字节)← XOR 0x24
0x55C624152020(14 字节)← XOR 0x56
从 core dump 中读取这三段加密数据,用对应密钥 XOR 解密:
1 | # 字母表 (64 bytes) |
RC4 密钥 C0nFu5i0n_K3y!(Confusion_Key 的 leet 写法)明显是人造的,确认解密方向正确。
0x03 主验证逻辑
sub_55C62414F86C 是核心验证函数:
1 | void sub_55C62414F86C() |
程序流程:用户输入 → RC4 加密 → 自定义 Base64 编码 → 与期望密文比较。
所以逆向求 flag 的路径:期望密文 → 自定义 Base64 解码 → RC4 解密 → Flag。
0x04 修改版 RC4
KSA(密钥调度)
仔细对比标准 RC4,该程序的 KSA 有改动:
1 | // 标准 RC4 KSA: |
PRGA(伪随机生成)
同样被修改了:
1 | // 标准 RC4 PRGA: |
两个关键改动:
KSA 中
j = j + S[i] + i + key[...](多了+ i)PRGA 中
k = (S[i] + S[j]) ^ pos(用输出位置 XOR 替代 S-box 索引)
0x05 自定义 Base64
sub_55C62414F5F8 实现了一个带位置相关偏移的 Base64 变体:
1 | v7 = 0; // 全局输出位置计数器 |
与标准 Base64 的区别:
字母表是乱序的(64 个自定义字符而非标准
A-Za-z0-9+/)**每个位置的编码索引加了偏移量 ****
(pos % 7) + 3**
解码时需要逆向这个偏移:
1 | for pos, char in enumerate(encoded): |
0x06 解密脚本
1 | # 从 core dump 读取的加密数据 |
0x07 总结
本题是一个典型的 CTF 逆向题,考察点包括:
Core dump 分析 — 识别 core dump 文件并加载到 IDA 分析
XOR 加密数据识别 — 通过 init 函数发现静态数据在编译时被 XOR 加密
魔改 RC4 识别 — 对比标准 RC4 发现 KSA 多了
+i和 PRGA 的^pos改动自定义 Base64 — 位置相关的偏移量
(pos % 7) + 3+ 乱序字母表
最终 Flag:
1 | flag{Tw34k3d_RC4_n_B64_m4k3_1t_h4rd!!!} |
第七题题目和附件全部丢失,如果有师傅有附件并愿意给我的话,请联系我,感谢
关于本文
由 GuQing 撰写,采用 CC BY-NC 4.0 许可协议。