__malloc_hook和__free_hook hijack原理 Hook即钩子,截获API调用的技术,是将执行流程劫持到你自己的代码。
刚开始在Ubuntu22上做实验,一直不成功,又换了kali,还是不行,最后发现__free_hook,__malloc_hook,__realloc_hook,_memalign_hook, _after_morecore_hookg在libc-2.34的patch中被移除了,换了Ubuntu16 libc版本2.23,但是发现只是在ld链接时会找不到definition,也就是无法通过链接的环节,但是在libc库里还是有的,可能是考虑之前使用hook程序的兼容。
grxer@Ubuntu16:/usr/include$ ldd --version ldd (Ubuntu GLIBC 2.23-0ubuntu11.3) 2.23 Copyright (C) 2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by Roland McGrath and Ulrich Drepper.
malloc free 先看一下malloc和free函数具体调用
#include <stdio.h> #include <malloc.h> int main () { void *x=malloc (8 ); free (x); return 0 ; }
malloc
由于版本不一样__malloc_hook在main_arena的上方偏移是不确定的,这里可以看到在malloc时会从取出__malloc_hook的值进行test,不为0则跳转,为0则继续malloc,这里采用了rip的寻址方式,很6,不利于我们分析,看静态汇编吧
不为0跳转到,为0直接get_free_list去fastbins找free chunk了( glibc 2.26才引入tcache)
最后jmp到malloc_hook地址函数里,同时rdi的参数也未变,如果我们把hook改为system地址,那么只要在malloc时填入binsh地址就可以getshell
free同理
free hook不同的是采用了call的形式转移pc
malloc hook #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> int main () { __malloc_hook =system; char str[10 ]="/bin/sh" ; char *s = malloc (str); return 0 ; }
.text:000000000041F220 malloc_hook_ini proc near ; CODE XREF: calloc+2C8↑p .text:000000000041F220 ; DATA XREF: .data:__malloc_hook↓o .text:000000000041F220 ; __unwind { .text:000000000041F220 55 push rbp .text:000000000041F221 53 push rbx .text:000000000041F222 48 89 FD mov rbp, rdi .text:000000000041F225 48 83 EC 08 sub rsp, 8 .text:000000000041F229 8B 05 35 B5 2A 00 mov eax, cs:__libc_malloc_initialized .text:000000000041F22F 48 C7 05 4E B5 2A 00 00 00 00+mov cs:__malloc_hook, 0 .text:000000000041F22F 00 .text:000000000041F23A 85 C0 test eax, eax
这时候我们发现malloc_hook并没有为0,而是malloc_hook_ini,会在mov cs:__malloc_hook, 0 置为0
free hook同理 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> int main () { char *str = malloc (160 ); strcpy (str,"/bin/sh" ); printf ("__free_hook: 0x%016X\n" ,__free_hook); __free_hook = system; free (str); return 0 ; }