首页
论坛
课程
招聘
雪    币: 530
活跃值: 活跃值 (208)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝

[原创]pwn中one_gadget的使用技巧

2020-8-1 11:12 941

[原创]pwn中one_gadget的使用技巧

2020-8-1 11:12
941

one_gadget介绍

很多新手在栈溢出的时候会手动输入/bin/sh地址和system等函数的地址,这样不仅麻烦而且很容易出错。其实libc中带有很多gadget,控制程序跳转到这些位置执行并满足一定的条件就可以拿到shell。

栈上的万能one_gadget

最常见的用法是one_gadget后面跟libc文件,就可以拿到one_gadget的地址了,上图我以libc 2.27为例,这里有一个小技巧,就是可以看到one_gadget是需要满足一定条件的,这里我认为最好满足的是 rsp+0x40==NULL 这个条件,要求栈上的这个位置为null,这里随便拿一个程序来看一下。我在返回地址处填充了0x4f3c2这个gadget。

然后跟进去运行, ,发现程序将rsp+0x40赋值给了rsi,那么显然这个值是需要是null的,这也跟刚才one_gadget给我们提示的满足条件相符合。看一下这个值,
这个值并不是null,这样的话运行下去显然是会出错的,修改这个值显然也很麻烦,但是我们可以观察到0x7fffb5b9e0d0 + 0x60是null,符合我们的要求,而且刚才溢出的时候我们是可以控制rsp的,我们可以在输入one_gadget之前多个ret指令的addr,这样就可以增加rsp的值了。修改后的payload如下

payload = 0x78 * 'a' + p64(ret_addr) + p64(ret_addr) + p64(ret_addr) + p64(ret_addr) + p64(one_addr)

此时

这样就可以满足我们的要求了

其他技巧

后面加-l2参数可以找到更多的gadget。

另外还有一个near功能也很管用,可以找最靠近某个函数的gadget,这里我以libc 2.23为例。

one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near read


可以看到这两个地址只相差了两个字节。利用这一点我们可以在泄露不了libc的情况下采用尾字节覆盖的方式来强行修改read函数地址成为我们的one_gadget地址。我们看到libc函数在随机时最后倒数两个字节中只有前半个字节随机。
第一次

第二次

因此在这里我们只要覆盖尾部的两个字节,我们就有1/16的概率命中。
one_gadget的介绍到这里就结束了,如果有不足的地方,欢迎大家指正。

[公告]SDC2020 看雪安全者开发者峰会10月23日将在上海举行!欢迎参加!

最后于 2020-8-1 14:06 被Mr.Bean编辑 ,原因: 刚才图片挂了
最新回复 (5)
雪    币: 5387
活跃值: 活跃值 (1866)
能力值: (RANK:220 )
在线值:
发帖
回帖
粉丝
0x2l 活跃值 2 2020-8-1 11:26
2
0
图片挂了
雪    币: 8
活跃值: 活跃值 (57)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6otest 活跃值 2020-8-1 12:18
3
0
403
雪    币: 530
活跃值: 活跃值 (208)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
Mr.Bean 活跃值 2020-8-1 14:07
4
0
图片已修复
雪    币: 1563
活跃值: 活跃值 (555)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
iddm 活跃值 4 2020-8-6 21:18
5
0
图片上的one和read不是三个字节不一样么?
雪    币: 530
活跃值: 活跃值 (208)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
Mr.Bean 活跃值 6天前
6
0
iddm 图片上的one和read不是三个字节不一样么?
尾部字节虽然是不一样的,但是一直是一个固定的值
游客
登录 | 注册 方可回帖
返回