有一段时间没有练习了,前一段时间一直在准备御网杯的应急响应,虽然到最后也没拿出来什么好结果吧,朋友给了一道练习题写写,看看自己退化了没有
练后:
篡改函数走 system 的还是比较常见的,2.27 算是低版本了,大概一个多月没怎么手开过 pwn 了,也算是回复一下手感,题目还算是比较基础的,之后还有好多东西要学呢 emmmmm

IDA 静态分析:
main

main 函数没什么看点,简单修一下函数名
add

要求大小只是小于 0x78。
emmm,那这样的话思路就很固定了啊,没有 FULL RELEO,2.27 的 libc,并且是小于 0x78 的堆
那么大概率就是篡改指针,走一个 got 表篡改了
delete


跟进一下 dword,发现值为 1,正好不用动调了,也就是说只能 free 一次

edit

这里只检查输入的 length,敏锐察觉到这里获取可以直接堆溢出,随便整两个小堆,再 edit 个大堆进行堆溢出
show

直接打印出内容
EXP 思路:
思路算是比较明了了,先做堆重叠,然后可以把 atoi 函数溢出覆盖到下一个堆的内容,用 show 打印出来
之后确定 libc.address,再用 edit 对 atoi 函数进行篡改,然后再调用 show 中的 atoi(“/bin/sh”)即可,实际的 atoi 已经被篡改成 system 了,直接 system(“/bin/sh”);
1 | add(0, 0x18) |
先进行堆溢出
这里有个小插曲,一开始没注意这个 \n,直接 recv 了,发现不对结果不对劲,然后尝试接收看一下内容
1 | add(0, 0x18) |

发现被分隔符 \n 截断了,那就 p.recvuntil(“/n”),之后动调检查一下,没有问题:

得到 libc.address 之后就可以直接进行 edit 篡改了,后面就没什么问题了:
总 EXP:
1 | from pwn import * |
说些什么吧!