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
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
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
#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
$ 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.