반응형

JSON Web Token(JWT) 관련 문제를 풀어보았습니다.

우선, JWT란 사용자와 서버간에 안전하고 신뢰할 수 있는 정보를 전달할 수 있는 토큰 값입니다.

주로, 회원 인증이나 안전하게 정보를 전달할 경우 사용되는데, 전달되는 정보들이 sign(서명)되기 때문에 탈취/변조되지 않았는지 판단할 수 있기 때문입니다.

 

문제에 들어가면, 로그인 폼이 나오는데, 여기서 Admin 계정을 탈취하는게 목표입니다.

[Login as Guest!] 버튼을 클릭해봅니다.

 

쿠키 값으로 jwt 값이 전송되는 것을 확인할 수 있습니다.

 

jwt 값은 1. 헤더(Header), 2.정보(Payload), 3.서명(Signature) 값으로 분리되는데, 각각을 BASE64로 인코딩해서 "."으로 구분한 후 전송합니다.

위 스크린샷의 jwt 값을 예로 들으면

이렇게 나뉘어 집니다. 

https://jwt.io/ << 여기에서 jwt 값을 디버깅하고 검증 및 생성할 수 있습니다.

 

헤더(Header)에서는 토큰의 타입(JWT), 해싱 알고리즘(HMAC SHA256 / RSA 등...)을 정의하고 있습니다.

정보(Payload)에서는 전송할 정보 데이터를 담고 있으며,,

서명(Signature)에서 헤더의 인코딩 값과, 정보의 인코딩 값을 합친 후 비밀키로 해싱하여 생성합니다.

 

저는 이 문제를 단순히 정보(payload) 부분의 "guest"를 "admin"으로 변조한 후 전송하면 된다고 생각했습니다.

그래서 PAYLOAD 부분을 admin으로 변조하여 생성된 값을 guest 로 로그인 시 전송되는 jwt 쿠키 값에 삽입해보았습니다.

 

그랬더니... 서명값에 오류가 있다고 출력되더라고요. 

비밀키를 모르는데 어떻게 변조를 하지 고민하다가 구글링으로 JWT Attack 케이스를 발견하였습니다.

 

CASE1. 중요 정보 노출(이거는 jwt.io로 디버깅/BASE64로 디코딩 했을 때 노출되는 정보들..)

CASE2. algorithm 값이 none

CASE3. algorithm 변조(RS256 to HS256)

CASE4. HS256 key Cracking

 

이렇게 4가지 케이스가 있더라고요. 저는 CASE2 방법을 이용해보았습니다.

헤더(Header) 부분의 alg 값을 none으로 변조하고, 서명(Signature) 값을 제거한 후 전송하는 방법입니다.

 

즉, 위와 같이 인코딩한 값을 [Header + "." + Payload + "."] 서명 값 없이 서버로 전송하였더니,

※ 참고로 jwt 값은 공백과 엔터 없이 BASE64로 인코딩되어야 하며, 인코딩 시 뒤에 패딩 문자(=, ==)는 제거해서 전송

 

Admin 권한을 획득할 수 있었습니다!!


참고자료

EN - Hacking JSON Web Token (JWT) - Rudra Pratap.pdf
0.30MB

 

문제되는 경우 삭제 처리 하겠습니다...

반응형

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

[root-me] Remote File Inclusion  (0) 2020.01.08
[root-me] PHP - assert()  (0) 2020.01.02
[root-me] XPath injection - authentication  (0) 2019.07.25
[root-me] SQL Truncation  (0) 2019.07.18
[root-me] CRLF  (0) 2019.07.18

+ Recent posts