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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-40176 — CVE-2026-40176에 대한 차등 개념 증명으로, 악성 저장소 URL을 통해 Composer의 Perforce 드라이버에서 OS 명령 삽입을 보여주며, 영향을 받는 버전과 패치된 버전에 대한 자동 A/B 테스트를 포함합니다. | Kitploit
도구/GitHubGitHub/ikarolaborda/cve-2026-40176
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingCommand and ControlLearning & Education
GitHubikarolaborda/cve-2026-40176

CVE-2026-40176

CVE-2026-40176에 대한 차등 개념 증명으로, 악성 저장소 URL을 통해 Composer의 Perforce 드라이버에서 OS 명령 삽입을 보여주며, 영향을 받는 버전과 패치된 버전에 대한 자동 A/B 테스트를 포함합니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-40176 — Composer Perforce 드라이버 명령 주입 (개념 증명)

자체 포함된 OOP 스타일 PHP 개념 증명으로, Composer의 Perforce 저장소 드라이버에서 명령 주입 취약점을 시연하고 차등 검증합니다.

PoC는 동일한 악성 composer.json을 두 개의 Composer 바이너리(영향을 받는 **릴리스(2.9.5)**와 수정된 릴리스(2.9.6))에 대해 실행하여, 영향을 받는 버전에서만 실행되고 수정된 버전에서는 실행되지 않는 부작용(주입된 셸 명령으로 작성된 마커 파일)을 관찰함으로써 버그를 증명합니다.

⚠️ 인가된 보안 연구 및 방어 테스트 전용입니다. 책임 있는 사용을 참조하세요.


목차

  • 요약
  • 취약점
  • PoC 작동 방식
  • 주입 페이로드 설명
  • 요구 사항
  • 설정
  • 사용법
  • 예상 출력
  • 결과 해석
  • 프로젝트 구조
  • 설계 노트
  • 제한 사항 및 알려진 문제
  • 책임 있는 사용
  • 참조

요약

CVECVE-2026-40176
구성 요소Composer — Perforce (perforce) 저장소/VCS 드라이버
클래스공격자가 제어하는 저장소 URL을 통한 OS 명령 주입
공격 표면type: perforce의 조작된 repositories 항목을 포함한 composer.json
영향 받는 버전Composer 2.9.5
수정된 버전Composer 2.9.6
트리거악성 매니페스트에 대한 의존성 해결/업데이트 (composer update)
영향Composer를 실행하는 머신에서 임의 명령 실행
PoC 언어PHP (단일 파일, 외부 종속성 없음)

취약점

Composer는 여러 버전 관리 시스템에서 패키지를 해결할 수 있습니다. Perforce의 경우 호스트, 포트 및 사용자/스트림을 인코딩하는 p4:// URL로 저장소가 식별됩니다. Composer의 Perforce 드라이버가 기본 p4 명령줄을 구축할 때, 공격자가 제어하는 URL에서 가져온 필드가 셸에 전달되기 전에 충분히 삭제되지 않습니다.

매니페스트 작성자는 저장소 URL을 완전히 제어할 수 있으므로, 피해자가 악성 composer.json에 대해 composer update/composer install을 실행하도록 할 수 있는 공격자(예: 감염된 의존성, 적대적인 저장소, 신뢰할 수 없는 프로젝트 파일을 처리하는 CI 작업)는 의도된 p4 호출을 벗어나 Composer 프로세스의 권한으로 임의의 OS 명령을 실행할 수 있습니다.

이는 URL/브랜치/스트림 값이 이스케이프 없이 셸 명령으로 전달되는 기존 Composer VCS 드라이버 인수 주입 문제와 같은 계열에 속합니다. Composer 2.9.6은 Perforce 드라이버를 강화하여 주입된 페이로드가 더 이상 실행되지 않도록 합니다.

여기서 시연된 동작에 대한 권위 있는 설명은 PoC 소스 자체(CVE202640176Test.php)입니다. 업스트림 수정 사항에 대한 자세한 내용은 공식 권고 및 Comporter 변경 로그를 참조하십시오.


PoC 작동 방식

