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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
cve-2026-85706 — GitLab CE/EE의 Workhorse 경로 인코딩 우회를 통한 인증되지 않은 임의 파일 읽기 취약점인 CVE-2026-85706에 대한 Python PoC 익스플로잇으로, 분석 글과 우회 변형을 포함합니다. | Kitploit
도구/GitHubGitHub/guneykabel/cve-2026-85706
Vulnerability AnalysisExploitationWeb Application ExploitationInformation GatheringSecurity VirtualizationWeb SecurityPenetration Testing
GitHubguneykabel/cve-2026-85706

cve-2026-85706

GitLab CE/EE의 Workhorse 경로 인코딩 우회를 통한 인증되지 않은 임의 파일 읽기 취약점인 CVE-2026-85706에 대한 Python PoC 익스플로잇으로, 분석 글과 우회 변형을 포함합니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

cve-2026-85706

GitLab CE/EE의 인증되지 않은 임의 로컬 파일 읽기 취약점. 18.7–19.1.7, 19.2.0–19.2.5, 19.3.0–19.3.1 버전에 영향을 미친다. 19.1.8 / 19.2.6 / 19.3.2에서 수정됨 (2026-09-10). CVSS 10.0, 실제 공격에서 악용된 것으로 보고됨. 최초 보고는 s3ntago가 했으며 이 저장소는 단지 나의 분석 글 + PoC일 뿐이다.

면책 조항

이 PoC는 교육 및 방어적 연구 목적으로만 공개되었으며, 관리자와 연구자가 취약점을 이해하고 테스트하는 데 도움을 주기 위한 것이다. 소유한 시스템 또는 테스트에 대한 명시적 서면 승인을 받은 시스템에만 실행하라. 당신의 인스턴스가 영향을 받는 범위에 해당한다면 읽기를 멈추고 먼저 19.1.8 / 19.2.6 / 19.3.2로 패치하라.

작동 방식

세 개의 저장소 엔드포인트(POST :id/repository/commits, POST/PUT :id/repository/files/:file_path)가 Workhorse의 requestBodyUploader 뒤에 위치한다. Rails 핸들러는 원시 file.path 요청 필드에서 디스크 상의 경로를 그대로 읽어들이고, 인증이 이루어지기 전에 File.open을 호출한다. require_gitlab_workhorse!는 인증 역할을 하지 못하는데, Workhorse의 서명 라운드트리퍼가 프록시하는 모든 요청에 유효한 JWT를 첨부하기 때문이며, 따라서 일반 API 프록시로 흘러 들어가는 모든 것은 이 검사를 통과한다.

Gitlab-Workhorse-Api-Request

이것이 모든 사람에게 즉각적인 LFI가 되지 않는 유일한 이유는 Workhorse가 먼저 요청을 재작성해야 하기 때문이다. 그러나 Workhorse의 라우트 정규식은 이스케이프된 경로(EscapedPath()와 결코 %XX를 디코딩하지 않는 path.Clean 복제본)에 대해 매칭되는 반면, Puma는 Grape 라우팅 전에 %XX를 디코딩한다. 따라서 정적 세그먼트의 아무 문자나 퍼센트 인코딩하거나(%63ommits, %72epository, %66iles), 후행 슬래시를 추가하거나, .json을 붙이면 Workhorse의 정규식이 놓치지만 Rails는 여전히 취약한 핸들러로 라우팅한다. 이 인코딩 불일치가 바로 우회의 핵심이다. (//, /./, %2F, ; 같은 변형은 작동하지 않는데, path.Clean이 처음 두 개를 정규화하고 Puma가 %2F를 거부하기 때문이다.)

그런 다음 위조된 서명 없는 업로드 메타데이터를 쿼리 파라미터로 전송하면 된다:

root@kitploit:~
POST /api/v4/projects/1/repository/%63ommits?file=&file.path=<ABSOLUTE_PATH>&file.size=1&Content-Type=application/x-www-form-urlencoded

file=을 비워두면 requires :file, WorkhorseFile 검증을 만족시킨다(빈 값은 nil로 강제 변환됨). 읽기는 인증 전에 발생한다. 바이트를 되돌려 받는 것이 재미있는 부분이다: urlencoded 분기에서 헬퍼는 Rack::Utils.parse_nested_query(File.read(path))를 실행하고 파서 오류를 400 응답 본문에 보간한다. 두 개의 16진수 숫자가 뒤따르지 않는 %는 InvalidParameterError: invalid %-encoding (<raw file bytes>)를 발생시키며, 파일 내용이 오류 메시지 안에 담겨 돌아온다. JSON 분기(Oj)는 아무것도 유출하지 않으며, 이것이 여기서 urlencoded 콘텐츠 타입이 중요한 이유이다.

수정 사항(master 0d9ce3e7, 백포트 1fe30154 / b43c8b26 / 0ff7b6b2)은 세 엔드포인트 모두에 authenticate!를 추가하고 /authorize 사전 단계를 더하며, 경로/크기에 대해 미들웨어가 생성한 UploadedFile만 신뢰하고, 파서 오류를 에코하는 것을 중단한다. 버그는 2025년 12월에 도입되었으며, 이것이 영향을 받는 범위가 18.7에서 시작하는 이유이다.

사용법

root@kitploit:~
./exploit.py --url http://localhost:8080 --file /etc/hostname
./exploit.py --url http://localhost:8080 --file /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml

이 스크립트는 검증된 모든 우회 형태(인코딩된 세그먼트, 후행 슬래시, .json; commits + files 엔드포인트, POST 및 PUT)를 순환하며 각 응답을 분류하여 체인의 어느 지점에서 프로브가 실패했는지 알 수 있게 해준다. 물론 승인된 대상에만 사용하라.

결함 / 한계 / 사전 조건

  • 에코는 파일에 두 개의 16진수 문자가 뒤따르지 않는 %가 포함된 경우에만 발생한다.
  • 유출 정규식은 탐욕적이다(본문의 마지막 )까지 (.*)). 기본 JSON 오류에 대해서는 문제없지만, 앞단의 무언가가 응답을 HTML로 감싸면 과도하게 캡처할 것이다. 올바른 수정은 JSON 메시지 필드를 파싱하는 것이다.
  • Commits API는 익명으로 읽을 수 있는 프로젝트 id가 필요하다(그렇지 않으면 before 블록이 404를 반환한다).

참고 자료

  • 수정 커밋 (master): https://gitlab.com/gitlab-org/gitlab/-/commit/0d9ce3e758a85f0690be751e213625f7902c0361
  • 패치 릴리스 노트: https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-3-2-released/
  • 분석 글: https://securityonline.info/gitlab-vulnerabilities-cve-2026-85706-cvss-10/
도구 다운로드