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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2025-55182 — React Server Components 버전 19.0.0, 19.1.0, 19.1.1, 19.2.0에서의 사전 인증 RCE | Kitploit
도구/GitHubGitHub/dwisiswant0/cve-2025-55182
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationLearning & EducationPayload Development
GitHubdwisiswant0/cve-2025-55182

CVE-2025-55182

React Server Components 버전 19.0.0, 19.1.0, 19.1.1, 19.2.0에서의 사전 인증 RCE

저장소 보기
591539개월 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2025-55182

이 저장소에는 CVE-2025-55182의 PoC 재현 코드가 포함되어 있습니다. 이는 React 서버 컴포넌트(RSC)의 심각한 보안 취약점으로, 인증되지 않은 임의 코드 실행을 허용합니다.

설명

취약점은 React 서버 컴포넌트가 클라이언트 요청에서 '서버 액션'을 역직렬화하는 방식에 존재합니다. 구체적으로, requireModule 함수가 요청된 내보내기 이름이 모듈의 직접적인 prop인지 검증하지 못했습니다. 이를 통해 공격자는 내보낸 함수의 constructor prop에 접근하여 전역 Function 생성자에 대한 참조를 얻을 수 있었으며, 이를 사용하여 임의 코드를 실행할 수 있습니다.

재현

이 PoC는 최소한의 Node.js 환경을 사용하여 react-server-dom-webpack 라이브러리의 취약점을 격리합니다. 이는 익스플로잇이 라이브러리 자체의 버그를 증명하는 것이지, 프레임워크의 잘못된 설정이 아님을 확인하기 위함입니다.

필수 조건

  • Node.js
  • npm

설치

root@kitploit:~
npm install

[!NOTE] package.json은 취약한 버전 19.0.0에 고정되어 있습니다.

개념 증명

  1. 취약한 서버 시작

이 스크립트는 취약한 React 런타임을 사용하여 요청을 디코딩하는 원시 HTTP 서버를 설정합니다.

root@kitploit:~
# tty1
node --conditions react-server server.js
  1. 익스플로잇 스크립트 실행

별도의 터미널에서 익스플로잇을 실행합니다. 이는 악의적인 Flight 페이로드를 서버에 전송합니다.

root@kitploit:~
# tty2
node exploit.js id

응답에서 명령 출력이 반환되는 것을 확인할 수 있습니다:

예상 출력:

root@kitploit:~
Response: uid=0(root) gid=0(root) groups=0(root)

분석

왜 취약점이 발생했나요?

ReactFlightDOMServerNode.js의 requireModule 함수는 기본적으로 클라이언트가 보낸 name을 그대로 신뢰했습니다. 해당 속성이 실제로 노출되도록 의도되었는지 확인하지 않고 moduleExports[metadata[NAME]]를 수행했습니다. 따라서 클라이언트가 "야, 이 속성 줘"라고 하면 서버는 "그래, 여기 있어, 친구"라고 그냥 응답했습니다.

누구나 모든 속성에 접근할 수 있게 하는 것이 왜 나쁜 생각인가요?

기본적으로 누구나 프로토타입 체인에 접근할 수 있게 하며, 심지어 **constructor**에까지 접근할 수 있어 매우 위험합니다. 모듈이 함수를 내보내는 경우(예: module.exports = () => {}), 그 함수의 constructor는 말 그대로 전역 Function 생성자입니다.

Function 생성자를 얻는 것이 왜 RCE를 의미하나요?

공격자가 Function 생성자를 확보하면 '바인딩된 서버 액션' 기능을 남용할 수 있습니다. 악성 JavaScript를 포함한 문자열을 이 생성자에 바인딩하여 (사실상 new Function("악성 코드")로 변환) 실행시키면, 서버는 그 코드를 실행하게 됩니다.

React가 실제로 그 악성 함수를 실행하는 이유는 무엇인가요?

서버 액션은 ID로 트리거될 수 있기 때문입니다. 공격자가 자신의 module#constructor 참조를 가리키는 액션 ID로 페이로드를 제작하면, React는 이를 정상 액션처럼 해석하여 실행합니다. 그 '액션'은 실제로 공격자의 악성 함수입니다.

왜 이러한 것들이 검증되지 않았나요?

시스템은 서버 참조 메타데이터의 id와 name이 항상 개발자가 정의한 유효한 내보내기를 참조할 것이라고 가정했습니다. 요청된 prop이 실제 내보내기인지, 아니면 프로토타입 체인에서 상속된 것인지 확인하는 hasOwnProperty와 같은 안전 검사가 없었습니다.

