首页
社区
课程
招聘
1
[原创]通过angr另类求解一道CISCN题目
发表于: 2025-3-14 02:36 4366

[原创]通过angr另类求解一道CISCN题目

2025-3-14 02:36
4366

这次又是写一道存货
CISCN 2022 secreeeeet

该题的精髓在于对5字节密钥的爆破
而爆破又需要我们复现其算法

以这篇随笔记录一个利用约束求解“偷懒”的办法

看附件显然是对 PNG 进行加解密

造一个假 PNG 给它加密
可以发现对同一个文件而言
每次加密结果都不一样

在 main 函数输入的地方调试
这是和一个长度为 3 的 key 进行循环 XOR

在 main 函数输出的地方调试
这是和一个 box 做流加密
步长 16 字节
每次步进都对 box 做一次混淆

追溯 box 的来源可以在 main 函数开头看到
box 的种子长度为 5
并且通过 debug 可以知道
这两个数字都属于 0-9 不过 box 种子对一个码表取了下标
码表是 qscfthnjik
如果数字为 12345
则种子为 scfth

两个数字均来源于时间
因此必须爆破
考虑到对 PNG 头进行 OTP 时使用的密钥在一个很小的范围内
可以利用这一点进行爆破

我的规则:

爆破时需要顺着逆向出 box 的生成算法

box 的生成算法并不是很”密码学”
然而它却很长很繁琐

考虑到 box 的生成过程中没有任何外界干扰
可以借助 angr 偷个大懒

众所周知 angr 提供了 FFI (Foreign Function Interface) 功能
将相同的思路运用在任意代码上:
对一连串基本块模拟执行可以得到两个相关联的 BitVec
一个是这串基本块的输入(可视为已知 因为要爆破)一个是输出
其之间的约束等效于加密算法

图片描述

这个流程只需调用一次取得 2 个 BitVec 即可
暂且叫这两个 BitVec 为“模型

在其他地方可以随意调用这个模型而且,
根本不需要知道算法具体是什么(一般来讲都不可名状)

不过这样做的难点是:
angr 对 windows 平台的支持不太完备
为了稳定且快速的运行,我们需要手动设置上下文(包括栈)

以 box 的生成为例

其中
长度为 5 的种子地址位于 r12
rbp 和 rsp 之间的差值是 0x100
box 最终的长度是 17 个 uint
位于 rsp + 0x420

下面是调用模型的示例
这里通过获得的模型 _box 伪造了 box 的生成函数
_box[0] 是 box 的 5 字节输入
_box[1] 是 box 的 68 字节输出

本质上就是调用 claripy 的 eval 功能

为了爆破还需获得 mix 的模型
它的要求很简单
rcx 中存储 68 字节的 box 数据即可
原理同上

上述做法还有一个缺点:相比原生算法可能会更慢
借助 pwnlib 的 mbruteforce 是一个好办法

然而在 Windows 环境中使用 multiprocessing 会有一些小小的问题
可以用 pickle 把 box 和 mix 的模型存到硬盘
在硬件条件更好的 Linux 服务器中导入

这也是该做法的一个优势:可持久化,无需次次符号执行

接下来应用上述爆破规则从码表 qscfthnjik 中选取 5 个
如果 mbruteforce 的进度条失效
可以使用 tqdm 和分段功能手搓一个进度条

在我的机器上大约 20 分钟后得出结果
种子为 iqsqn
三位数为 002

通过最后一步的流加密复原 PNG 得到 flag

图片描述
flag{2ed562e6-36fc-435e-9d97-2738d3774954}

25年3月13日于清水湾

do
{
  v114 = 0i64;
  if ( v112 < 3 )
    v114 = v112;
  *v113 ^= key3[v114];
  v112 = v114 + 1;
  ++v113;
  --v111;
}
while ( v111 );                             // OTP key3
do
{
  v114 = 0i64;
  if ( v112 < 3 )
    v114 = v112;
  *v113 ^= key3[v114];
  v112 = v114 + 1;
  ++v113;
  --v111;
}
while ( v111 );                             // OTP key3
do
{
  mix(box2);
  v125 = box2[3];
  v126 = box2[5];
  *(data - 2) ^= box2[0] ^ HIWORD(box2[5]) ^ (box2[3] << 16);
  v127 = box2[7];
  *(data - 1) ^= box2[2] ^ (v126 << 16) ^ HIWORD(box2[7]);
  v128 = box2[1];
  *data ^= box2[4] ^ (v127 << 16) ^ HIWORD(box2[1]);
  data[1] ^= box2[6] ^ HIWORD(v125) ^ (v128 << 16);
  data += 4;
  v124 += 16;
}
while ( v124 < (unsigned __int64)v133 );
do
{
  mix(box2);
  v125 = box2[3];
  v126 = box2[5];
  *(data - 2) ^= box2[0] ^ HIWORD(box2[5]) ^ (box2[3] << 16);
  v127 = box2[7];
  *(data - 1) ^= box2[2] ^ (v126 << 16) ^ HIWORD(box2[7]);
  v128 = box2[1];
  *data ^= box2[4] ^ (v127 << 16) ^ HIWORD(box2[1]);
  data[1] ^= box2[6] ^ HIWORD(v125) ^ (v128 << 16);

[注意]看雪招聘,专注安全领域的专业人才平台!

最后于 2025-3-22 23:23 被狗敦子编辑 ,原因: 添加图片
上传的附件:
收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
wx_Dispa1r
+5
感谢你分享这么好的资源!
2025-3-16 13:03
最新回复 (2)
雪    币: 1835
活跃值: (1856)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
感谢分享,可以分享下完整的 angr 代码吗
2025-3-16 13:02
0
雪    币: 1832
活跃值: (1065)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
wx_Dispa1r 感谢分享,可以分享下完整的 angr 代码吗
已上传附件
2025-3-16 21:21
1
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册