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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
cve-2026-85706 — CVE-2026-85706에 대한 근본 원인 분석, 취약한 Docker 랩, 그리고 PoC 스크립트로, 파서 차이를 통해 GitLab에서 발생하는 인증되지 않은 임의 파일 읽기 취약점입니다. | Kitploit
도구/GitHubGitHub/0xenesbayram/cve-2026-85706
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingLearning & EducationLabs & Practice
GitHub0xenesbayram/cve-2026-85706

cve-2026-85706

CVE-2026-85706에 대한 근본 원인 분석, 취약한 Docker 랩, 그리고 PoC 스크립트로, 파서 차이를 통해 GitLab에서 발생하는 인증되지 않은 임의 파일 읽기 취약점입니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-85706 — GitLab 인증되지 않은 임의 파일 읽기

CVSS 10.0 · 인증 불필요 · 실제 악용 중 (CISA KEV)

GitLab Workhorse(Go 리버스 프록시)와 Puma/Grape(Ruby) 간의 파서 차이로 인해 인증되지 않은 공격자가 Workhorse의 가속 업로드 핸드오프를 우회하고, 공격자가 제어하는 file.path를 사용하여 세 개의 업로드 엔드포인트에 도달할 수 있으며, 이로 인해 GitLab 호스트에서 임의 파일 읽기가 가능합니다.

files의 한 문자를 %66iles로 인코딩하면 Workhorse의 업로드 라우트가 매치되지 않고 (Workhorse는 인코딩된 경로로 매칭함), Rails는 이를 다시 디코딩하여 실제 핸들러에 도달합니다(Rails는 디코딩된 경로로 라우팅함). 핸들러는 Workhorse가 덮어쓰기로 되어 있던 원시 file.path 파라미터를 신뢰하므로, file.path=/etc/passwd가 자격 증명 없이 디스크에서 읽힙니다.

root@kitploit:~
POST /api/v4/projects/1/repository/%66iles/x?file=&file.path=/etc/passwd&file.size=1
                                   ^^^^^^  Workhorse misses -> raw file.path survives to Rails

영향받는 버전 / 수정된 버전

버전
영향받음CE/EE 18.7 → 19.1.8, 19.2 → 19.2.6, 19.3 → 19.3.2
수정됨19.1.8 / 19.2.6 / 19.3.2 (2026-09-10)

이 저장소에 포함된 내용

경로내용
docs/ANALYSIS.md전체 근본 원인 분석 — 파서 차이, 두 개의 Workhorse JWT, 원시 file.path 신뢰 버그, 패치 diff, 그리고 반사된 오류를 통한 유출 채널. 실제 소스(v19.3.1-ee vs v19.3.2-ee)를 대상으로 분석.
lab/Docker 기반 취약 랩(gitlab-ce:19.3.1-ce.0) + 구동 안내.
poc/detect.sh (비파괴적 존재 확인 오라클) 및 exploit.sh (반사된 오류를 통한 파일 읽기). 단일 대상, 권한 부여 제한.

배경 — GitLab의 요청 파이프라인

GitLab 내부 구조에 익숙하지 않으신가요? 다음은 요청이 통과하는 순서대로 각 계층이 수행하는 작업입니다. 핵심 개념을 담은 더 자세한 용어집은 docs/ANALYSIS.md §0에 있습니다.

root@kitploit:~
  Internet
     │
     ▼
 ┌────────┐     ┌───────────┐     ┌────────┐     ┌──────────────────────┐
 │ NGINX  │────▶│ Workhorse │────▶│  Puma  │────▶│  Grape / Rails app  │
 │(proxy) │     │   (Go)    │     │ (Ruby) │     │      (Ruby)         │
 └────────┘     └───────────┘     └────────┘     └──────────────────────┘