server.js를 사용하고 Next.js를 사용하지 않는 이유

원시 server.js (그리고 도우미 webpack-runtime.js)를 사용하여 React 서버 컴포넌트 런타임을 수동으로 구성합니다. 이를 통해 다음을 할 수 있습니다:

  1. 취약한 설정을 강제: 익스플로잇은 모듈이 함수로 내보내질 때만 작동합니다 (module.exports = fns). 실제 번들러는 구성에 따라 내보내기 방식이 달라질 수 있습니다.
  2. 버그 격리: 이를 통해 문제가 Next.js가 아닌 react-server-dom-webpack 내부에 있음을 보여줄 수 있습니다.
  3. 번들러 환경 재현: react-server-dom-webpack은 Webpack 번들 내에서 실행된다고 가정합니다. 우리의 webpack-runtime.js는 예상되는 전역 변수(__webpack_require__, __webpack_chunk_load__)를 제공합니다.

이는 취약점을 모의하는 것이 아니라, 라이브러리가 실제로 작동하는 데 필요한 최소한의 런타임을 제공하는 것입니다.

참고 사항

개발자가 의도적으로 child_process.exec와 같은 위험한 것을 노출할 때만 작동하는 '유효하지 않은 PoC'에 대한 논의가 있었습니다.

이 PoC는 그런 것이 아닙니다. 정상적이고 안전한 설정에서 작동합니다.

  1. 노출된 함수는 무해함 앱은 단순히 문자열을 반환하고 의심스러운 점이 없는 updateProfile 함수를 노출합니다. 셸 명령은 없습니다.
  2. 익스플로잇은 해당 함수를 완전히 우회함 취약점으로 인해 공격자는 안전한 내보내기를 무시하고 updateProfile.constructor로 바로 이동할 수 있으며, 이는 전역 Function 생성자입니다.
  3. 핵심 문제는 속성 접근 React는 .constructor에 대한 접근을 허용하지 말았어야 합니다. 개발자는 Function 생성자를 노출할 의도가 없었지만, 안전하지 않은 역직렬화가 대신 그렇게 했습니다.

유일한 실제 요구 사항은 모듈이 함수를 직접 내보낸다는 것입니다 (module.exports = fn). 이는 CommonJS 및 많은 번들러 설정에서 매우 일반적입니다.

페이로드

exploit.js의 페이로드는 세 개의 청크로 React Flight 메시지를 구성합니다:

  • 청크 0: 청크 1에 정의된 서버 참조를 가리킵니다.
  • 청크 1: 서버 참조를 선언합니다:
    • id: "user-profile-action#constructor", "생성자를 줘"라는 의미.
    • bound: 인수가 포함된 청크 2를 가리킵니다.
  • 청크 2: ["console.log('nice try, diddy!')"]: 악성 코드 문자열.

React가 이를 역직렬화할 때:

  1. user-profile-action을 해석합니다.
  2. .constructor 속성을 읽어 전역 Function을 얻습니다.
  3. 공격자가 제공한 문자열을 바인딩합니다.
  4. 사실상 다음을 실행합니다: new Function("console.log('nice try, diddy!')")

그리고 그것이 RCE입니다!

완화 방법

패치된 버전으로 즉시 업그레이드하십시오:

  • react-server-dom-webpack >= 19.0.1
  • react-server-dom-parcel >= 19.0.1
  • react-server-dom-turbopack >= 19.0.1

패치는 상속된 속성에 접근하는 것을 방지하기 위해 hasOwnProperty 검사를 도입하고 base64 파일 업로드를 제한합니다.

패치된 버전에서 이 PoC를 실행하면 서버가 다음 오류로 충돌하거나 오류가 발생합니다:

root@kitploit:~
$ node --conditions react-server server.js
Listening on http://localhost:3000
/path/to/CVE-2025-55182/node_modules/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js:2726
            resolvedValue = resolvedValue.bind.apply(
                                          ^

TypeError: Cannot read properties of undefined (reading 'bind')
    at /path/to/CVE-2025-55182/node_modules/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js:2726:43
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v20.19.3

이는 익스플로잇이 constructor 속성에 접근하는 데 실패했음을 확인합니다 (Function 대신 undefined 반환). 결과적으로 후속 .bind 호출이 실패했습니다.

면책 조항

이 코드는 교육 및 테스트 목적으로만 제공됩니다. 소유하지 않았거나 테스트 허가를 받지 않은 시스템에 이 익스플로잇을 사용하지 마십시오.

라이선스

Released under DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE.

도구 다운로드