CTF刷题记录--format2(整数溢出)

文章讲述了作者在一次CTF挑战中遇到的题目,涉及栈溢出、整数溢出和printf函数的利用,通过查找auth函数中的攻击点,利用memcpy的特性进行整数溢出攻击,最终通过覆盖栈帧实现系统调用的执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

###上周做了两个题,结果笨人去准备csp认证去了,准备了一周结果还是考了一坨,麻了,发现可能还是不适合打算法呜呜(羡慕算法大佬),笨人还是乖乖搞CTF手艺活了(两道题的题解回头有时间发,这次先做个难度5的复健去)

format2初试:

https://adworld.xctf.org.cn/challenges/list

题目链接放在上面了,还是攻防世界的(BUUCTF难度好大,下次一定)

DIE结果我就不放图了,结果是32位linux上面的,没有壳。

但是checksec出现了canary found,这就比较有意思了,我也是第一次做这个题目。

查了下资料发现,其实是在我们ebp低四位的位置上插入了一组随机数,导致如果我们还是按照以前栈溢出攻击的时候,就算我们填满它了(污),如果这段随机数不匹配的话,程序自己会停止运行,那么我们需要泄露出来这段随机数。

这样的话,其实有点像格式化字符串的思路(但实际上并不是,,,晕)。

格式化字符串简介:

参考:https://www.freebuf.com/articles/system/317425.html

这位大佬讲的很接地气,可以直接看这位大佬的,这里就不在赘述了。

那就。。。直接来吧!

题目:

根据刚才的思路我们最想找的是printf 最好就是那种 read str之后 的printf

然后我们看看各个函数,找着找着就能发现 correct这个函数有猫腻

发现只要能够auth(v7)成立就行

现在我们找找能攻击的printf

…………………………

然后你会发现好像没啥能攻击的点()并且子函数又臭又长,如果还想着printf的话 实在难绷

但是我们发现有一个函数

memcpy 现在我们可以想到另一个东西,整数溢出(说白了就是利用unsigned /signed之间的范围差进行攻击)

整数溢出:

https://www.cnblogs.com/jopny/p/13527880.html

比较好的介绍如上

接着做题:

但是不应该攻击这里 最直接的攻击方式应该直接去auth里面去看攻击点

memcpy的作用是把input的地址拷贝a1个给v4地址上 注意无论a1是不是有符号数 在memcpy都会转成无符号数,这里就创造了一个攻击点。

v4放在了ebp-0x8的位置上 按理说上面紧跟着就是canary,如果我们放的input+读了很大的a1 就会覆盖掉栈上的东西

我们看一下auth的栈布局:

这很好,没从fs:28内存读东西,没用到canary 喜)

那这样的话,我们反而希望 从input读取的内容覆盖掉ebp 然后直接跳转到system函数就行

但是,观察到

这块v7<=12,因此我们最多读取12个字节覆盖ebp,

现在我们捋一下:输入一个字符串->base64解密(对于解密过程其实不用细看查网页就行)->v7不能大于12->进入auth进行整数溢出

观察到 auth里面

而 leave做的事情是把现在ebp指向的原来基址内容给到ebp上,说白了就是恢复ebp指向的内容。   

mov %ebp,%esp
pop %ebp

现在就很有意思了,我之前刷题少 没见过这种攻击方式,就是说 现在如果我修改了基址ebp的内容 确实不影响后面的执行,但是! 当main函数要退出的时候,他也是会retn的,而它是要跳转到ebp所指内容+4的,就是(%ebp+4)上的,那么现在就很简单了。

我们解码后的input,将ebp覆盖成input的地址,现在演示一下会发生什么

payload='a'*4+sysm+input

系统将ebp覆盖成了input地址,当main退出的时候,转到了存input的地址,先leave,将ebp搞成了aaaa,然后retn将sysm地址给了eip,这样 就攻击成功了。

(之所以选择跳转到input,是因为我们这里只能通过覆盖ebp进行攻击,而不能想过去一样随心所以的retn。)

(服了,wp研究半天)

注意 这里得先到08049284 你得先传参数啊(捂脸)

代码如下:

from pwn import *
import base64
elf=ELF("./format2")
r=remote("61.147.171.105",53358)
sys_addr=0x08049284
inputs=elf.symbols['input']
payload=b'a'*4+p32(sys_addr)+p32(inputs)
r.recvuntil("Authenticate :")
r.sendline(base64.b64encode(payload))
r.interactive()

(还是见题目少,第一次见这种针对main函数的攻击)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值