0x01
- 拿一道CTF题目为例,主函数如下
- 这是一个关于矩阵的题目。
思路很清晰,函数名称也直接表达出来函数作用了。 但是求解是现在的难题了。
如果考虑正向爆破… 难度太大太大,太费时间了, 毕竟有27个未知数呢。
为什么是27而不是36? 因为根据
1 | gets(flag); |
需要让v4 = 9,那么也就需要 !flag[i]满足9次,而flag的大小是36, 即 只输入27个数就能满足题意。
现在需要提取出来题目给的矩阵(即题中的d)
1 | d = [0x12027,0x0F296,0x0BF0E,0x0D84C,0x91D8,0x297, |
- 网上找到一脚本:
1 | #coding:utf-8 |
鉴于有27个未知数,正如求解27元方程组一般,如果知道的关系越多,那么求解起来越容易, 求解所用时间也就越少。
我把 “#添加约束,由于flag有格式,前6位一定为whctf{ “这个条件约束去掉以后再去跑的话 跑了74秒,而按照上面脚本跑的话,只需要3.2秒。
不难看出z3求解的约束条件就是把题中给的关系进行还原,然后让约束求解器进行求解,我们所须要做的工作就是把条件列出来。
顺带说一下 s.append(m[flag[i]].as_long()) 中的as_long()的大致作用。
如果去掉这个.as_long(),而只保留m[flag[i]]
则下面for i in s: 中的i的类型是instance类型,从而导致 flag+=chr(i)中的chr()方法无法正常使用(因为chr()里面需要传入int型的数据。)
所以这个as_long()的功能大概就是把数据转为int类型吧。
0x02
- 拿一道22元方程组求解的数学题目为例,直接上脚本了。
1 | #coding:utf-8 |