티스토리 뷰

연습

WebGoat: Broken Authentication JWT Tokens

onaeonae1 2024. 4. 20. 20:32

JWT 에 대한 간단한 정리

기본 지식

세션과 토큰 그리고 JWT

자동 로그인?

  • 자동 로그인은 기본적으로 세션 혹은 토큰에 의해 이루어진다
  • 브라우저의 Cookie 혹은 localStorage 에 session, token 등이 저장, 로그인 여부 확인에 사용
  • Cookie 의 경우 HTTP Request 에서 Header에 포함되니깐 서버에서 Header 값으로 확인한다
  • 쿠키니깐 key, value, 유효기간 등이 존재하며, httpOnly를 하지 않았을` 경우 js 로 접근 가능함
    • 따라서, 인증 관련된 쿠키들의 경우 반드시 httpOnly 등을 처리해주어야 함
  • localStorage 나 cookie 중 뭐가 더 낫냐에 대해서는 확실히 모르겠다. 일단 난 쿠키 사용함
    • httpOnly 이런거로 막기도 쉽고 HTTP Header 에 들어가기 때문

세션

  • 세션은 서버의 DB에서 저장한다
  • 사용자 로그인에 대해 세션을 발급하고 HTTP Header 등으로 돌아올 때 이를 DB에서 대조
  • DB에서 유효할 시 로그인 처리를 해주고, 만료되었거나 유효한 값이 아니면 로그인 다시 하게 함

토큰

  • 세션은 서버의 DB에 저장된다는 문제점이 있다
  • 서버가 여러개 있는 경우에는 상당히 귀찮다(서버 여러 개 운영 시 세션 관리 구글링ㄱ)
  • token 은 DB에 부하를 거는 대신 SECRET_KEY를 사용해서 유효를 판단
  • 즉 DB에 세션을 저장하지 않고, 마구 발급하며, 이게 정해진 SECRET_KEY로 풀리는지만 판단
  • 추상적인 개념상 토큰은 위와 같고 구체적인 것은 JWT이다. JWT를 알아보자.

JWT : Json Web Token

위에서 말한 "토큰" 의 좀 더 구체적인 개념이라고 생각하면 된다

[header].[payload].[signature] 로 구성됨

Header

header에서는 암호화 알고리즘이 정의됨(json 형태)

암호화 알고리즘은 SHA256 등 Hash 기반→ SECRET_KEY가 있어야 decode 가능!

참고로 RS256 도 있으니 추가 공부하면 좋다

Payload

구성

  • json 형태의 key, value 들

역할

  • 인증에 사용할 사용자의 정보(이름, id 등)

Signature

구성

  • header, payload를 암호화 알고리즘(Header에서 정의된) + SECRET_KEY로 암호화
  • 암호화 완료 후 base64 encode

역할

  • header, payload에 담긴 값이 변조를 거쳤는지 아닌지 verify 하는 역할
  • base64로 encode 되어 있어서 바로 decode 가능하지만 decode 된 내용도 암호화 된 결과임
  • header, payload를 변조해도 signature 에서 걸릴 수 있음. (Secret Key 가 털리지 않았다면)

특징

header, payload, signature 모두 base64URL 로 encode 된 상태.

따라서, header, payload는 바로 base64에서 decode해 내용 확인 가능.

→ 바로 값을 확인할 수 있으므로 민감한 정보는 안담아둠

→ 변조의 위험성이 있음(alg: "none")

→ 변조 여부 파악 위해 header,payload(암호화 알고리즘 + SECRET_KEY) 로 암호화⇒ signature.

Q. Token이 탈취당한 경우?

토큰이 탈취당한 경우 세션과 동일하게 자격 증명을 속이고 들어올 수 있다.

따라서, 토큰의 유효기간을 짧게 설정한다.(iat)

대신 이 경우, 로그인을 아주 자주 해줘야 하는 번거로움이 존재한다.

이로 인해, access_token과 refresh_token으로 분리하여 처리한다.

  • access_token : 인증 정보 보관 목적. 유효 기간 짧음
  • refresh_token : 토큰 재발급 목적. 유효 기간 긺.

Q. access_token 과 refresh_token은 어떻게 작동하는가?

  • access_token으로 접근.
  • 만료시 access_token과 refresh_token을 동시에 서버에 제출.
  • access_token을 통해 사용자 정보를 확인하고 refresh_token을 verify 해서 재발급 여부를 결정.
  • 조건을 만족하면 재발급.

문제 해결

WebGoat 으로 가보자

#4. JWT Signing

header의 알고리즘을 none으로 바꾸고 payload의 값을 원하는 대로 변경 signature를 공백으로 남겨두면 공격 가능

#5. JWT Cracking

SECRET_KEY를 취약하게 설정할 경우 hashcat과 같은 도구들로 crack 가능

해시캣에 사용할 워드리스트는 이걸 사용하면 됨

payload의 값을 원하는 대로 변조한 후 hashcat으로 SECRET_KEY를 crack.

워싱턴!

 

SECRET_KEY 파악 후 jwt.io 에서 해당 값 대입해서 JWT 생성 후 request.

해당 문제를 통해 알 수 있는건 유추 가능한 SECRET_KEY를 사용 자제.

#7. Refreshing a token

  • access_token과 refresh_token의 목적은 서로 다름.
    • access_token은 사용자 정보 확인, 실제 인증에 사용됨
    • refresh_token은 access_token 재발급

그래서 access_token은 다음과 같이 재발급함

  1. 만료된 access_token 에서 사용자 정보를 파악 (user id 등)
  2. refresh token을 검증해 사용자 정보에 대응하는 access_token을 재발급

이때 refresh_token에 대한 검증이 확실하지 않은 경우 다음과 같은 문제 발생 가능.

  1. 만료된 다른 사용자의 access_token이 노출됨
  2. 공격자의 refresh_token이 존재함.
  3. 새 토큰을 발급받는 엔드포인트 등에 1, 2를 각각 보냄.
  4. 공격자는 다른 사용자의 자격 증명을 획득가능

 

로그를 통해 만료된 다른 사용자 "Tom" 의 access_token 이 노출됨

 

 

해당 Access Token 과 Refresh Token 으로 재발급 요청 후 발급받음

 

 

 

다른 사용자의 자격증명으로 요청에 성공

#8. Final Challenges

SECRET_KEY를 하나만 사용하는 경우 노출시 매우 위험해짐. 이를 위해서 여러가지를 DB에 저장 후 사용하면서 위험도를 줄일 수 있다.

본 문제의 경우 header의 kid를 통해서 SECRET_KEY에 접근. encdoe-decode에서 그 SECRET_KEY를 사용하고 있다.

이때 kid의 값으로 SQL Injection이 발생할 수 있다.

 

delete 명령을 보냈을 때 전달되는 token의 header 가 기존 방식과는 다름

 

소스 코드를 확인해본 결과 kid 부분에서 SQL Injection 발생함.

원래 값인 webgoat_key 뒤에 SQL Injection.

원래 webgoat_key에 해당하는 SECRET_KEY를 DB에서 조회하는 방식이므로 이를 변조.

변조 목적으로 기존 결과 UNION으로 원하는 SECRET_KEY 값인 'mykey'를 base64 인코딩

이제 SECRET_KEY는 'mykey'로 접근 가능함

 

payload 에서 exp 를 변조, 그리고 문제대로 username 변조

 

SECRET_KEY 로 SQL Injection 으로 변조한 mykey를 대입

 

 

생성된 JWT를 delete 요청의 Token 으로 전송

 

공격에 성공!!

 

 

'연습' 카테고리의 다른 글

프로그래머스 등굣길  (0) 2024.04.17
토익스피킹 빠르게 고득점 하는 방법  (0) 2024.03.29
docker-compsoe 업그레이드하기  (1) 2022.09.16
[Django] testcase 사용하기  (0) 2022.08.16
vscode remote ssh 막힐때  (0) 2022.08.08
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함