PoC는 단일 클래스 CVE202640176Test로, 제어된 A/B(차등) 실험을 수행합니다:

  1. 사전 점검 — 영향을 받는 (2.9.5) 및 수정된 (2.9.6) Composer 바이너리 모두에서 --version을 조회하고, 둘 중 하나라도 호출할 수 없으면 조기 종료합니다.
  2. 영향 받는 실행 (2.9.5)
    • 시스템 임시 경로 아래에 격리된 임시 디렉터리를 만듭니다.
    • repositories 섹션에 주입된 셸 페이로드를 포함하는 악성 p4:// URL이 있는 perforce 항목이 포함된 composer.json을 작성합니다.
    • 해당 디렉터리에서 composer update를 실행합니다.
    • 결과를 검증합니다.
  3. 수정된 실행 (2.9.6) — 패치된 바이너리에 대해 동일한 단계를 반복합니다.
  4. 복원 — finally 블록은 항상 프로젝트 디렉터리의 원래 composer.json을 복원합니다.
  5. 판정 — 영향을 받는 실행이 부작용을 보이고 수정된 실행이 그렇지 않은 경우에만 PASS를 출력합니다.

검증 ("악용"으로 간주하는 기준)

각 실행에 대해 validateRun()은 세 가지를 확인합니다:

검사 항목증명하는 내용
마커 파일이 존재하고 실행 ID를 포함함주입된 touch/echo 페이로드가 실제로 실행되었음 — 즉 명령 주입이 성공했음.
Composer 출력에 p4가 언급됨Perforce 드라이버 코드 경로에 도달했음(페이로드가 관련 없는 단계가 아닌 올바른 구성 요소에 의해 처리됨).
파싱된 Composer 버전이 예상과 일치함올바른 바이너리(2.9.5 대 2.9.6)가 실행되었음.

세 가지 모두 통과해야 실행이 "OK"입니다. 전체 테스트는 영향을 받는 실행이 OK이고 수정된 실행이 아닌 경우에만 통과합니다. 이는 실제 취약점이 나중에 패치되었음을 나타내는 정확한 신호입니다.


주입 페이로드 설명

악의적인 저장소 URL은 writeComposerJson()에서 생성됩니다:

root@kitploit:~
p4://127.0.0.1:1666:attacker_user;touch <marker> && echo '<runId>' > <marker>:client_test

분석:

  • p4://127.0.0.1:1666:attacker_user — 올바른 형식의 Perforce URL (호스트, 포트 1666, 사용자).
  • ;touch <marker> && echo '<runId>' > <marker> — 주입된 셸 명령입니다. 선행 ;는 의도된 p4 명령을 종료합니다. touch는 마커 파일을 생성하고 echo '<runId>' > <marker>는 고유한 실행 ID를 파일에 기록하여 PoC가 페이로드(관련 없는 프로세스가 아닌)가 파일을 생성했음을 확인할 수 있도록 합니다.
  • :client_test — URL 파싱이 그럴듯하게 유지되도록 하는 후행 텍스트입니다.

영향을 받는 드라이버에서는 셸 메타문자가 처리되어 마커 파일이 생성됩니다. 수정된 드라이버에서는 값이 적절하게 이스케이프/인용되므로 동일한 문자열이 비활성 데이터로 처리되어 마커가 나타나지 않습니다.

참고: PoC는 고유한 타임스탬프가 있는 실행 ID를 사용하고 격리된 임시 디렉터리 내부에 마커를 작성하므로 페이로드는 무해하고 자체 정리되며 파괴적이지 않습니다.


요구 사항

  • PHP 7.4+ (PHP 8.x CLI에서 개발/테스트). PoC 자체는 핵심 함수만 사용합니다 — 하네스를 실행하는 데 Composer 패키지가 필요하지 않습니다.
  • 두 개의 Composer 바이너리 (PHAR 형태로 제공):
    • Composer 2.9.5 (영향 받는 버전)
    • Composer 2.9.6 (수정된 버전)
  • POSIX 계열 셸 환경 (exec()는 cd … && php …를 실행합니다). Linux/macOS용으로 설계되었습니다.
  • 프로젝트 디렉터리에 기본 composer.json (시작 시 읽히고 각 임시 실행에 복사된 후 복원됨).

일반적으로 라이브 Perforce 서버가 필요하지 않습니다. 취약점은 Composer가 p4 명령줄을 구축하는 방식에 있으며, 주입된 페이로드는 실제 p4 연결 전/주변에서 실행됩니다. Composer는 Perforce 연결 오류를 기록할 수 있습니다. 이는 예상된 것이며 마커 파일 증명에 영향을 미치지 않습니다.


