Pwnable.tw silver_bullet
好久之前做过一次,当时不怎么会调,栈构造的乱七八糟的,现在再来做感觉还是有点东西的😂
这题大概流程就是先create_bullet,再增加power,最后去挑战boss(HP=0x7f000000),成功就退出了,啊这
程序的漏洞点在power_up:
1 | int __cdecl power_up(char *dest) |
strncat函数在执行完拼接后会在末尾加上一个\0,如果我们先创造47个bullet然后再powe_up一个,那在strncat的时候就会在s+0x30的位置写入一个字节的\0,导致之前存放在这里的size数据被覆盖为0,然后再之后的strlen(&s) + *((_DWORD *)dest + 12)计算的结果就是1了。
从而我们有了继续向下拼接的机会,在之后的拼接会在s+0x30开始我们可以先伪造size大于0x7fffffff,然后就到了ebp的位置,伪造ebp为bss地址,返回地址用puts_plt覆盖,接下来写进去pop_ebx——ret作为puts的返回地址来清理栈并接着ret,之后写puts函数的参数为puts_got,然后写入input_read的地址,使得在pop_ebx_ret时去执行read_inputs,接下来设置read的参数为上面的bss的段和输入的size(够用就行),之后返回地址写成leave_ret使得两次leave把栈迁移到bss去执行我们input_read输入的system。
拼接的效果如下:
1 | 15:0054│ eax 0xffddc584 ◂— 0x61616161 ('aaaa') |
之后执行beats获胜,main函数将执行返回
1 | EAX 0x0 |
先执行puts(puts_got)
leak后返回到pop_rbx_ret清理stack并跳到read_input
1 | EAX 0x5 |
完成向0x804b410输入payload后进行栈迁移:
1 | EAX 0x17 |
leave_ret两次完成栈迁移,执行payload!!🚩
EXP:
1 | from pwn import * |
这题漏洞在于数据布局不规范以及strncat函数的结尾添加\0的操作🕵️♀️