_hook Overwrite

oogu ㅣ 2023. 1. 18. 17:02

_hook Overwrite


c 표준 라이브러리에서는 malloc, realloc, free와 같은 함수들의 동작을 수정할 수 있도록 __malloc_hook, __realloc_hook, __free_hook과 같은 변수를 제공합니다. 이러한 변수에 후킹 함수의 주소가 저장되어 있으면 함수가 호출될 때 기존의 함수가 아니라 후킹 함수가 호출됩니다.

__int64 __fastcall malloc(__int64 a1, __int64 a2, __int64 a3)
{
  if ( _malloc_hook )
    return _malloc_hook(a1, retaddr);

이런 후킹 변수들은 라이브러리의 쓰기 가능한 영역에 존재하기 때문에 후킹 변수를 사용하는 함수가 있다면 익스플로잇 과정에서 이를 실행 흐름을 조작하는 데 사용할 수 있습니다.

 

hook1.c


// gcc -o hook1 hook1.c
#include <stdio.h>
#include <malloc.h>
int main()
{
	__malloc_hook = 0x41414141;
	malloc(1);
}

hook1.c는 __malloc_hook을 0x41414141 값으로 덮어쓰고 malloc 함수를 호출하는 코드입니다.

[그림 1-1]

gdb로 run을 하고 rip 값을 확인하면 0x41414141 값이 들어가 있습니다.

__malloc_hook 변수를 덮어씀으로써 malloc 함수가 호출될 때 pc가 0x41414141로 바뀐 것을 확인할 수 있습니다.

 

__malloc_hook, __realloc_hook, __free_hook과 같은 훅 변수들은 c code 상에서 지정하지 않는 한 기본값이 NULL로 되어있습니다. 그래서 익스플로잇 과정에서 훅 변수가 overwrite 한 시점 이후부터 훅 변수 값인 함수 or 코드가 호출됩니다.

 

hook2.c


// gcc -o hook2 hook2.c

#include <stdio.h>
#include <malloc.h>

int main()
{
        long int *ptr;
       
        printf("stdout@LIBC addr: %p\n", *&stdout);
        
         for(int i=0; i < 10; i++) {
                ptr = (long int *)malloc(1024);              
                read(0, ptr, 1024-1);
                
                *(long int *)*ptr = *(long int *)(ptr+1);
                free(ptr);
        }

}

hook2.c는 라이브러리 주소를 출력한 후, 힙 버퍼를 할당하고 입력받아 이를 기반으로 임의 주소 쓰기를 수행하는 코드입니다.

공격자는 라이브러리 내에 존재하는 stdout 포인터를 통해 라이브러리의 베이스 주소를 알아낼 수 있고, 이를 통해

__malloc_hook 과 __free_hook의 주소를 알아낼 수 있습니다. 해당 주소를 알아냈다면 _hook을 덮어씀으로써 다음번 반복에서 malloc 혹은 free 함수가 호출될 때 pc를 조작할 수 있습니다.

 

__malloc_hook과 __free_hook의 주소 및 오프셋은 gdb를 이용해 알아낼 수 있습니다.

[그림 1-2]

 

[그림 1-2] 참고하면 __malloc_hook 의 offset은 0xc30, __free_hook의 offset은 0x8e8 입니다.

이를 원샷 가젯으로 덮으로 쉘을 획득할 수 있습니다.

[그림 1-3]

 

[그림 1-4]

[그림 1-4]는 주어진 stdout 포인터를 통해 라이브러리의 베이스 주소를 구하고 __malloc_hook, 원샷 가젯의 주소를 알아냈습니다. 이후에 주어진 임의 주소 쓰기 취약점을 이용해 __malloc_hook을 원샷 가젯의 주소로 덮어쓰는 코드입니다.

hook2에서 반복문을 통해 malloc이 열 번 호출되기 때문에 덮어쓴 후에 malloc 함수가 호출되면 원샷 가젯의 코드가 실행되어 쉘을 획득할 수 있습니다.

 

 

참고


https://coding-factory.tistory.com/671

 

[C언어] 메모리 동적할당 (malloc, free) 함수 사용법 & 예제

메모리의 동적 할당이란? "메모리를 동적 할당한다"라는 뜻은 컴퓨터 프로그램이 실행되는 도중인 런타임 도중에 사용할 메모리 공간을 할당하는 것을 말합니다. 동적 할당되는 메모리는 힙 영

coding-factory.tistory.com

 

https://dreamhack.io/forum/qna/694

 

hook2.c 코드 설명 부탁드립니다.

강의 자료에서 제공된 hook2.c 의 소스코드 입니다. #include <stdio.h> #include <malloc.h> int main() { long in…

dreamhack.io

 

 

stdout_offset = lib.symbols['_IO_2_1_stdout_'] -> ['stdout'] 인 줄 알았다..

stdin_offset = lib.symbols['_IO_2_1_stdin_']

 

 

'Dreamhack - pwnable' 카테고리의 다른 글

fho  (0) 2023.01.19
Hook Overwrite (2)  (0) 2023.01.19
PIE (Position-Independent Executable)  (0) 2023.01.16
RELRO (RELocation Read-Only)  (0) 2023.01.16
basic_rop_x86 (ret2main + bss 쓰기)  (0) 2023.01.15