설정

  1. PoC를 작업 디렉터리에 복제/배치합니다.

  2. PoC와 동일한 디렉터리에 composer.json을 제공합니다. 최소한의 것으로 충분합니다:

    root@kitploit:~
    {
      "name": "research/cve-2026-40176-poc",
      "description": "CVE-2026-40176 차등 PoC용 기본 매니페스트",
      "require": {}
    }
    
  3. 두 개의 Composer 바이너리를 얻고 PoC가 예상하는 위치에 배치합니다(기본값은 다음과 같습니다):

    root@kitploit:~
    /usr/local/bin/composer-2.9.5.phar   # 영향을 받는 버전
    /usr/local/bin/composer-2.9.6.phar   # 수정된 버전
    

    공식 아카이브에서 특정 Composer 릴리스를 다운로드할 수 있습니다. 예:

    root@kitploit:~
    curl -Lo /usr/local/bin/composer-2.9.5.phar https://getcomposer.org/download/2.9.5/composer.phar
    curl -Lo /usr/local/bin/composer-2.9.6.phar https://getcomposer.org/download/2.9.6/composer.phar
    

    경로가 다른 경우 CVE202640176Test.php 하단의 두 생성자 인수를 편집하십시오.


사용법

root@kitploit:~
php CVE202640176Test.php

하네스는 두 Composer 버전을 차례로 실행하고 최종 판정을 출력합니다. 실행이 실패하더라도 원래 composer.json은 자동으로 복원됩니다(작업은 휘발성 임시 디렉터리에서 수행됨).


Docker에서 실행 (권장)

저장소는 정확한 환경을 복제하는 컨테이너화된 랩을 제공합니다: PHP CLI 런타임과 PoC가 예상하는 경로에 있는 두 개의 고정 Composer 릴리스, 런타임에 완전히 네트워크 격리됨.

root@kitploit:~
docker compose run --rm poc

이 명령은 cve-2026-40176-lab:latest를 빌드하고(빌드 중 Composer 2.9.5 및 2.9.6을 다운로드하고 각 --version을 확인) 권한이 없고 외부 송신이 없는 컨테이너 내에서 차등 테스트를 실행합니다.

랩이 보장하는 사항:

  • 실제 바이너리. 두 Composer 릴리스 모두 공식 아카이브에서 가져오며 빌드 시 버전이 확인됩니다. 고정된 버전을 사용할 수 없으면 빌드가 명시적으로 실패합니다.
  • 격리. poc 서비스는 internal 브리지 네트워크(호스트/인터넷 송신 없음)에서 실행되며, cap_drop: ALL 및 no-new-privileges가 설정됩니다. 주입 페이로드는 격리된 상태로 유지됩니다.
  • 호스트 설정 불필요. 호스트에 PHAR를 배치하거나 경로를 직접 편집할 필요가 없습니다.

빌드 인수를 통해 버전을 다시 고정할 수 있습니다(PoC의 두 생성자 경로와 동기화되어야 함):

root@kitploit:~
docker compose build --build-arg COMPOSER_AFFECTED_VERSION=2.9.5 --build-arg COMPOSER_FIXED_VERSION=2.9.6

선택 사항 — 라이브 Perforce 서버. full-lab 프로필에서 p4d 서비스를 사용할 수 있습니다(docker compose --profile full-lab up). 마커 기반 증명에는 필요하지 않습니다. 라이브 p4:// 엔드포인트를 원하는 연구자를 위해 존재합니다. PoC 페이로드는 127.0.0.1:1666을 대상으로 하므로 별도의 p4d 컨테이너를 통한 라우팅은 PoC URL을 호스트 p4d로 지정해야 합니다.


재현 상태 (관찰됨)

정직한 결과: 실제 게시된 Composer 2.9.5 및 2.9.6에 대해 PoC는 현재 실행되지 않으며, 랩은 INCONCLUSIVE / FAIL을 보고합니다.

영향을 받는 Composer (2.9.5)를 PoC의 악성 매니페스트에 대해 실행하면 Composer 내부에서 p4/셸 명령이 구축되기 전에 다음 오류가 발생합니다:

root@kitploit:~
In PerforceDriver.php line 40:
  [ErrorException]
  Undefined array key "depot"

