首页
社区
课程
招聘
[原创]printf函数leak与canary绕过原理及利用方式
发表于: 2018-6-30 18:31 21345

[原创]printf函数leak与canary绕过原理及利用方式

2018-6-30 18:31
21345

printf 属于可变参数函数,函数调用者可任意指定参数和数量,这也是漏洞产生的原因。
printf()函数的一般形式为:

format参考列表

编译命令

会弹出警告


接着我们尝试运行并输入 AAAA%x,%x,%x,%x,%x,%x,%x,%x,%x

我们可以利用gdb看一下输入的地址

我们可以知道数据在堆栈中是如何储存的并且知道输出的第7位是AAAA的ascll码
为了pwn的利用 我们可以只输出指定的地址
这里利用printf函数的一个特性,$操作符
例如我们现在要输出第7位


发现成功输出第七位AAAA的ascll码

要检测对函数栈的破坏,需要修改函数栈的组织,在缓冲区和控制信息(如 EBP 等)间插入一个 canary word。这样,当缓冲区被溢出时,在返回地址被覆盖之前 canary word 会首先被覆盖。通过检查 canary word 的值是否被修改,就可以判断是否发生了溢出攻击。
为了方式发生信息泄露以及其他漏洞的利用 canary使用\x00对值进行截断
所以canary的最低byte位为\x00

pwn200

程序提供了shell
检查下程序保护

开启了NX以及Canary保护

可以对照源代码 发现多出了变量V5 根据上述canary保护解释应该可以理解 这里的V5应该就是canary保护生成的随机参数 我们也可以在汇编代码处看出

因为v5的地址是esp+3Ch 而这里 mov edx,[esp+3ch]就可以知道edx里面存在的就应该是v5的值了
看到这里利用edx中获取的v5的值与large gs:14h进行 xor判断 如果不相等则 call ___stack_chk_fail 退出程序

一般canary有两种利用方式
1.爆破canary
2.如果存在字符串格式化漏洞可以输出canary并利用溢出覆盖canary从而达到绕过

载入程序到gdb

在printf处下断


尝试运行
这是可在看到我们输入的字符串在堆栈中的位置

尝试打印该地址内存


可以看到输出AAAA的偏移为5
printf打印出的应该是偏移后的下一位地址
我们再运行程序进行测试输出


发现成功输出
这里需要注意 输出的地址都是十进制数 所以在后面地址的利用时 我们应转为16进制使用 或者直接利用pwntools函数p32或者p64直接进行转换
既然canary


我们这xor判断这里下断

输入C 运行到下一断点位置
查看此时的edx的值

我们可以查看之前printf时的内存地址

发现edx 0x68496c00 的偏移为15,所以可以构造打印出当前的canary的值


成功泄露出当前canary

我们应该这样去写exp

既然可以泄露出canary的值,我们就可以通过gets溢出到canary处然后覆盖我们leak处的canary从而达到绕过canary的目的

因为canary的赋值是从v5而来所以这里计算s与v5的偏移即可

得到偏移为40
所以这里的payload可以写为

我们这里的最终目的是为了获取shell
而程序提供了shell


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

最后于 2018-6-30 19:29 被iosmosis编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (13)
雪    币: 265
活跃值: (29)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
2018-7-1 16:25
0
雪    币: 6911
活跃值: (9069)
能力值: ( LV17,RANK:797 )
在线值:
发帖
回帖
粉丝
3
哈哈哈哈 学习了
2018-7-1 19:13
0
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
2018-7-1 23:11
0
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
2018-7-1 23:12
0
雪    币: 543
活跃值: (370)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
6
无名侠 哈哈哈哈 学习了
和大佬一起学习
2018-7-2 11:31
0
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
7
关键点在于那条 gcc 编译参数(-fno-stack-protector),禁用了栈保护功能,于是程序 printf 在运行时不会检查栈上数据是否被非法覆盖。不过实践中很少有软件会刻意忽略掉金丝雀的 
2018-7-2 14:05
0
雪    币: 543
活跃值: (370)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
8
shayi 关键点在于那条 gcc 编译参数(-fno-stack-protector),禁用了栈保护功能,于是程序 printf 在运行时不会检查栈上数据是否被非法覆盖。不过实践中很少有软件会刻意忽略掉金丝雀的 ...
嗯对,那条gcc编译主要是为了演示printf函数漏洞利用,题目的话canary是开启的
2018-7-3 09:22
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
2018-7-24 07:21
0
雪    币: 3170
活跃值: (129)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
受益匪浅
2018-8-3 13:22
0
雪    币: 543
活跃值: (370)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
11
灵音 受益匪浅
2018-8-9 23:32
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
大佬这几句没有看懂,能解释一下吗?
因为这里的canary已经被覆盖
而v5距离ebp为0x4
所以此时只需要计算v5到ebp的偏移即可
距离和偏移不一样吗?
最后于 2018-10-18 18:22 被枫筱一墨编辑 ,原因:
2018-10-18 18:19
0
雪    币: 543
活跃值: (370)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
13
枫筱一墨 大佬这几句没有看懂,能解释一下吗?因为这里的canary已经被覆盖而v5距离ebp为0x4所以此时只需要计算v5到ebp的偏移即可距离和偏移不一样吗?
那里其实想算得就是v5的偏移  而位是通过算计算v5的地址再而计算偏移 所以用了距离这个词==  其实位想表达的是一样德
2018-11-18 12:57
0
雪    币: 199
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
咨询一下楼主,第二步算v5和ebp偏移的时候,int v5; // [esp+3Ch] [ebp-4h],为什么偏移不直接是ebp-4h,偏移为4?而是esp+3c减去ebp得出偏移?这个 [ebp-4h]是什么啊?
2019-5-23 09:23
0
游客
登录 | 注册 方可回帖
返回
//