前言

本文学习自Ex师傅的__free_hook 劫持原理, 根据学习情况略有补充和修改

例子

先从一个简单的例子来讲, 下面代码直接队全局变量__free_hook进行修改

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

extern void (*__free_hook) (void *__ptr,const void *);

int main() {
char *str = malloc(160);
strcpy(str,"/bin/sh");

printf("__free_hook: %p\n",__free_hook);

// 劫持__free_hook

puts(" __free_hook abduction");
__free_hook = (void*)system;

free(str);
printf("__free_hook: %p\n",__free_hook);
return 0;
}

编译运行:

➜  work gcc __free_hook.c -o __free_hook
➜ work ./__free_hook
__free_hook: (nil)
__free_hook abduction
$ echo hello world
hello world
$
__free_hook: 0x7f545a07f4e0

源码分析

glibc-2.23/malloc/malloc.c: 1851

void weak_variable (*__free_hook) (void *__ptr,
const void *) = NULL;

这里定义为的__free_hook定义为全局变量,所以可以直接被修改。再来看看__free_hook的引用:

void
__libc_free (void *mem)
{
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */

void (*hook) (void *, const void *)
= atomic_forced_read (__free_hook);
if (__builtin_expect (hook != NULL, 0))
{
(*hook)(mem, RETURN_ADDRESS (0));
return;
}
// ...
}

上面的代码是free()函数的一部分,可以看出程序先把全局变量__free_hook赋给了局部变量hook,然后对hook是否为NULL进行判断,如果不为空,则执行hook,第一个参数就是chunk的内容部分。

一般情况下__free_hook是为NULL, 因此上述代码是不会执行的, 但是如果恶意修改__free_hook, 就会造成__free_hook劫持, 如例子所示

参考

__free_hook 劫持原理