JWT Vulnerabilities (Json Web Tokens)
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
If you are interested in 해킹 경력 and hack the unhackable - we are hiring! (유창한 폴란드어 필기 및 구사 필요).
Part of this post is based in the awesome post: https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology Author of the great tool to pentest JWTs https://github.com/ticarpi/jwt_tool
Run jwt_tool with mode All Tests!
and wait for green lines
운이 좋다면 도구가 웹 애플리케이션이 JWT를 잘못 확인하는 경우를 찾을 것입니다:
그런 다음, 프록시에서 요청을 검색하거나 jwt_ tool을 사용하여 해당 요청에 사용된 JWT를 덤프할 수 있습니다:
You can also use the Burp Extension SignSaboteur to launch JWT attacks from Burp.
서명은 그대로 두고 데이터를 변조하여 서버가 서명을 확인하는지 확인할 수 있습니다. 예를 들어 사용자 이름을 "admin"으로 변경해 보세요.
JWT의 서명이 검증되는지 확인하려면:
오류 메시지가 검증이 진행 중임을 나타냅니다; 자세한 오류에서 민감한 세부정보를 검토해야 합니다.
반환된 페이지의 변경도 검증을 나타냅니다.
변경이 없으면 검증이 없음을 나타냅니다; 이때 페이로드 클레임을 변조해 볼 수 있습니다.
토큰이 서버 측에서 생성되었는지 클라이언트 측에서 생성되었는지를 확인하기 위해 프록시의 요청 기록을 검토하는 것이 중요합니다.
클라이언트 측에서 처음 보이는 토큰은 키가 클라이언트 측 코드에 노출될 수 있음을 시사하며, 추가 조사가 필요합니다.
서버 측에서 발생한 토큰은 안전한 프로세스를 나타냅니다.
토큰이 24시간 이상 지속되는지 확인하세요... 아마도 만료되지 않을 수도 있습니다. "exp" 필드가 있다면 서버가 이를 올바르게 처리하는지 확인하세요.
사용된 알고리즘을 "None"으로 설정하고 서명 부분을 제거하세요.
Burp 확장 기능 "JSON Web Token"을 사용하여 이 취약점을 시도하고 JWT 내부의 다양한 값을 변경하세요 (요청을 Repeater로 보내고 "JSON Web Token" 탭에서 토큰의 값을 수정할 수 있습니다. "Alg" 필드의 값을 "None"으로 설정할 수도 있습니다).
알고리즘 HS256은 비밀 키를 사용하여 각 메시지에 서명하고 검증합니다. 알고리즘 RS256은 개인 키를 사용하여 메시지에 서명하고 인증을 위해 공개 키를 사용합니다.
알고리즘을 RS256에서 HS256으로 변경하면 백엔드 코드는 공개 키를 비밀 키로 사용하고 HS256 알고리즘을 사용하여 서명을 검증합니다.
그런 다음 공개 키를 사용하고 RS256을 HS256으로 변경하여 유효한 서명을 생성할 수 있습니다. 이를 실행하여 웹 서버의 인증서를 검색할 수 있습니다:
공격자는 토큰의 헤더에 새로운 키를 삽입하고 서버는 이 새로운 키를 사용하여 서명을 검증합니다 (CVE-2018-0114).
이 작업은 "JSON Web Tokens" Burp 확장을 사용하여 수행할 수 있습니다. (요청을 Repeater로 보내고, JSON Web Token 탭에서 "CVE-2018-0114"를 선택한 후 요청을 보냅니다).
지침은 "jku" 헤더 클레임을 사용하는 JWT 토큰의 보안을 평가하는 방법을 자세히 설명합니다. 이 클레임은 토큰 검증에 필요한 공개 키가 포함된 JWKS (JSON Web Key Set) 파일에 연결되어야 합니다.
"jku" 헤더로 토큰 평가:
"jku" 클레임의 URL을 확인하여 적절한 JWKS 파일로 연결되는지 확인합니다.
토큰의 "jku" 값을 수정하여 제어된 웹 서비스로 향하게 하여 트래픽을 관찰합니다.
HTTP 상호작용 모니터링:
지정한 URL로의 HTTP 요청을 관찰하면 서버가 제공된 링크에서 키를 가져오려는 시도를 나타냅니다.
이 프로세스에 jwt_tool
을 사용할 때는 테스트를 용이하게 하기 위해 개인 JWKS 위치로 jwtconf.ini
파일을 업데이트하는 것이 중요합니다.
jwt_tool
명령:
다음 명령을 실행하여 jwt_tool
로 시나리오를 시뮬레이션합니다:
선택적 헤더 클레임인 kid
는 특정 키를 식별하는 데 사용되며, 이는 여러 키가 존재하는 환경에서 토큰 서명 검증에 특히 중요합니다. 이 클레임은 토큰 서명을 검증하기 위해 적절한 키를 선택하는 데 도움을 줍니다.
헤더에 kid
클레임이 존재할 때, 해당 파일이나 그 변형을 웹 디렉토리에서 검색하는 것이 좋습니다. 예를 들어, "kid":"key/12345"
가 지정된 경우, 웹 루트에서 /key/12345 및 /key/12345.pem 파일을 검색해야 합니다.
kid
클레임은 파일 시스템을 탐색하는 데 악용될 수 있으며, 임의의 파일을 선택할 수 있는 가능성을 제공합니다. 특정 파일이나 서비스를 대상으로 kid
값을 변경하여 연결성을 테스트하거나 서버 측 요청 위조(SSRF) 공격을 실행할 수 있습니다. 원래 서명을 유지하면서 kid
값을 변경하기 위해 JWT를 조작하는 것은 jwt_tool에서 -T
플래그를 사용하여 수행할 수 있습니다.
By targeting files with predictable content, it's possible to forge a valid JWT. For instance, the /proc/sys/kernel/randomize_va_space
file in Linux systems, known to contain the value 2, can be used in the kid
parameter with 2 as the symmetric password for JWT generation.
If the kid
claim's content is employed to fetch a password from a database, an SQL injection could be facilitated by modifying the kid
payload. An example payload that uses SQL injection to alter the JWT signing process includes:
non-existent-index' UNION SELECT 'ATTACKER';-- -
This alteration forces the use of a known secret key, ATTACKER
, for JWT signing.
A scenario where the kid
parameter specifies a file path used within a command execution context could lead to Remote Code Execution (RCE) vulnerabilities. By injecting commands into the kid
parameter, it's possible to expose private keys. An example payload for achieving RCE and key exposure is:
/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&
jku는 JWK Set URL을 의미합니다. 토큰이 “jku” 헤더 클레임을 사용하는 경우, 제공된 URL을 확인하십시오. 이는 토큰을 검증하기 위한 공개 키를 포함하는 JWKS 파일이 있는 URL을 가리켜야 합니다. 토큰을 변조하여 jku 값을 모니터링할 수 있는 웹 서비스로 가리키게 하십시오.
먼저 새로운 개인 및 공개 키로 새로운 인증서를 생성해야 합니다.
그런 다음 예를 들어 jwt.io를 사용하여 생성된 공개 및 개인 키로 새로운 JWT를 만들고 jku 매개변수를 생성된 인증서로 지정할 수 있습니다. 유효한 jku 인증서를 만들기 위해 원본 인증서를 다운로드하고 필요한 매개변수를 변경할 수 있습니다.
공개 인증서에서 "e" 및 "n" 매개변수를 얻으려면 다음을 사용하십시오:
X.509 URL. PEM 형식으로 인코딩된 X.509(인증서 형식 표준) 공개 인증서 집합을 가리키는 URI입니다. 집합의 첫 번째 인증서는 이 JWT를 서명하는 데 사용된 인증서여야 합니다. 이후의 인증서는 각각 이전 인증서를 서명하여 인증서 체인을 완성합니다. X.509는 RFC 52807에 정의되어 있습니다. 인증서를 전송하려면 전송 보안이 필요합니다.
이 헤더를 귀하의 제어 하에 있는 URL로 변경해 보십시오 그리고 요청이 수신되는지 확인하십시오. 그런 경우 JWT를 변조할 수 있습니다.
귀하가 제어하는 인증서를 사용하여 새 토큰을 위조하려면 인증서를 생성하고 공개 및 개인 키를 추출해야 합니다:
그런 다음 예를 들어 jwt.io를 사용하여 생성된 공개 및 개인 키로 새로운 JWT를 만들고 x5u 매개변수를 생성된 .crt 인증서로 지정할 수 있습니다.
이 두 가지 취약점을 SSRF에 대해 악용할 수도 있습니다.
이 매개변수는 base64로 인코딩된 인증서를 포함할 수 있습니다:
공격자가 자체 서명된 인증서를 생성하고 해당 개인 키를 사용하여 위조된 토큰을 생성한 다음 "x5c" 매개변수의 값을 새로 생성된 인증서로 교체하고 다른 매개변수, 즉 n, e 및 x5t를 수정하면 본질적으로 위조된 토큰이 서버에 의해 수락될 것입니다.
JWT에 다음과 같은 시나리오처럼 내장된 공개 키가 있는 경우:
다음 nodejs 스크립트를 사용하면 해당 데이터에서 공개 키를 생성할 수 있습니다:
새로운 개인/공개 키를 생성하고, 새로운 공개 키를 토큰에 삽입한 후 이를 사용하여 새로운 서명을 생성하는 것이 가능합니다:
이 nodejs 스크립트를 사용하여 "n"과 "e"를 얻을 수 있습니다:
마지막으로, 공개 키와 개인 키 및 새로운 "n"과 "e" 값을 사용하여 jwt.io에서 임의의 정보를 가진 새로운 유효한 JWT를 위조할 수 있습니다.
일부 애플리케이션이 ES256을 사용하고 동일한 nonce를 사용하여 두 개의 jwt를 생성하는 경우, 개인 키를 복원할 수 있습니다.
여기 예시가 있습니다: ECDSA: 동일한 nonce를 사용할 경우 개인 키 노출 (SECP256k1 사용)
JTI (JWT ID) 클레임은 JWT 토큰에 대한 고유 식별자를 제공합니다. 이는 토큰이 재전송되는 것을 방지하는 데 사용될 수 있습니다. 그러나 ID의 최대 길이가 4(0001-9999)인 상황을 상상해 보십시오. 요청 0001과 10001은 동일한 ID를 사용할 것입니다. 따라서 백엔드가 각 요청마다 ID를 증가시키고 있다면, 이를 악용하여 요청을 재전송할 수 있습니다(각 성공적인 재전송 사이에 10000 요청을 보내야 함).
교차 서비스 릴레이 공격
일부 웹 애플리케이션이 토큰의 생성 및 관리를 위해 신뢰할 수 있는 JWT 서비스에 의존하는 것으로 관찰되었습니다. JWT 서비스에 의해 한 클라이언트를 위해 생성된 토큰이 동일한 JWT 서비스의 다른 클라이언트에 의해 수용된 사례가 기록되었습니다. 제3자 서비스를 통해 JWT의 발급 또는 갱신이 관찰되면, 동일한 사용자 이름/이메일을 사용하여 해당 서비스의 다른 클라이언트에 계정을 등록할 가능성을 조사해야 합니다. 그런 다음, 얻은 토큰을 대상으로 요청하여 수용되는지 확인하기 위해 재전송을 시도해야 합니다.
귀하의 토큰이 수용되면 심각한 문제가 발생할 수 있으며, 이는 모든 사용자의 계정을 스푸핑할 수 있는 가능성을 허용할 수 있습니다. 그러나 제3자 애플리케이션에 가입하는 경우 더 넓은 테스트에 대한 허가가 필요할 수 있으며, 이는 법적 회색 영역에 들어갈 수 있음을 유의해야 합니다.
토큰의 만료 확인
토큰의 만료는 "exp" 페이로드 클레임을 사용하여 확인됩니다. JWT가 종종 세션 정보 없이 사용되기 때문에 신중한 처리가 필요합니다. 많은 경우, 다른 사용자의 JWT를 캡처하고 재전송하면 해당 사용자를 가장할 수 있습니다. JWT RFC는 토큰의 만료 시간을 설정하기 위해 "exp" 클레임을 활용하여 JWT 재전송 공격을 완화할 것을 권장합니다. 또한, 이 값을 처리하고 만료된 토큰을 거부하는 관련 검사를 애플리케이션에서 구현하는 것이 중요합니다. 토큰에 "exp" 클레임이 포함되어 있고 테스트 시간 제한이 허용된다면, 토큰을 저장하고 만료 시간이 지난 후 재전송하는 것이 좋습니다. 타임스탬프 파싱 및 만료 확인(UTC의 타임스탬프 포함)을 포함한 토큰의 내용을 jwt_tool의 -R 플래그를 사용하여 읽을 수 있습니다.
애플리케이션이 여전히 토큰을 검증하는 경우 보안 위험이 존재할 수 있으며, 이는 토큰이 결코 만료되지 않을 수 있음을 의미할 수 있습니다.
해킹 경력에 관심이 있고 해킹할 수 없는 것을 해킹하고 싶다면 - 우리는 채용 중입니다! (유창한 폴란드어 필기 및 구술 필요).
AWS 해킹 배우고 연습하기:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 배우고 연습하기: HackTricks Training GCP Red Team Expert (GRTE)