week4-ret2csu2
New-star-Week4-Ret2csu2
拿到题目,我们先checksec一下:
那就可能是栈溢出了,我们看了看源码:
这个题目,我是不会的,也是去学习了别的师傅的wp,才会的,前两个函数没啥说的,普通的向屏幕输出语句,第三个函数是存在溢出的,但是溢出的字节数是不够的,那就要考虑栈迁移了,栈迁移首先是考虑迁移到bss段的,但是栈迁移也存在问题,我们只能读入一次,读入的字节太有限了,所以我们要想办法多读入一次,其实是很简单的,但是我愣是没想到,就是跳到lea rsi,[rbp-0xf0]这里,因为最后执行的是read函数,很多寄存器的值都没改变,我们可以下断点(main函数的快结尾)去看看:
可以看到,rax还是等于0,那么系统调用就是read函数,rdi是0,第一个参数正确,rdx是0x100,第三个参数也是正确的,第二个参数也是可以控制的,我们第一次ret跳到这里就可以了:
这样跳转过去,就可以再次执行read函数了,那么第二个参数地址写成0x601020 就可以了,这里IDA给反汇编好像不对,题目给了c程序,看题目即可,0x601020是bss段的起始地址,如何控制第二个参数?只需要溢出覆盖旧的rbp为0x601020 + 0xf0,这样第二个参数rsi就是0x601020了:
接下来就是ret2csu了,payload如下:
1 | from pwn import * |
read函数,二次读入后,rbp为0x601020 + 0xf0,返回到main函数结束位置,执行leave指令,rsp =0x601020 + 0xf0,然后rbp = 0x601020-0x8,然后retn到我们布置的leave ret这里,leave后,rsp =0x601020,此时再次ret,就到了 p64(gadget1)的地方,执行retcsu,里面调用 mprotect函数改写权限,返回后顺势执行到最后一个retn指令,指向p64(0x601020+0x40+0x38+0x8),去执行shellcode,b”A”*(0xf0-0x40-0x38-0x8-0x30)是为了填充数据大小到0xf0,填满read函数的区域。所以用send发送,sendline会多换行符,发送回失败。