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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
cve-2026-69243-poc-aiohttp-smuggling — 거부된 WebSocket 업그레이드를 통한 aiohttp CWE-444 요청 스머글링을 재현하며, 프록시 접근 제어 우회를 시연하는 Python/Rust 페이로드 및 Docker 랩을 포함합니다. | Kitploit
도구/GitHubGitHub/jvbotelho/cve-2026-69243-poc-aiohttp-smuggling
Payload GenerationVulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityFuzzing
GitHubjvbotelho/cve-2026-69243-poc-aiohttp-smuggling

cve-2026-69243-poc-aiohttp-smuggling

거부된 WebSocket 업그레이드를 통한 aiohttp CWE-444 요청 스머글링을 재현하며, 프록시 접근 제어 우회를 시연하는 Python/Rust 페이로드 및 Docker 랩을 포함합니다.

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기웹사이트
116일 전아직 검토되지 않음

CVE-2026-69243 — aiohttp 요청 스머글링 (CWE-444)

aiohttp < 3.14.2에서 거부된 WebSocket 업그레이드를 통한 요청 스머글링. 역방향 프록시가 Connection: Upgrade + Upgrade: websocket 헤더를 전달하면, 취약한 aiohttp 파서는 요청 본문을 건너뛰고 후행 바이트를 파이프라인된 요청으로 해석하여 에지 접근 제어를 우회합니다.

aiohttp 3.14.2에서 수정됨 (커밋 6ae358f).

저자: João Victor Botelho (JV Botelho) — https://glitchedcat.com

60초 실행

Python 버전을 복사하여 붙여넣으세요 (의존성 없음, 표준 라이브러리만 사용):

root@kitploit:~
curl -O https://raw.githubusercontent.com/JVBotelho/cve-2026-69243-poc-aiohttp-smuggling/main/poc.py
python3 poc.py <proxy-host> <proxy-port> <backend-host>

또는 Rust 버전을 빌드하세요 (의존성 없음, 표준 라이브러리만 사용):

root@kitploit:~
git clone https://github.com/JVBotelho/cve-2026-69243-poc-aiohttp-smuggling
cd cve-2026-69243-poc-aiohttp-smuggling/poc
cargo build --release
./target/release/cve-2026-69243-poc <proxy-host> <proxy-port> <backend-host>

사전 빌드된 바이너리는 릴리스 워크플로를 통해 릴리스에 게시됩니다.

두 버전 모두 바이트 단위로 동일한 페이로드를 생성합니다 (CI 패리티 테스트로 보장). 랩이 실행 중이면:

root@kitploit:~
python3 poc.py nginx-upgrade 80 backend-vuln

예상 출력: HTTP 응답 1개 (WebSocket upgrade rejected). 그런 다음 확인:

root@kitploit:~
# Backend processed 2 requests (/ws + smuggled /admin):
docker logs backend-vuln | grep -c '"path".*"/admin"'

# Nginx only logged 1 request (the /ws):
docker exec nginx-upgrade cat /logs/nginx-upgrade.access.log | grep -c '/admin'

백엔드 카운트 > 0이고 Nginx 카운트 = 0이면 CWE-444 분할이 확인된 것입니다. 이 PoC는 단일 TCP 세그먼트를 전송합니다. 본문이 곧 스머글링된 요청이며, Nginx는 이를 본문으로 처리하는 반면 aiohttp는 이를 두 번째 요청으로 처리합니다.

이를 통해 입증되는 것

  • 파서 혼동: aiohttp 3.14.1 _http_parser.pyx는 본문이 소비되기 전에 업그레이드 감지 시 2(본문 건너뛰기)를 반환합니다(약 863행). 본문 바이트는 _message_tail에 남아 web_protocol.py의 finish_response(약 771행)에서 파서로 다시 전달됩니다.
  • CWE-444 분할: 프런트엔드는 본문이 있는 요청 1개를 보고, 백엔드는 파이프라인된 요청 2개를 봅니다. 로그에서 요청 수 불일치가 발생합니다.
  • 접근 제어 우회: Nginx에 location /admin { deny all; }가 있을 때, 스머글링된 /admin은 Nginx 라우팅 결정이 외부 요청에 대해서만 이루어지기 때문에 여전히 백엔드에 도달합니다.
  • 핸들러 수준 수정 불가: 3.14.1에서 await request.read()는 업그레이드 요청에 대해 0바이트를 반환합니다. 본문은 핸들러 계층 아래에서 보류됩니다. 패치를 적용하거나, 프로토콜을 전환해서는 안 되는 경로의 프록시에서 업그레이드 헤더를 제거하세요.

전체 랩

root@kitploit:~
git clone https://github.com/JVBotelho/cve-2026-69243-poc-aiohttp-smuggling
cd cve-2026-69243-poc-aiohttp-smuggling
docker compose up -d

# Run the PoC:
docker compose run --rm --entrypoint /app/poc attacker nginx-upgrade 80 backend-vuln

서비스:

Phase 1-3 전체 조사 결과는 findings/에 있습니다.

