Post

(glibc) free\_hook, malloc\_hook

1
2
3
4
gdb-peda$ x/4wx &\_\_free\_hook
0xf7fd08b0 <\_\_free\_hook>:       0x00000000
gdb-peda$ patch 0xf7fd08b0 one\_gadget\_addr

32bit libc.so의 경우 다음과 같이 unsorted\_bin에서 0x10 단위로 조회하면 없는 것 처럼 나오는데, 이는 gdb가 맨 왼쪽에 있는 symbol만 표시해주기 때문이다.

1
2
3
4
5
gdb-peda$ x/40wx 0xf7fad7b0 - 0x60
0xf7fad750:     0x00000000      0x00000000      0x00000000      0x00000000
0xf7fad760 <\_\_memalign\_hook>:   0xf7e6cfa0      0xf7e6cf40      0x00000000      0x00000000
0xf7fad770:     0x00000000      0x00000000      0x00000000      0x00000000

이렇게 조회해보면 있다. 그리고 어차피 \_\_free\_hook은 여기에 없기 때문에 unsorted\_bin에서 바로 hook func에 접근하지 말고 libc\_base를 계산해서 접근하는 것이 좋다.

1
2
3
gdb-peda$ x/4wx 0xf7fad7b0 - 0x48
0xf7fad768 <\_\_malloc\_hook>:     0x00000000      0x00000000      0x00000000      0x00000000

__free_hook VS __malloc_hook

아무래도 malloc("/bin/sh")보다는 c free("/bin/sh")쪽이 훨씬 더 자연스럽고 인자 넣기도 수월하다. 전자는 ` size고 후자는 ptr이니까, 그냥 문자열 넘기고 이를 free하도록 하면 된다. 대신 64bit의 경우 malloc()은 근처에 0x7f같이 chunk.size`로 쓸만한 주소가 있는 경우가 있어 fastbin attack으로 chunk를 할당하기 좋다. * smallbin range chunk는 unlink 때문에 할당할 수가 없다.

argument push

free(arg) / malloc(arg)이면 hook\_func(arg)으로 넘어간다. 따라서 free("/bin/sh") / malloc("/bin/sh")를 호출해야 system("/bin/sh")가 된다. one-gadget을 사용할 수 없는 경우 이렇게 직접 argument를 넘길 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <malloc.h>

  

int main(){
void \*a;
a = malloc(10);
a = malloc("/bin/ls");
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
arg[0]: 0x4005e4 --> 0x736c2f6e69622f ('/bin/ls')
gdb-peda$ patch 0x7ffff7dd3740 0x7ffff7a5b590 // ( == patch \_\_malloc\_hook system)
Written 6 bytes to 0x7ffff7dd3740
gdb-peda$ c
Continuing.
[New process 6924]
process 6924 is executing new program: /bin/dash
[New process 6925]
process 6925 is executing new program: /bin/ls
ht  ht.c  malloc\_hook  malloc\_hook.c  peda-session-ht.txt

__malloc_hook 호출 sequence

코드에서 정상적으로 __malloc_hook을 변경하는 경우

* rip+0x33b870 == 0x7ffff7dd2ee0는 libc의 bss section이다.

1
2
3
4
5
6
7
8
9
10
11
malloc()

   

\_\_GI\_\_\_libc\_malloc() {
mov    rax,QWORD PTR [rip+0x33b870]   # 0x7ffff7dd2ee0: 0x601060
mov    rax,QWORD PTR [rax]    # RAX: 0x601060 (<\_\_malloc\_hook@@GLIBC\_2.2.5>) --> 0x4005bd (<my\_malloc\_hook>)
}

hook\_func()

&__malloc_hook에 직접 접근해 값을 변경하는 경우
1
2
3
4
5
6
7
8
9
10
11
malloc()

   

\_\_GI\_\_\_libc\_malloc() {
mov    rax,QWORD PTR [rip+0x33b870]   # 0x7ffff7dd2ee0: 0x00007ffff7dd3740
mov    rax,QWORD PTR [rax]    # RAX: 0x7ffff7dd3740 (<\_\_malloc\_hook>) --> 0x7ffff7a5b590 (<\_\_libc\_system>)
}

hook\_func()

This post is licensed under CC BY 4.0 by the author.