PerforceDriver::initialize()는 가장 먼저 $this->repoConfig['depot']를 읽지만, PoC의 저장소 항목은 type과 url만 제공합니다("depot" 키 없음). 드라이버가 이 시점에서 중단되므로 URL의 주입된 ;touch <marker> 페이로드에 도달하지 못하고 마커가 생성되지 않습니다. 네트워크 격리가 원인이 아닙니다 — 완전한 송신이 있는 경우에도 동일한 오류가 발생합니다.

이것이 의미하는 바:

  • Docker 랩 자체는 올바르며 차등 하네스를 실제 영향/수정 바이너리에 대해 충실히 실행합니다. INCONCLUSIVE 결과는 PoC 페이로드의 속성이며 환경의 속성이 아닙니다.
  • 실제 Perforce 명령 구축 경로를 실행하려면 PoC의 저장소 구성에 최소한 depot 키(그리고 현실적으로 full-lab 프로필 아래의 라이브 p4d 엔드포인트)가 필요합니다. 페이로드를 해당 시점까지 정제하는 것은 "랩을 설정하는 것"을 넘어서는 익스플로잇 개발이며 의도적으로 여기서는 범위를 벗어납니다.

아래 "예상 출력"은 PoC의 의도된/이상적인 결과이며 참조용으로 유지됩니다. 현재 페이로드가 실제 드라이버에 대해 생성하는 결과가 아닙니다.


예상 출력

성공적인 시연은 대략 다음과 같습니다(경로 및 ID는 다를 수 있음):

root@kitploit:~
=== CVE-2026-40176 PoC started ===
- Composer 2.9.5 version: 2.9.5
- Composer 2.9.6 version: 2.9.6
Prepared temp dir: /tmp/cve20264176_5_20260610_142233
Written malicious composer.json to /tmp/cve20264176_5_20260610_142233
Running Composer in /tmp/cve20264176_5_20260610_142233…
- Parsed Composer version: 2.9.5
- Marker /tmp/cve20264176_5_.../poc_marker_5.txt created with expected ID.
- Output shows Perforce driver activity.
- Affected run exit code: 1
Prepared temp dir: /tmp/cve20264176_6_20260610_142233
Written malicious composer.json to /tmp/cve20264176_6_20260610_142233
Running Composer in /tmp/cve20264176_6_20260610_142233…
- Parsed Composer version: 2.9.6
✘ Marker file /tmp/cve20264176_6_.../poc_marker_6.txt not found.
- Output shows Perforce driver activity.
- Fixed   run exit code: 1

=== CVE-2026-40176 PoC finished ===
=== TEST RESULT: PASS (affected succeeded, fixed failed) ===

0이 아닌 Composer 종료 코드는 정상입니다. composer update는 결국 (가짜) 패키지를 가져오지 못합니다. 증명은 마커 파일이지 Composer의 종료 상태가 아닙니다.


결과 해석

결과의미
PASS (영향 받는 버전 성공, 수정된 버전 실패)확인됨: 2.9.5는 주입된 명령을 실행했고, 2.9.6은 실행하지 않았습니다. 취약점과 수정 사항이 모두 재현되었습니다.
INCONCLUSIVE / FAIL하나 이상의 검사가 일치하지 않았습니다. 실행별 ✓/✗ 줄을 검사하십시오: 잘못된 바이너리 경로, 버전 불일치, 영향 받는 마커 누락(환경/이스케이프 차이), 또는 수정된 실행이 예기치 않게 마커를 생성함.

결론이 나지 않은 결과의 일반적인 원인:

  • 드라이버가 PerforceDriver.php:40에서 Undefined array key "depot"로 중단됨 — 저장소 구성에 depot 키가 없어 Composer가 p4 명령 구축 경로에 도달하지 않음. 이것이 현재 페이로드가 실제 2.9.5/2.9.6에 대해 수행하는 동작입니다(재현 상태 참조).
  • Composer 바이너리 경로가 잘못되었거나 PHAR가 실제로 2.9.5/2.9.6이 아닙니다.
  • 호스트 셸 또는 PHP exec()가 샌드박싱/비활성화되었습니다.
  • Composer 출력에 문자열 p4가 포함되지 않음(드라이버 경로에 도달하지 않음).

프로젝트 구조

root@kitploit:~
CVE2026-40176/
├── CVE202640176Test.php   # PoC: CVE202640176Test 클래스 + 진입점
├── composer.json          # PoC가 런타임에 읽고 복원하는 기본 매니페스트
├── Dockerfile             # 랩 이미지: PHP CLI + 고정 Composer 2.9.5 및 2.9.6
├── docker-compose.yml     # `poc` 실행기 (+ full-lab 프로필 아래 선택적 `p4d`)
├── .dockerignore          # 빌드 컨텍스트 정리
├── README.md              # 이 파일
└── .gitignore             # 로컬 에이전트/도구 상태 제외

