堆进阶学习之4大利器
字数 1579 2025-08-25 22:59:09

堆进阶学习之4大利器

一、Tcache攻击

1. Tcache原理

Tcache是glibc 2.26引入的线程本地缓存机制,用于提高堆分配性能,但牺牲了安全性检查。

关键特性:

  • 类似fastbin的单链表结构
  • 直接指向数据块而非chunk头
  • 每个size类最多缓存7个chunk
  • chunk大小范围:0x8到0x408字节
  • 超过大小限制或缓存满后进入常规bins
  • 采用LIFO(后进先出)策略

关键函数分析:

// 将free后的chunk放入tcache
static void tcache_put(mchunkptr chunk, size_t tc_idx) {
    tcache_entry *e = (tcache_entry *)chunk2mem(chunk);
    assert(tc_idx < TCACHE_MAX_BINS);
    e->next = tcache->entries[tc_idx];
    tcache->entries[tc_idx] = e;
    ++(tcache->counts[tc_idx]);
}

// 从tcache获取chunk
static void *tcache_get(size_t tc_idx) {
    tcache_entry *e = tcache->entries[tc_idx];
    assert(tc_idx < TCACHE_MAX_BINS);
    assert(tcache->entries[tc_idx] > 0);
    tcache->entries[tc_idx] = e->next;
    --(tcache->counts[tc_idx]);
    return (void *)e;
}

2. Tcache攻击方式

(1) 修改FD指针

  • 利用tcache不检查size的特性
  • 可实现任意地址写

(2) Double Free

  • 老版本可直接double free
  • 新版本需要通过overlapping heap chunk实现

(3) House of Spirit

  • 只需一个可控区域
  • 能覆盖堆地址即可
  • tcache不检查next chunk的size位

3. Overlapping Heap Chunk攻击(夹心饼攻击)

攻击步骤:

  1. 实现unsorted bin分配(绕过tcache机制)
  2. 构造布局:free1 → used2 → used3
  3. 通过used2溢出伪造used3的presize为前两个chunk大小
  4. 设置used3的pre_inuse为0(可通过off-by-null实现)
  5. free used3实现unlink合并到free1
  6. 切割合并后的chunk,获得两个used2指针

4. 实战案例:easy_heap

漏洞点:

  • off-by-null漏洞(输入结束置null)
  • 保护全开(PIE等)

利用步骤:

  1. 堆布局准备
  2. 构造夹心饼攻击条件
  3. 泄露地址
  4. double free利用
  5. 覆盖free_hook为one_gadget

二、沙箱规则

1. prctl函数

#include <sys/prctl.h>
int prctl(int option, unsigned long arg2, unsigned long arg3, 
          unsigned long arg4, unsigned long arg5);

重要选项:

  • PR_SET_NO_NEW_PRIVS(38):禁用系统调用
  • PR_SET_SECCOMP(22):设置沙箱规则

2. Seccomp模式

  1. SECCOMP_MODE_STRICT(1):仅允许read/write/exit/sigreturn
  2. SECCOMP_MODE_FILTER(2):自定义过滤规则

3. 结构体定义

struct sock_filter {
    __u16 code;   // 实际过滤代码
    __u8 jt;      // Jump true
    __u8 jf;      // Jump false
    __u32 k;      // 通用多用途字段
};

struct sock_fprog {
    unsigned short len;        // 过滤块数量
    struct sock_filter *filter;// 过滤块指针
};

4. 工具使用:seccomp-tools

常用命令:

  • 查看保护情况:seccomp-tools dump ./文件名
  • 文本形式展示:seccomp-tools dump ./文件名 -f inspect
  • 规则转汇编:seccomp-tools asm 文件名.asm -f assembly
  • 规则转C代码:seccomp-tools asm 44.asm -f c_source
  • 规则转结构体:seccomp-tools asm 文件名.asm -f raw | seccomp-tools disasm -

5. 实战案例:vip

利用步骤:

  1. 构造沙箱规则绕过限制
  2. 实现任意大小写入
  3. overlap创建unsorted bin泄露地址
  4. 修改FD为free_hook
  5. 覆盖free_hook为system

三、竞争条件

1. 基本概念

竞争条件是系统中由于并发访问共享资源导致的反常现象,可能引发:

  • 内存泄露
  • 系统崩溃
  • 数据破坏
  • 安全问题