구성 요소설명
NGINX최외곽 리버스 프록시. TLS를 종료하고, 정적 파일을 제공하며, 나머지 모든 것을 내부로 전달합니다. 이 취약점에 직접적으로 관여하지는 않습니다.
WorkhorseGitLab 전용 Go 리버스 프록시. 주된 역할은 Ruby가 느린 작업 — 특히 대용량 업로드 스트리밍 — 을 오프로딩하는 것입니다. 업로드 엔드포인트의 경우, Workhorse는 본문을 임시 파일로 버퍼링하고, JWT에 서명하고, file.path를 재작성하여 Ruby가 원시 업로드 바이트를 절대 보지 못하게 합니다. 또한 전달하는 모든 요청에 요청별 Gitlab-Workhorse-Api-Request JWT를 찍습니다("이것이 프록시를 통해 왔다"는 것을 증명하며, "이 사용자가 인증되었다"는 것이 아님).
PumaRails 앱을 실행하는 Ruby 애플리케이션 서버. Workhorse로부터 요청을 받아 미들웨어(Rack)를 실행하고 라우터로 디스패치합니다.
RackRuby 웹 서버 인터페이스 계층. Rack 미들웨어는 쿼리 문자열 파싱, 세션 관리, 그리고 여기서 결정적으로 Workhorse의 업로드 JWT 검증 및 UploadedFile 객체 생성을 처리합니다. Rack::Utils.parse_nested_query는 이 익스플로잇에서 오류 메시지가 파일 내용을 유출하는 함수입니다.
GrapeGitLab이 모든 /api/v4/* 엔드포인트에 사용하는 REST API 프레임워크. 라우트 정의와 require_gitlab_workhorse!(프록시 확인) 및 authenticate!(사용자 신원 확인)와 같은 before-filter를 제공합니다. Rails 내부, Puma 위, Workhorse 뒤에서 실행되므로 디코딩된 URL 경로를 봅니다.
Rails전체 웹 프레임워크(Ruby on Rails). GitLab은 Rails 모놀리스로, 모델, 서비스, 미들웨어가 모두 Puma 내부에서 실행됩니다.

이 취약점은 Workhorse(인코딩된 경로로 라우트를 매칭)와 Grape/Puma(디코딩된 경로로 라우팅) 사이의 간극에 존재합니다. 아래를 참조하세요.

메커니즘 요약

  1. 파서 차이. Workhorse는 r.URL.EscapedPath()(인코딩됨)로 라우트를 매칭하고, Puma/Grape는 디코딩된 경로로 라우팅합니다. Workhorse에게 %66iles ≠ 정규식 files이지만, Rails에게는 files로 디코딩됩니다.
  2. 핸드오프 건너뜀. 업로드 라우트가 매치되지 않았기 때문에, Workhorse는 본문을 임시 파일로 버퍼링하지 않고, file.path를 서명된 임시 경로로 재작성하지 않으며, Gitlab-Workhorse-Multipart-Fields 헤더를 설정하지 않습니다 — 하지만 여전히 요청을 프록시합니다(유효한 Gitlab-Workhorse-Api-Request JWT와 함께).
  3. 인증 누락 + 원시 파라미터 신뢰. 엔드포인트에 authenticate!가 없었고, 핸들러는 Workhorse가 검증하고 경로가 제한된 params[:file] UploadedFile 대신 params['file.path'] (공격자의 문자열)를 직접 읽었습니다.
  4. 오류 메시지를 통한 유출. 내용은 Rack::Utils.parse_nested_query 오류 문자열 ("invalid %-encoding (<file bytes>)")을 통해 유출됩니다 — 응답은 첫 번째 잘못된 %까지의 파일 바이트를 반사합니다.

패치는 authenticate!를 추가하고, 검증된 UploadedFile로 전환하며, e.message 반사를 중단합니다. docs/ANALYSIS.md §5를 참조하세요.

빠른 시작

root@kitploit:~
# 1. Stand up the vulnerable lab (see lab/README.md for details)
cd lab && docker compose up -d      # wait ~5 min for GitLab to become healthy

# 2. Non-destructive detection
../poc/detect.sh http://localhost:8929

# 3. File-read PoC against a file you're authorized to read on your own lab
../poc/exploit.sh http://localhost:8929 /var/opt/gitlab/gitlab-rails/etc/gitlab.yml

⚠️ 책임 있는 사용

이것은 방어 및 교육 목적으로 공개되었습니다: CISA KEV 목록에 있는 공개되고 패치된 CVE를 이해하고, 탐지하고, 패치하기 위함입니다. 여기의 스크립트는 단일 대상이며 대상을 명시적으로 전달해야 합니다.

  • 소유하거나 테스트 권한을 명시적으로 부여받은 시스템에만 실행하세요.
  • 랩은 localhost에서 실행되도록 설계되었습니다. 제3자 호스트를 향하게 하지 마세요.
  • 컴퓨터 시스템에 대한 무단 접근은 대부분의 관할권에서 불법입니다.

GitLab을 운영 중이라면, 수정된 버전으로 업그레이드하세요 — 그것이 유일한 실질적 해결책입니다.

참고 자료

  • watchTowr — Rapid Reaction: GitLab Path Traversal (CVE-2026-85706)
  • Nuclei Templates — PR #17231
  • 기본 소스 diff: gitlab-org/gitlab @ v19.3.1-ee vs v19.3.2-ee

라이선스

MIT — 분석 및 PoC 코드에만 해당. GitLab은 GitLab Inc.의 상표이며, 이 저장소는 GitLab Inc.와 제휴하거나 보증받지 않았습니다.

도구 다운로드