吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9875|回复: 67
收起左侧

[系统底层] 从零开始的Linux堆利用(四)——Unsafe Unlink

  [复制链接]
呆毛王与咖喱棒 发表于 2021-4-29 20:14
本帖最后由 呆毛王与咖喱棒 于 2021-11-7 17:30 编辑

写到第四篇了,也不知道有没有人看,再贴一下自己博客的链接https://hack1s.fun/

这次是介绍到堆中Unlink时可能出现的问题

这种Unlink的技巧是比较久远的年代提出的,当时还没有NX、ASLR这样的安全机制,我们这次也用到旧版本的glibc


Unsorted Bin

与Top Chunk相邻的chunk,在Free之后如果不属于fastbin,就会直接合并到Top Chunk中

image-20210323151654862

fastbin最大是可以放0x80,这边申请两个大小为0x90的chunk,之后free与top chunk相邻的那个

image-20210323151755991

可以看到这是直接将空间收回了;

下面我们再执行两个malloc,重新申请b的空间,以及再申请一个新的0x20大小的空间;

这时堆中的内容是下面这样

image-20210323152024792

这时如果将a的空间释放,a就被链接到了unsorted bins上面

image-20210323152331967

这里发生变化的主要有三个地方;

  • 被释放的块a的用户空间中的两个字,变成了两个指针(绿色框)
  • 与a靠近的块b,指示位previous_inuse,值从原本的91变成了90(蓝色框)
  • 与a靠近的块b,原本空着的一个字变成了previous_size,也是90(红色框)

unsortedbin 是一个双向链表的结构,因此a中这两个指针分别是backward和forward;

目前只有a一项,所以是同一个值,这个值就是main_arena中的top这个字段;

image-20210323154000475

我们继续执行,把b也free了,这时并不会再unsortedbin中加两项,而是会把ab两个块合并在一起

image-20210323154354084

可以看到直接是修改了块a的大小,变成了120,最后一个chunk的prev_size也是变成了120

free掉一个fastbin是对周边的chunk没有影响的,但是free常规的chunk,是对周围的值有影响的;

前面一部分介绍了unsortedbin,我们可以注意到它是通过一个链表实现的;

image-20210323165239257

链表大概就是这样的一个结构;

fd、bk分别是双链表的指针,指向前后的块;

如果想要拆下来其中的一个块,只需要把它前一个块的fd改成它自身的fd,把它后一个块的bk改成它自身的bk就可以;

image-20210323170813482

在低版本的GLIBC中没有对这个过程进行检查,并且是通过宏来实现的;

并且由于fd、bk这两个指针本身的位置是一个正常块的user data部分,所以这里是存在伪造的可能的;

示例程序

下面就用一个例子来看一下;

image-20210323190151013

程序和之前一样是一个菜单形式

1是malloc申请空间,2是可以输入对应空间要填充的内容,3可以free掉申请的chunk

这个程序的malloc申请的chunk限制了大小在120~1000字节之间;

0x78是120比特,也就是说正好是fastbin放不下的chunk

另外还有一点就是,这个漏洞unsafe_unlink提出的时候还没有NX,这个程序为了讲最基本的原理也关闭了NX

image-20210327110922700

任意地址写

首先是程序的漏洞所在,就是没有进行输出内容长度的判断,申请a、b后输入很多内容回溢出到下一个chunk

这个类似于之前的House_of_force,但是这个程序限制了malloc的次数,所以没办法像House_of_force一样利用;

image-20210329155553056

那么我们还是先设法获取一个任意地址写的能力;

我们这次一共只能申请两次chunk

在前面的demo程序中也了解到了,远离top chunk的块a被free之后会加入到unsortedbin

并且会出现这几个修改

  • 还在使用中的块b,size filed中prev_inuse位置零;
  • 被释放的块a,user data最后一个字变成块a的大小,即prev_size字段;
  • 被释放的块a,user data的前两个字节变成两个指针,分别是fd和bk;

这时free(b)会把两个块合并,实际上执行的操作是

  1. 查看b的prev_inuse,发现位0,前一个块已经被释放;
  2. 查看b的prev_size,找到块a的起始地址;
  3. 把a从unsortedbin list上卸载下来,即按照fd、bk去修改前后块的地址

那么我们一步一步来,首先申请a、b两个chunk

编辑chunk_a的数据,把b的prev_inuse位清0

a = malloc(0x88)
b = malloc(0x88)

edit(a,b'a'*0x88+p64(0x90))

可以看到这时a的最后一个字已经属于b了

image-20210329161824457

下面把prev_size这个字段也伪造了,只需要修改刚才的edit那句

edit(a,b'a'*0x80+p64(0x90)*2)

image-20210329162148950

接下来我们需要填入两个指针,修改chunk_a的fd和bk两个字段;

在unlink的时候实际上是

this.fd->bk = this.bk;
this.bk->fd = this.fd;