전체 PoC는 하나의 파일입니다:

  • __construct() — 두 바이너리 경로를 저장하고, 타임스탬프가 있는 실행 ID를 생성하며, 원래 composer.json의 스냅샷을 만듭니다.
  • run() — 사전 점검, 영향 받는 실행, 수정된 실행, 복원 및 판정을 조정합니다.
  • prepareTempDir() — 실행당 격리된 작업 디렉터리를 만듭니다.
  • writeComposerJson() — 주입된 p4:// URL로 악성 매니페스트를 만듭니다.
  • runComposer() — composer update를 실행하고(인수는 escapeshellarg()로 이스케이프) 출력 및 종료 코드를 캡처합니다.
  • validateRun() — 버전, 마커 파일 및 Perforce 드라이버 활동을 확인합니다.
  • preflightVersion() — 주어진 바이너리에서 --version을 읽습니다.

설계 노트

  • 격리 및 정리. 각 실행은 자체 임시 디렉터리를 사용합니다. 원래 composer.json은 결과에 관계없이 finally 블록에서 복원됩니다.
  • 하네스와 페이로드 이스케이프. 하네스는 자체 셸 인수를 escapeshellarg()로 이스케이프합니다(PoC가 실수로 자체 exec() 호출에 주입되지 않도록). 취약점은 한 단계 더 깊은 곳, 즉 Composer 자체가 p4 명령을 구축하는 방식에 있으며, 이것이 바로 페이로드가 대상으로 삼는 부분입니다.
  • 차등 증명. 취약한 바이너리와 패치된 바이너리를 한 번에 실행하면 모호함이 제거됩니다. 동일한 입력이 다른 동작을 생성하며, 이는 단일 긍정 관찰보다 훨씬 강력한 증거입니다.
  • 무해한 페이로드. 주입된 명령은 고유한 임시 마커에만 touch/echo하므로 PoC를 반복적으로 실행해도 호스트에 부작용이 없습니다.

제한 사항 및 알려진 문제

  • 하드코딩된 바이너리 경로. 두 PHAR 경로는 파일 하단에 인라인으로 전달됩니다. 환경에 맞게 편집하거나 CLI 인수/환경 변수에서 읽도록 리팩터링하십시오.
  • POSIX 가정. exec("cd … && php …") 패턴과 ;/&& 페이로드는 Unix 계열 셸을 가정합니다. Windows는 현재 지원되지 않습니다.
  • mkdir 경쟁 조건 / 권한. 임시 디렉터리는 모드 0777로 생성됩니다. 공유 환경에서 실행하는 경우 강화하십시오.
  • 버전 감지는 정규식 기반입니다. 출력에서 Composer X.Y.Z를 구문 분석합니다. 특이한 Composer 배너는 일치를 방해할 수 있습니다.

책임 있는 사용

이 저장소는 CVE-2026-40176을 이해하고 방어하기 위해 존재합니다.

  • 소유하고 있거나 명시적으로 테스트할 권한이 있는 시스템 및 Composer 설치에 대해서만 실행하십시오.
  • 방어자를 위한 핵심 내용: Composer를 2.9.6 이상으로 업그레이드하고, 격리 없이 신뢰할 수 없는 composer.json 파일(예: 타사 프로젝트 소스를 처리하는 CI 파이프라인)에 대해 composer install/update를 실행하지 마십시오.
  • 통제하지 않는 시스템에 대해 주입 기술을 사용하지 마십시오. 무단 악용은 불법이며 비윤리적입니다.

참조

  • Composer — 공식 프로젝트
  • Composer 릴리스 아카이브 (특정 2.9.5 / 2.9.6 PHAR 가져오기)
  • 공식 CVE-2026-40176 권고 및 Composer 2.9.6 변경 로그(배포판의 보안 추적기 / GitHub Advisory Database에서 권위 있는 수정 세부 정보 확인)
  • Composer VCS 드라이버 인수 주입 배경(동일한 취약점 클래스), 예: CVE-2021-29472

저자: Ikarolaborda · PoC 작성일: 2026-06-10.

도구 다운로드