guess_num
来自 xctf 的题目
附件是一个猜数字的程序,只要猜错就会“GG”。
通过 file 查看该文件是 64 位 elf 文件,checksec 发现有堆栈金丝雀保护。
简单分析程序后直接上 ida pro 进行反汇编:
这里使用 srand() 和 rand() 获得伪随机数,如果成功获得就进入 sub_C3E() 里面有 system 函数获得 flag。
对此,我们需要得到种子,这里 seed[0] 存储种子,但是又发现种子是靠 sub_BB0() 函数获得的,而 sub_BB0() 靠 /dev/urandom 获得随机数,基本上就是说种子是随机的,那么随机数也大抵是很随机的……
不过呢,前面输入名字获得字符串使用的是 gets(),给了我们溢出覆盖空间的可能。
点击 v7 看看函数栈里面的布局,发现:
v7(var_30) 往下就是 seed 的空间,它们之间只差了 0x20 字节。显然我们可以通过 gets() 的漏洞改写 seed 内的数据。
改写了 seed 的数据就相当于我们可以自己定义种子,那么随机数也就能够知道了。
由此可以写 python 脚本开始 pwn!
|
|
这里使用 ctypes 来 python 内运行 srand 和 rand 函数。
|
|
使用 libc 运行库,然后运行 srand(0) 种子。后面我们就是要将 seed 种子改写成 0。
|
|
攻击载荷显而易见,0x20 个 a 溢出,然后改写为 0。
这个载荷在输出 “Your name:” 之后注入。
最后是循环 10 次写入对应随机数,随机数计算如下
|
|
用 .encode() 方法把 str 转换为 byte 类型。
10 次结束都正确就进入 sub_C3E() 函数然后获得 flag ,pwn 成功。