2. 示例代码分析

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int i = 1;

void *mythread1() {
    if(i == 1){          // <a>
        sleep(3);
        if(i == 2)       // <b>
            printf("hack it!\n");
        else
            printf("try again!\n");
    }
}

void *mythread2() {
    sleep(1);
    i = 2;
}

int main() {
    pthread_t id1, id2;
    pthread_create(&id1, NULL, (void *)mythread1, NULL);
    pthread_create(&id2, NULL, (void *)mythread2, NULL);
    pthread_join(id1, NULL);
    pthread_join(id2, NULL);
    return 0;
}

执行流程:

  1. 线程1检查i==1(成立)
  2. 线程1睡眠3秒
  3. 线程2睡眠1秒后修改i=2
  4. 线程1醒来检查i==2(成立)
  5. 输出"hack it!"

3. 实战案例:强网杯pwn1

利用步骤:

  1. 泄露真实地址(异或0得到本身)
  2. 利用条件竞争先free再伪造FD为free_hook
  3. 申请两次修改free_hook为system
  4. free含有"/bin/sh\x00"的chunk

四、IO_File结构体与攻击方法

(待更新)

堆进阶学习之4大利器 一、Tcache攻击 1. Tcache原理 Tcache是glibc 2.26引入的线程本地缓存机制,用于提高堆分配性能,但牺牲了安全性检查。 关键特性: 类似fastbin的单链表结构 直接指向数据块而非chunk头 每个size类最多缓存7个chunk chunk大小范围:0x8到0x408字节 超过大小限制或缓存满后进入常规bins 采用LIFO(后进先出)策略 关键函数分析: 2. Tcache攻击方式 (1) 修改FD指针 利用tcache不检查size的特性 可实现任意地址写 (2) Double Free 老版本可直接double free 新版本需要通过overlapping heap chunk实现 (3) House of Spirit 只需一个可控区域 能覆盖堆地址即可 tcache不检查next chunk的size位 3. Overlapping Heap Chunk攻击(夹心饼攻击) 攻击步骤: 实现unsorted bin分配(绕过tcache机制) 构造布局:free1 → used2 → used3 通过used2溢出伪造used3的presize为前两个chunk大小 设置used3的pre_ inuse为0(可通过off-by-null实现) free used3实现unlink合并到free1 切割合并后的chunk,获得两个used2指针 4. 实战案例:easy_ heap 漏洞点: off-by-null漏洞(输入结束置null) 保护全开(PIE等) 利用步骤: 堆布局准备 构造夹心饼攻击条件 泄露地址 double free利用 覆盖free_ hook为one_ gadget 二、沙箱规则 1. prctl函数 重要选项: PR_SET_NO_NEW_PRIVS (38):禁用系统调用 PR_SET_SECCOMP (22):设置沙箱规则 2. Seccomp模式 SECCOMP_MODE_STRICT (1):仅允许read/write/exit/sigreturn SECCOMP_MODE_FILTER (2):自定义过滤规则 3. 结构体定义 4. 工具使用:seccomp-tools 常用命令: 查看保护情况: seccomp-tools dump ./文件名 文本形式展示: seccomp-tools dump ./文件名 -f inspect 规则转汇编: seccomp-tools asm 文件名.asm -f assembly 规则转C代码: seccomp-tools asm 44.asm -f c_source 规则转结构体: seccomp-tools asm 文件名.asm -f raw | seccomp-tools disasm - 5. 实战案例:vip 利用步骤: 构造沙箱规则绕过限制 实现任意大小写入 overlap创建unsorted bin泄露地址 修改FD为free_ hook 覆盖free_ hook为system 三、竞争条件 1. 基本概念 竞争条件是系统中由于并发访问共享资源导致的反常现象,可能引发: 内存泄露 系统崩溃 数据破坏 安全问题 2. 示例代码分析 执行流程: 线程1检查i==1(成立) 线程1睡眠3秒 线程2睡眠1秒后修改i=2 线程1醒来检查i==2(成立) 输出"hack it !" 3. 实战案例:强网杯pwn1 利用步骤: 泄露真实地址(异或0得到本身) 利用条件竞争先free再伪造FD为free_ hook 申请两次修改free_ hook为system free含有"/bin/sh\x00"的chunk 四、IO_ File结构体与攻击方法 (待更新)