栈迁移之任意地址写(pwn入门)

先来谈谈栈迁移的攻击手法

很多时候,程序给的溢出空间不够,仅仅只能溢出到rbp,或者是返回地址,这个时候去构造rop链条打程序就行不通了,没有多余的空间给你去构造rop链条,那么我们可以使用栈迁移的技术,先在一个位置布置好rop链条,然后把程序的执行流迁移到我们布置好rop链条的位置,让程序执行流执行踏入我们布置好了的地方,就相当于之前的那种构造rop链条的手段,但是多了一个迁移栈步骤,这个下一篇博客会细讲

现在就是讲下最基础的利用栈迁移实现任意地址写,也就是可以改写变量的值

这里的关键一就是rbp指令,局部变量是根据rbp寻址的

这里的关键二就是leave_ret指令

leave指令的本质其实就是:

mov esp,ebp

pop ebp

ret指令的本质其实就是:

pop eip

下面我们就可以利用上面分析的原理解出这道题目

例题

可以看到,这里不存在栈溢出,不存在栈溢出的题目大概率就是用栈迁移去打

这里允许读入的数据只有0x58,而buf变量的大小有0x50,64位的程序,所以只能刚刚好溢出到rbp的地方,连返回地址的空间都没办法溢出到

可以看到当v4和passwd的值都为4660也就是0x1234的时候就可以直接拿到shell了

那么具体怎么判断的呢?我继续给出汇编代码的分析,让我们对汇编代码理解更加深刻一些

第一步,cs:passwd,也就是把passwd这个空间的值取出来,然后mov eax,cs:passwd,也就是把这个取出来的值赋值给eax

第二步,cmp eax,1234h  这里的h代表这是一个16进制的数,这里就是说把eax里面的值和16进制0x1234进行判断,如果相同的话就跳到下面的call system直接提权拿shell,不过不成功的话就跳到short loc_4012DB里面去,jnz就是指cmp判断后不等于跳转的位置

然后第三步,就是把rbp+var_4也就是rbp-4的位置赋值给eax里面,其实也就是啊,闭环了,我们输入的数据的位置,然后的步骤和上面的一样的

 

所以我们在打程序的时候就是需要通过这个栈迁移来实现对passwd这一个全局变量的内容进行更改,改成我们输入的0x1234,同时x的值本来就是我们输入的值,也就是rbp-4的值是0x1234,就可以把程序打下来了

首先我们需要找到passwd的地址,双击一下跟进,可以看到所在地址是0x4033cc

第二步我们需要确认一下调用scanf的时候它读取的偏移是多少,这需要根据汇编代码来看

可以看到偏移是减4,上面仔细分析过,所以偏移就是4,所以就把rbp迁移到passwd_addr + 0x4的位置,那么我们输入的数据依据rbp寻址后就是在减去0x4的位置也就是passwd的位置,也就完成了任意地址写,改写了passwd的值

 知道了这些就可以构造脚本了

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')
p = process("./test1")
elf = ELF("./test1")

passwd_addr = 0x04033cc + 0x4

payload = b'a'*0x50 + p64(passwd_addr)
p.recvuntil("input2:")
p.send(payload)
p.recvuntil("input1:")
p.sendline(b"4660")
p.interactive()

  • 33
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值