본문 바로가기
[ ★ ]Study/PWNABLE

Use After Free 취약점

by nroses-taek 2017. 9. 16.
Use After Free 취약점
UAF 취약점

그대로 사용한 해제했을 취약점이 발생하는 것을 뜻합니다. 정확히는
heap 영역에서 할당된 ( malloc ) 공간을 free하고 reuse 일어날 있는 취약점입니다.
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    int *heap1;
    int *heap2;
    int *heap3;
 
    heap1 = (int *)malloc(sizeof(int* 50);
    heap2 = (int *)malloc(sizeof(int* 50);
 
    printf("heap1 address : %p\n", heap1);
    printf("heap2 address : %p\n", heap2);
 
    *heap2 = 1234;
    printf("heap2 number : %d\n"*heap2);
 
    printf("free heap2 :)\n");
    free(heap2);
 
    heap3 = (int *)malloc(sizeof(int* 50);
    printf("heap3 address : %p\n", heap3);
    printf("heap3 value : %d\n"*heap3);
 
    return 0;
}
cs

sizeof(int) * 50 ( 200bytes ) 만큼 할당을 2번하고
번째 heap2 값을 넣은 free해주었습니다.
후에는 heap3 같은 크기로 할당해주었으며
주소와 값을 print 해주었습니다. 결과 heap2 address value 같은 것을
확인할 있습니다.
 
이는 heap 메모리를 효율적으로 사용하기 위해 반환된 heap영역의 크기를 기억해놨다가 
같은 크기의 할당 요청이 들어오면 이전 영역을 재사용하게 합니다.
이는 malloc 함수에는 caching 기능이 있는데, Deferred Coalescing(병합 지연) 속성이라고 합니다. heap2 free heap3 다시 할당하면 병합하거나 분할하는 시간을 절약하고자 영역을 그대로 사용하게 해주는 겁니다.
 
결과적으로 메모리를 효율적으로 사용하지만 반대로 공간을 재사용할 경우, 원하지 않는 값을 참조할 있게 됩니다.
(2016년에 어떤 개발자가 \0 넣어주면서 한게 기억이 나네요)
 
< 예제는 Use After Free Heap Overflow 다룹니다>
예제는 https://bpsecblog.wordpress.com/2016/10/06/heap_vuln/ 여기를 참고하였습니다.

예제 소스는 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct{
    char namep[10];
    void (*print)(void*);
}test;
 
typedef struct{
    char name[128];
}string;
 
void printName(test *t)
{
    printf("%s\n", t->name);
}
 
void shell(void)
{
    printf("This is Shell\n");
}
 
int main(void)
{
    test *t1;
    string *s1;
 
    t1 = malloc(256);
 
    strcpy(t1->name, "DOG");
    t1->print = (void*)printName;
 
    t1->print(t1);
 
    free(t1);
 
    s1 = malloc(256);
 
    scanf("%128s", s1->name);
 
    t1->print(t1);
 
    return 0;
}
cs
test, String 구조체 변수들을 선언해주었습니다.
때의 Heap 영역은 아래와 같이 할당됩니다.

여기서 주의깊게 봐야 되는건 같은 위치에서 이벤트들이 발생하고 있다는 겁니다.
test 할당 -> test 해제 -> string 할당 -> test 사용
하게 된다면 마지막 test사용에서 어떤 값으로 바뀌었을지 모르는 포인터를 참조하게 됩니다.
 
test 구조체가 free 같은 위치에 string 구조체가 할당되는데
test구조체의 멤버 변수 print라는 함수 포인터의 값을 덮을 있습니다.
원래는 t1->print = (void*)printName; 값이 들어가 있지만, 값을
shell 함수의 주소로 덮은   마지막 t1->print(t1); 코드가 실행된다면 PrintName함수가 아닌 Shell 함수가 실행될 것입니다.


main 에서 scanf 실행을 시킨 브레이크를 잡아보았습니다.
s1->name 알아보기 쉽게 aaaa값을 넣었습니다.


할당된 영역을 확인해보겠습니다.
입력된 아래보면 40062d주소가 보이네요


40062d 주소에는

당연히 실행될 printName코드가 들어가 있습니다.
그러면 a 16 채우고 shell 주소를 덮어준다면 어떻게 될까요.


예제는 Use After Free Heap Overflow 알아보는 실습코드였습니다.
(_ _ )





'[ ★ ]Study > PWNABLE' 카테고리의 다른 글

[Tip] pwntool 함수 offset/plt/got 주소 찾기(pwntools)  (0) 2018.11.06
Double Free Bug(DFB)  (0) 2017.09.18
system call table 정리  (0) 2017.09.16
shellcode 만들기 2부  (0) 2017.09.16
shellcode 만들기 1부  (2) 2017.09.16

댓글