Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

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

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

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

도구 디렉토리

카테고리

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

cve-2026-85706

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

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

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. 취약 랩 구동 (자세한 내용은 lab/README.md 참조)
cd lab && docker compose up -d      # GitLab이 정상 상태가 될 때까지 약 5분 대기

# 2. 비파괴적 탐지
../poc/detect.sh http://localhost:8929

# 3. 자신의 랩에서 읽을 권한이 있는 파일에 대한 파일 읽기 PoC
../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.와 제휴하거나 승인받지 않았다.

도구 다운로드