这样两个写入操作,如果我们想要用第一个语句来写

那么fd+0x18是最终写入的地址,bk是写入的内容;

我们先试着直接利用这个写入堆中的数据

由于测试的时候都关闭了ASLR,直接是用的固定的地址

我们输入的payload直接就拿这个固定的地址了

edit(chunk_A, p64(0x555555757090)+p64(0x5555557570b0)+b"a"*0x70+2*p64(0x90))
free(chunk_B)

image-20210329163725241

执行完毕之后,用vis可以看到A、B一起都被free掉了

并且可以看到我们输入的两个值都写到内存里了,fd+0x18写入了70b0bk+0x10写入了7090

说明确实是可以写的;

这可以说是一个有限制的任意地址写;

限制在于要写的数据也会被当成地址来做一个解析,并且会尝试往那个地址写内容;

命令执行

接下来尝试将这个转换为一个命令执行的漏洞

如果我们直接在__free_hook写入system的话,会导致system之后的内容也被写入一些内容

这样由于尝试在不可写的地方写入导致出错;

不过由于这个程序是2000s时的程序,NX没有开启,因此我们可以直接把shellcode写到内存里面

之后把__free_hook覆盖成堆里面的地址

edit(chunk_A, p64(fd) + p64(bk) + shellcode + p8(0)*(0x70-len(shellcode)) + p64(0x90)*2

修改一下要edit的内容

shellcode的话由于bk+0x10会被写入为fd的值,shellcode中需要空出来一小段区域,这个可以通过汇编加一个小jmp实现

shellcode = asm("jmp shellcode;"+ "nop;"*0x20+ shellcraft.execve("/bin/sh"))

这里的nop至少要把bk+0x10这里的8个字节都空出来,最小值的话应该是0x18-len("jmp shellcode")

jmp shellcode汇编代码是两个字节,所以这里至少要是0x16

image-20210401101944829

可以看到图中红框是shellcode的内容,绿框是指向shellcode地址的一个指针,即bk

下面执行free(b)

image-20210401102202252

看到堆中a和b都已经被释放掉了,并且bk+0x10的位置已经变成了fd__free_hook的值

使用u可以将__free_hook中的内容当作code打印出来,可以看到已经是我们shellcode的内容了

image-20210401102941350

这时继续执行,再调用一次free就会执行我们的shellcode

最终返回了一个shell

image-20210401102517211

unsafe_unlink.zip

9.44 KB, 下载次数: 28, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 20吾爱币 +18 热心值 +17 收起 理由
junjia215 + 1 + 1 用心讨论,共获提升!
RiiiickSandes + 1 + 1 OHHHHHHHHHHHHHHHHHH
Connly + 1 + 1 我很赞同!
blywq + 1 + 1 谢谢@Thanks!
like852 + 1 + 1 用心讨论,共获提升!
victos + 1 + 1 谢谢@Thanks!
qaz007 + 1 + 1 用心讨论,共获提升!
zhukun1980 + 1 + 1 谢谢@Thanks!
chuxia12 + 1 鼓励转贴优秀软件安全工具和文档!
xiong_online + 1 + 1 用心讨论,共获提升!
longestusername + 1 + 1 谢谢@Thanks!
senur + 1 谢谢@Thanks!
tetrahedro + 1 + 1 我很赞同!
Kristin_ + 1 我很赞同!
MYC_OvO + 1 热心回复!
erh + 1 + 1 谢谢@Thanks!
努力加载中 + 1 + 1 热心回复!
malu2335 + 1 谢谢@Thanks!
LENY77777 + 1 + 1 我很赞同!
唐小样儿 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

UNKNNOW 发表于 2021-5-1 17:03
呆毛王与咖喱棒 发表于 2021-4-30 12:29
就随便找的一个,主题不太重要,主要是多写🤣

想要你那种的 我自己的用的emlog 很简陋 求你了大佬
 楼主| 呆毛王与咖喱棒 发表于 2021-4-30 12:29
UNKNNOW 发表于 2021-4-30 08:45
有人看有人看 大佬你博客用的是wordpress 的哪个主题呀

就随便找的一个,主题不太重要,主要是多写🤣
鹏总不惯病 发表于 2021-4-29 20:46
eonezhang 发表于 2021-4-29 21:24
666666666
LENY77777 发表于 2021-4-29 23:16
我啥也不是,啥也不会
kmzwyong12 发表于 2021-4-29 23:51
学无止境,感谢分享!!!
cqzhaodaxio 发表于 2021-4-30 00:26
膜拜,这种好帖
cqzhaodaxio 发表于 2021-4-30 00:38
分析的很经典啊!!!!
灵魂守卫 发表于 2021-4-30 07:41
不明觉厉!膜拜大佬!
傅粉何郎 发表于 2021-4-30 07:46
最近正在学习linux,感谢分享666
xao 发表于 2021-4-30 08:33
学无止境,感谢分享!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-25 04:59

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表