안녕하십니까. barrack입니다.
먼저 그동안의 글을 읽어봤는데 틀린 정보도 있더라구요. 당시에는 맞다고 생각했던 정보들이 이제와서 보니 부족함이 많았다는 생각에 글을 쓰는게 좀 무서워졌었습니다.(누군가가 가짜 정보를 믿게 되지 않을까...)
그렇다고 블로그 쓰는걸 멈추긴 싫어서 경고 아닌 경고를... 해두려고요ㅎ
😊해당 블로그의 글은 barrack이 공부하며 적는 글입니다. 틀린 정보가 있을 수 있으니 모든 글을 정답으로 받아들이지 마시고, 만약 정확한 정보를 아시는 분이 계시다면 댓글로 알려주세요😊
그렇습니다. 이제 Hook overwrite 시작할까요...(매 블로그마다 반말과 존댓말을 넘나드는 사람)
Hook
Hook Overwrite을 하려면 Hook이 뭔지부터 알아야 하지 않을까요?
아래 코드는 malloc 의 코드입니다.
https://elixir.bootlin.com/glibc/glibc-2.23/source/malloc/malloc.c#L2902
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));
arena_get (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
/* Retry with another arena only if we were able to find a usable arena
before. */
if (!victim && ar_ptr != NULL)
{
LIBC_PROBE (memory_malloc_retry, 1, bytes);
ar_ptr = arena_get_retry (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
}
if (ar_ptr != NULL)
(void) mutex_unlock (&ar_ptr->mutex);
assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
ar_ptr == arena_for_chunk (mem2chunk (victim)));
return victim;
}
코드 분석
void *(*hook) (size_t, const void *) = atomic_forced_read (__malloc_hook);
malloc을 실행하게 되면 atomic_forced_read(__malloc_hook); 을 실행하게 됩니다.
atomic_forced_read는 스레드 안전하게 _malloc_hook의 값을 read 해준다고 하네요. (GPT 피셜이다)
__malloc_hook은 함수를 가르키는 함수 포인터 입니다.
따라서 위 코드가 실행되면 hook이 __malloc_hook을 가르키게 됩니다.
if (__builtin_expect (hook != NULL, 0))
return (*hook)(bytes, RETURN_ADDRESS (0));
아까 불러온 hook 함수가 NULL인지 확인하고, NULL이 아니면 malloc이 호출될 때 __malloc_hook에 설정된 사용자 정의 함수를 호출합니다.
이렇게 되면 'malloc'의 동작을 사용자 정의 함수로 대체할 수 있게 되는거죠!
그래서 hook이 뭔데?
hook은 소프트웨어 개발에서 특정 동작을 커스터마이징하거나 확장하기 위해 사용합니다.
대표적으로 Hooking은 OS가 어떤 코드를 실행하려 할 때, 이를 Hooking(훅! 낚아채는거)하여 다른 코드가 실행되게 하는 것이죠.
그럼 위에서 malloc에서 hook이 사용자 정의 함수로 설정되어있는지 확인하는 이유가 감이 살짝 오죠?
개발자들이 동적할당 관련해서 디버깅하거나 메모리 사용 패턴을 분석하거나... 뭐 등등... 할때 사용할것입니다.(GPT피셜)
Q. 그러면 기본적으로는 __malloc_hook이 NULL인건가요...?
A. 그렇다고 합니다. 그래서 평소에는 일반적으로는 arena_get 함수가 실행되어서 malloc이 동작하는거죠.
해커의 관점에서의 hook 공략법
그러면 이걸 어떻게 이용할 수 있을까요?
__malloc_hook, __free_hook, __realloc_hook과 같은 함수들은 .bss영역에 있습니다. 해당 영역은 쓰기가 가능한 영역이죠. 그렇다면 해당 값들을 원하는 주소로 변조하게 된다면 어떻게 될까요?
if (__builtin_expect (hook != NULL, 0))
return (*hook)(bytes, RETURN_ADDRESS (0));
hook을 system함수의 주소로 overwrite한다면, return system(bytes, RETURN_ADDRESS (0)); 이 실행이 되겠죠?
그렇다면 bytes는 malloc(인자) 였으니, malloc("/bin/sh")을 했으면 return system("/bin/sh")이 되는것입니다.
이게 바로 hook overwrite이죠.
'시스템해킹' 카테고리의 다른 글
[Dreamhack] PWN Sea of Stack writeup (0) | 2025.03.15 |
---|---|
pwnable.kr shellshock write up (0) | 2024.02.10 |
pwnable.kr leg write up (0) | 2024.02.08 |
pwnable.kr cmd1 write up (2) | 2023.12.07 |
pwnable.kr passcode write up (0) | 2023.11.30 |