JWT란?

JWT(Json Web Token)는 시스템 간에 암호화된 JSON 데이터를 전송하기 위한 표준화된 형식이다. 기존 세션과 달리 서버에 필요한 모든 데이터는 JWT 자체에 클라이언트 측에 저장한다.

JWT 형식

JWT는 헤더(Header), 페이로드(Payload), 시그니처(Signature) 세 부분으로 구성된다.

eyJraWQiOiI5...  ←헤더
.
eyJpc3MiOiJw...  ←페이로드
.
SYZBPIBg2CR...   ←시그니처

헤더와 페이로드는 Base64 인코딩된 JSON 이다. Burp Suite의 디코더를 사용해 쉽게 디코딩할 수 있다.

JWT vs JWS vs JWE

  • JWT는 단독으로 사용되지 않고, JWS(JSON Web Signature) 또는 JWE(JSON Web Encryption)로 확장됨
  • 보편적으로 “JWT”라고 하면 JWS 토큰을 의미함

세션 기반 인증 vs JWT 인증

세션 기반 인증

  1. 로그인 정보 전송
  2. 서버에서 인증 성공 시 세션 생성 → DB/Redis에 저장
  3. 세션 ID가 포함된 쿠키를 클라이언트에 전송
  4. 이후 모든 요청에 세션 쿠키 포함

JWT 인증

  1. 로그인 정보 전송
  2. 서버에서 인증 성공 시 헤더+페이로드를 비밀키로 해싱 → 시그니처 생성
  3. 헤더 + 페이로드 + 시그니처 조합 → JWT 생성 후 클라이언트 전송
  4. 이후 모든 요청에 JWT 포함 → 서버에서 유효성 검증

JWT 공격이란?

공격자가 아래 방법으로 임의의 값을 가진 유효한 토큰을 생성할 수 있음:

  • 서명 미검증으로 인한 페이로드 변조
  • 비밀키 탈취/추측/브루트포싱

생성한 토큰으로 권한 상승, 계정 탈취, 서버 장악으로 이어질 수 있음.


실습 1: 서명 미검증 JWT 인증 우회

시나리오: 서버가 수신하는 JWT의 서명을 확인하지 않는다.

공격 과정

  1. wiener 계정으로 로그인
  2. JWT 토큰의 헤더와 페이로드 확인 (Base64 디코딩)
    • 알고리즘: RS256
    • sub 클레임: wiener
  3. JWT Tool로 sub 값을 administrator로 변조
python3 jwt_tool.py [Token] -I -pc sub -pv administrator
 
# 옵션 설명
# -I: Interactive mode (페이로드 수정 모드)
# -pc sub: 수정할 클레임 지정 (sub)
# -pv administrator: 새로운 값 설정
  1. 변조된 토큰으로 /admin 접근 → 성공

핵심: 서명 검증을 하지 않으면 페이로드를 변조해도 토큰이 유효한 것으로 처리됨


실습 2: alg:none 공격 (결함이 있는 서명 확인)

시나리오: 서버가 서명되지 않은 JWT(alg: none)를 허용하도록 잘못 구성되어 있다.

공격 과정

  1. wiener 계정으로 로그인
  2. JWT Tool로 subadministrator로 수정하고 알고리즘을 none으로 변경
python3 jwt_tool.py [Token] -I -pc sub -pv administrator -X a
 
# -X a: alg:none 공격 수행
  1. none 알고리즘 토큰으로 /admin 접근 → 성공

핵심: alg: none은 “서명 없음”을 의미한다. 서버가 이를 허용하면 시그니처 없이도 인증 우회가 가능하다.


관련 Dreamhack 문제

jwt web-hacking authentication portswigger