Post

UAF, Use After Free

* Integer overflow와 연계해 reference counter를 overflow시켜 0으로 만들어 강제로 free()시키는 방법으로 사용할 수도 있다.

#1

free()된 영역을 참조하는 경우. 보통 free()하면 fd/bk/last\_size 부분만 초기화되고 나머지 영역은 그대로 남아있기 때문에 나머지 영역에 있는 데이터를 leak할 수 있다. 이 때 puts()같은 문자열 함수를 사용해 처음부터 출력하면 \x00까지만 읽어 fd 첫 바이트가 \x00인 경우 아무것도 출력되지 않으므로 주의.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(){
void \*old\_p = malloc(32);
void \*new\_p;
strcpy(old\_p, "aaaabbbbccccddddeeeeffffgggg");
free(old\_p);


new\_p = malloc(32);
puts(&new\_p[8]);


return 0;
}

1
2
3
ccccddddeeeeffffgggg

#2

function pointer를 사용하는 경우(e.g., old->funcptr) function pointer 부분이 다른 값으로 변경되면 코드를 실행하는 취약점으로 연결될 수도 있다.

free(old)이후 c new = malloc()으로 같은 chunk 또는 old가 있던 영역의 chunk를 반환 받았을 때, chunk에 old를 이용해 접근하는 경우도 포함한다.

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
#include <stdio.h>
#include <stdlib.h>

  

void some\_func(){ }

  

typedef struct \_vul\_st{
int i;
void (\*fp)();
}vul\_st;

  

int main(){
vul\_st \*st = malloc(32);
char \*new\_p;


st->i = 0x1234;
st->fp = some\_func;
free(st);


new\_p = malloc(32);

  

memcpy(new\_p, "\x01\x01\x01\x01\x01\x01\x01\x01 \
\x41\x42\x43\x44\x00\x00\x00\x00", 16);
printf("%p is st->fp\n", st->fp);
st->fp();


return 0;
}

1
2
3
4
5
6
7
8
$ strace -if ./uaf
....
[00007f67a7f3a710] write(1, "0x4342412020202020 is st->fp\n", 290x4342412020202020 is st->fp
) = 29
[00000000004006b6] --- SIGSEGV {si\_signo=SIGSEGV, si\_code=SI\_KERNEL, si\_addr=0} ---
[????????????????] +++ killed by SIGSEGV +++
Segmentation fault

This post is licensed under CC BY 4.0 by the author.