제한 사항 (솔직하게)

  • 프록시가 업그레이드 헤더를 전달해야 합니다. 백엔드로 Connection: close를 보내거나 Connection/Upgrade 헤더를 제거하는 Nginx 구성은 취약하지 않습니다. 분할을 노출하는 구성은 Nginx 자체 프록시 문서의 표준 WebSocket map 스니펫입니다.
  • 스머글링된 응답은 프록시에 흡수됩니다. 시연된 Nginx 체인에서 공격자는 외부 /ws 응답만 받습니다. 스머글링의 증거는 공격자 응답이 아닌 백엔드 로그에 있습니다. 이 토폴로지에서는 블라인드 단방향 프리미티브입니다. 다른 프록시 토폴로지는 테스트되지 않았습니다.
  • 청크 프레이밍은 실질적으로 CL에 한정됩니다. aiohttp에 직접 적용할 경우 Transfer-Encoding: chunked는 스머글링하지 않습니다. 원시 청크 크기 라인 (예: 3e)이 유효하지 않은 메서드로 파서에 도달하여 연결이 종료됩니다. Nginx를 통하면 작동하지만 정규화를 통해서입니다. Nginx가 본문의 청크를 해제하고 생성된 Content-Length를 전달하므로 백엔드는 동일한 CL 경로를 통해 공격받습니다. --chunked 플래그는 프록시 경로를 시연합니다.
  • WebSocket 업그레이드를 거부하는 엔드포인트가 필요합니다. 핸들러는 WebSocketResponse가 아닌 응답을 반환해야 합니다. 라우트에서 WebSocket을 사용하지 않는 대부분의 앱은 기본적으로 거부합니다(프레임워크가 404를 반환 하거나 다음 핸들러로 넘어갑니다).

파일

root@kitploit:~
poc/                       # Rust cargo project
├── Cargo.toml
├── src/main.rs            # CLI binary
├── src/lib.rs             # Library + unit tests
├── tests/parity.rs        # Cross-language payload parity test
└── fuzz/                  # cargo-fuzz targets
poc.py                     # Python PoC (copy-paste from blog)
attacker/ backend/ frontend/   # Docker lab services
docker-compose.yml         # 7-service lab
findings/                  # Research notes (Phase 1-3)
.github/workflows/
├── ci.yml                 # Build, test, clippy, parity, integration, fuzz
└── release.yml            # Cross-compile + GitHub Release

탐지

전체 분석은 findings/fase3-deteccao.md를 참조하세요. 프로덕션에서 중요한 주의사항을 포함한 요약:

  1. 요청 수 불일치 (백엔드 > 프런트엔드) 동일한 연결에서. 참고: 백엔드는 클라이언트의 IP가 아닌 프록시의 IP를 기록합니다. 상관관계를 파악하려면 X-Forwarded-For/Proxy Protocol을 정규화하거나 업스트림 연결 ID + 연결별 요청 순서를 로깅해야 합니다. 클라이언트 IP + 시간 창 만으로는 약합니다(NAT, keep-alive, 동시성).
  2. 프런트엔드 매칭이 없는 백엔드 요청: 프런트엔드 액세스 로그에 해당 항목이 없는데 백엔드 로그에 제한된 경로가 나타납니다. 내부 서브넷을 필터링하세요(프록시를 우회하는 헬스 체크가 오탐을 유발).
  3. 업그레이드 거부 + 동일 클라이언트의 약 100ms 내 다른 경로. 중간 신뢰도 — 합법적인 파이프라이닝도 비슷한 간격을 생성합니다. 랩 로거는 원격 포트/연결 ID를 기록하지 않으므로 "새 TCP 핸드셰이크 없음"은 이 데이터로 입증되는 것이 아닙니다.
  4. 본문 보류 미들웨어 (content_length vs request.read()의 바이트): 3.14.1에서 발동하고 3.14.2에서는 조용합니다. 탐지는 하지만 완화하지는 않습니다. 범위를 한정하세요(업그레이드 후보 라우트, 작은 본문, 101이 아닌 상태 코드). 단순한 버전은 모든 본문을 메모리에 버퍼링합니다.
  5. WebSocket 엔드포인트에서 헤더 기준선보다 높은 에지 reqlen — 단독으로는 신뢰도가 낮지만(쿠키/JWT/추적 헤더가 노이즈가 많음), 클라이언트가 Content-Length를 보내지 않을 때(청크 수신) 유일한 에지 신호입니다.
도구 다운로드
Container용도
backend-vulnaiohttp 3.14.1 (취약), READ_BODY=false
backend-vuln-readaiohttp 3.14.1, READ_BODY=true (핸들러가 도움이 될 수 없음을 입증)
backend-patchedaiohttp 3.14.2 (수정됨)
nginx-upgrade업그레이드 헤더 전달 (/admin에 대해 deny all)
nginx-default업그레이드 전달 없음 (버그 중화)
nginx-stripConnection "" 제거 (버그 중화)
attackerRust 바이너리: reproduce, fase2, poc