2026-御网杯-逆向-chacha20

2026-御网杯-逆向-chacha20 前言这个题目比赛的时候是AI一把梭的。这个比赛有三题比赛时候没做出来。当时感觉题目缺材料还有就是服务器有待提高的感觉好几次连上就断。一整个AI大战现在感觉现在入门的速度应该没有AI成长的快。但是但是如果是HVV安全演练这样的行动我认为实力加AI是必不可少的。CTF比赛包括AWD和AWDP等其实AI是作为一个加法进行的。但是HVV安全演练这样的行动AI是作为乘法的个人能力现在还是比较重要的个人啥都不会的话就算有AI也难打出成绩。这里笔者挑选一些质量高的题目进行复现。整体比赛下来抛去AI不谈抛去服务器不谈题目质量很可以但是这两个都抛不去。有的题目在公众号上比如rerere那题有的在博客上。我的公众号读者随缘遇见吧。这次前言有点多了。题目ChaCha20 是一种流密码Stream Cipher由丹尼尔·伯恩斯坦Daniel J. Bernstein于2008年设计。它是 Salsa20 密码的改进版本旨在提供更高的安全性和性能特别是在软件实现中。解包。这里APK一般都可以改后缀解压的。因为是软件类型的压缩包解压会慢一些。APK 内有 native 库。就是所谓的原生库。打开这个so文件。一般我们说 native 库是在 lib 文件下也就是应用下的静态库或者导入库。这个apk里面就这一个文件正常是lib/ ├─ armeabi-v7a/ ├─ arm64-v8a/ ├─ x86/ └─ x86_64/这样比较合理。用IDA打开这个so文件。.soShared Object是 Linux、Android 等类 Unix 系统中的共享库/动态库文件全称 Shared Object。这是一个安卓APK用JEB或许会好做一些。不过我们就正常使用IDA就行。查看 JNI 注册JNI 注册是 Java 通过 Java Native Interface (JNI) 调用 C/C 代码时将 Java 中声明的 native 方法与 Native 库.dll/.so中的具体 C/C 函数建立关联的过程。这题是动态注册那么在 JNI 库加载时JNI_OnLoad 函数中通过 RegisterNatives API 手动将 Java 方法和 C 函数绑定。这里的eReferenceE是因为Hex-Rays 反编译器识别错误。进入sub_25010。说明JNI_OnLoad ↓ sub_25010 ↓ RegisterNatives这段代码已经确认了FindClass(com/cr/myapplication/NativeBridge)RegisterNatives(a1,v2,off_571B4,3)说明真正关键的信息不在 JNI_OnLoad而是在off_571B4这个 JNI 注册表里。程序通过 RegisterNatives 动态注册了 3 个 native 方法。整理后得到 native 方法映射关系Java 方法 JNI 签名 Native 函数 a([B)[B sub_250B0 b([B)[B sub_251F0 c(Ljava/lang/String;)Z sub_25330其中c()方法接收字符串并返回布尔值因此可以判断sub_25330就是核心 flag 校验函数。这就是flag的校验函数。sub_27530转成 Hex 字符串byte_F315 → Hex 字符表 ‘0123456789abcdef’v3 sub_27820(off_58EF0 1183, i);意思就是密文数据存放在 off_58EF0 1183 开始的数组里每个字节按偏移 12*i 取sub_27700(v8, v3) 再去做比对在data数据段里面可以中找到得到ct等于d097c3f6d203a152c851a9318b93e9e5ef63f34925c6ccdb到这里还差 ChaCha20 KeyNonce。跳转到sub_25740这就是 ChaCha20 或类似流密码生成 keystream 并和输入字节逐块 XOR 的函数。密钥key正好从unk_F2E9开始32 字节硬编码。149263A16F2D89CBF0375B1CA94E78D3226017EE9ABC4D0853E1762A8DC4903Fnonceunk_F309开始12字节。44332211ABCDEF668899AA55脚本fromCrypto.CipherimportChaCha20 keybytes.fromhex(149263a16f2d89cbf0375b1ca94e78d3226017ee9abc4d0853e1762a8dc4903f)noncebytes.fromhex(44332211abcdef668899aa55)ciphertextbytes.fromhex(d097c3f6d203a152c851a9318b93e9e5ef63f34925c6ccdb)cipherChaCha20.new(keykey,noncenonce)plaintextcipher.decrypt(ciphertext)print(plaintext)输出bflag{HNCTF62RDYNTFMZ1TF}