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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2024-4947-PoC — CVE-2024-4947에 대한 교육용 proof-of-concept로, V8 Maglev 타입 혼동을 다루며, 샌드박스가 없는 d8 빌드에서 트리거부터 임의 코드 실행까지의 전체 체인을 시연합니다. | Kitploit
도구/GitHubGitHub/l1m3syc/cve-2024-4947-poc
Vulnerability AnalysisExploitationWeb Application ExploitationPapers & ResearchLearning & EducationBinary Exploitation
GitHubl1m3syc/cve-2024-4947-poc

CVE-2024-4947-PoC

CVE-2024-4947에 대한 교육용 proof-of-concept로, V8 Maglev 타입 혼동을 다루며, 샌드박스가 없는 d8 빌드에서 트리거부터 임의 코드 실행까지의 전체 체인을 시연합니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2024-4947 — V8 Maglev 타입 혼동 → 완전한 RCE (d8 PoC)

CVE-2024-4947(V8 Maglev 타입 혼동)에 대한 완전하고 자체 포함된(self-contained) 익스플로잇 체인으로, 초기 타입 혼동 트리거에서부터 임의 코드 실행에 이르기까지 전체를 아우릅니다. 이 PoC는 비-샌드박스(non-sandboxed) d8 빌드를 대상으로 실행되며, 코드 실행 증명으로 CVE-2024-4947-PWNED를 stdout에 출력합니다.

⚠️ 이는 패치된 공개 취약점에 대한 연구/교육용 PoC입니다. V8 셸의 개발 빌드(d8 --allow-natives-syntax)를 대상으로 하며 — 실제 Chrome 브라우저가 아닙니다. 면책 조항을 참조하세요.


TL;DR

root@kitploit:~
$ ./v8-build-nosandbox.sh            # build the vulnerable d8 (WSL2 Ubuntu, ~10-20 min)
$ d8 --allow-natives-syntax --module exploit/exploit_rce.mjs
[engine] dblData0=0004f470 class=0
[inst] addr=0x001dc274 trusted_data(tagged)=0x00202bd5 td=0x00202bd4
[jt]   jump_table_start = 0x00000967426cd000 (external code space)
[bridge] memory0_start -> jt, memory0_size -> huge  (r/w reach jt+off)
[slot0] before: e9 3b 08 00 00
[shell] wrote 52 bytes @ jt+0x0100: VERIFIED
CVE-2024-4947-PWNED
$ echo $?   # 0

52바이트 셸코드는 write(1, "CVE-2024-4947-PWNED\n", 20); exit_group(0)입니다.


취약점

CVE-2024-4947은 V8 Maglev JIT 컴파일러의 타입 혼동 취약점으로, Chrome 125.0.6422.60(커밋 b3c01ac1e60a)에서 패치되었습니다. Lazarus APT 그룹에 의해 실제 환경(in the wild)에서 악용되었습니다. Maglev가 모듈 네임스페이스 객체(JSModuleNamespace)에 대한 스토어를 컴파일할 때 잘못된 AccessInfo를 사용합니다. 즉, 스토어가 올바른 속성-저장(property-store) 경로를 거치지 않고, 인접 객체의 map 필드에 제어된 값을 쓰는 단순한 mov [[obj + 4], rax]로 컴파일됩니다.

악용은 다음과 같이 진행됩니다:

  1. 객체의 map을 가짜 NAME_DICTIONARY_TYPE (0xB2) map으로 손상시켜, V8이 객체의 해시를 저장하는 위치를 변경합니다.
  2. new WeakRef(...)를 트리거하여 해시 쓰기가 인접 객체의 length 슬롯에 떨어지게 합니다 → 경계를 벗어난(out-of-bounds) 접근.

여기서부터 고전적인 V8 툴킷, 즉 addrOf/fakeObj, 그리고 임의 in-cage 읽기/쓰기를 얻습니다.


익스플로잇 체인

root@kitploit:~
CVE-2024-4947 trigger (fake NAME_DICTIONARY map + WeakRef hash write)
  └─► OOB write ─► corrupt doubleArray length
        └─► in-cage 4/8-byte arbitrary R/W            (the "engine")
              └─► overwrite WasmTrustedInstanceData.memory0_start (+0x18)
                    & memory0_size (+0x20) → huge
                    └─► wasm load8_u / store8 = clean 64-bit R/W bridge
                          (no software bounds check in compiled code)
                          └─► read jump_table_start (+0x38) — external code space
                                └─► jump table region is RWX (this build)
                                      └─► write shellcode into the slack (jt+0x100)
                                            └─► repoint func0's `e9 rel32` slot at it
                                                  └─► call func0 → shellcode → RCE

단계별

#단계세부 내용
1트리거opt()가 혼동된 스토어를 통해 가짜 map을 씁니다. new WeakRef(m)이 corruptArray.length를 OOB시킵니다.
2엔진addrOf/fakeObj; doubleArray의 length를 손상시켜 4-정렬된 모든 cage 주소에 임의 4바이트 R/W를 수행합니다.
364비트 브리지WasmTrustedInstanceData.memory0_start(+0x18)은 컴파일된 wasm i32.load8_u/i32.store8이 사용하는 raw 64비트 포인터이며 소프트웨어 경계 검사가 없습니다(범위를 벗어나면 가드 페이지에 부딪혀 → SIGSEGV → wasm 트랩). 이를 임의 주소로 리다이렉트하고 memory0_size(+0x20)를 크게 설정하면 → 임의 64비트 R/W.
4코드 공간 찾기jump_table_start(+0x38)은 외부 코드 공간(4 GB cage 밖)을 가리키는 raw 64비트 포인터입니다.
5셸코드 쓰기이 빌드에서 점프-테이블 영역은 RWX입니다(V8이 런타임에 엔트리를 패치함): 52바이트 셸코드를 jt+0x100의 여유 공간(slack)에 씁니다.
6슬롯 재지정func0의 점프-테이블 슬롯은 5바이트 e9 <rel32>입니다(target = slot + 5 + rel32). rel32를 jt+0x100으로 설정합니다.
7디스패치 트리거inst.exports.r(0) → JSToWasmWrapper가 slot 0을 통해 디스패치 → 셸코드 실행.

다른 공개 PoC와의 차이점

대부분의 공개 CVE-2024-4947 PoC는 샌드박스 d8 또는 실제 Chrome 렌더러(v8_enable_sandbox=true)를 대상으로 하며, 타입 혼동/OOB 프리미티브까지만 진행합니다. 이 PoC는 노-샌드박스(no-sandbox) d8을 대상으로 하며 체인을 코드 실행까지 끝까지 이어갑니다. 중요한 차이점은 다음과 같습니다:

차원일반적인 공개 PoC 방식이 PoC
대상 빌드샌드박스 d8 / Chrome 렌더러v8_enable_sandbox=false d8 — trusted 포인터가 직접(direct)이며 외부 코드 공간이 활성화됨
64비트 R/W 브리지JSTypedArray.external_pointer 덮어쓰기해당 경로는 코드 범위를 읽을 때 크래시가 발생합니다(실증적으로 확인됨); 대신 **memory0_start**를 덮어쓰고 raw wasm load/store를 사용
최종 코드 실행 경로코드 공간은 W^X → JIT-스프레이 + 간접 리다이렉트점프-테이블 영역은 RWX → 직접 셸코드 쓰기 + e9 rel32 슬롯 패치
점프-테이블 슬롯 형식문서들은 일반적으로 movabs rax, imm64; jmp rax(12바이트)를 가정측정 결과: 5바이트 e9 <rel32>, target = slot + 5 + rel32
필드 오프셋샌드박스 빌드 레이아웃노-샌드박스 WasmTrustedInstanceData: jump_table_start@+0x38, memory0_start@+0x18, memory0_size@+0x20; WasmInstanceObject.trusted_data@+0x0c
깨끗한 종료—d8은 멀티스레드입니다: exit(60)가 아닌 exit_group(231)을 사용해야 하며, 그렇지 않으면 프로세스가 멈춥니다

각 행 뒤에 있는 실증적 발견 사항을 포함한 전체 기술 문서는 docs/walkthrough.md를 참조하세요.


저장소 구조

root@kitploit:~
.
├── exploit/
│   ├── Module.mjs           # module namespace object corrupted by the trigger
│   ├── exploit_rce.mjs      # the full chain (trigger → arbitrary R/W → RCE)
│   └── shellcode.S          # assembly source for the 52-byte payload
├── build/
│   └── v8-build-nosandbox.sh # build the vulnerable no-sandbox d8 from V8 source
└── docs/
    └── walkthrough.md       # deep dive: bridge mechanics, layouts, gotchas

익스플로잇은 Module.mjs(취약한 모듈 네임스페이스 객체)를 자신의 디렉터리에서 import하므로, 두 파일을 함께 두십시오(또는 import 경로를 조정하십시오).


빌드 및 실행

요구 사항

  • WSL2(Ubuntu) 또는 C/C++ 툴체인, git, 약 10GB 여유 디스크가 있는 모든 Linux
  • Google depot_tools (git clone https://chromium.googlesource.com/chromium/tools/depot_tools)
  • 취약한 리비전의 V8 소스(아래 참조)

취약한 d8 빌드

root@kitploit:~
# 1. fetch V8 at the vulnerable tag (12.4.254.16 is the pre-fix release)
export PATH="$HOME/depot_tools:$PATH"
cd ~/v8w && fetch v8 && cd v8
git checkout 12.4.254.16          # or the commit just before b3c01ac1e60a

# 2. first build a normal release d8 (needed to seed args.gn), then:
./v8-build-nosandbox.sh           # copies args.gn and appends v8_enable_sandbox = false

v8-build-nosandbox.sh는 ninja -C out.gn/x64.release_nosandbox -j6 d8를 사용합니다.

실행

root@kitploit:~
out.gn/x64.release_nosandbox/d8 --allow-natives-syntax --module exploit/exploit_rce.mjs

예상 출력은 다음과 같이 끝납니다:

root@kitploit:~
CVE-2024-4947-PWNED

그리고 프로세스는 상태 0으로 종료됩니다.

%PrepareFunctionForOptimization / %OptimizeMaglevOnNextCall 런타임 호출에는 --allow-natives-syntax가 필요합니다. 이것이 이 PoC가 실제 브라우저에서 실행될 수 없는 이유입니다 — 설계상 d8 셸 개념 증명(PoC)이기 때문입니다.


재사용 가능한 기법

V8 익스플로잇 연구에 실제로 재사용 가능한(그리고 쉽게 알기 어려운) 부분들:

  1. Wasm 메모리-리다이렉트 64비트 R/W 브리지 — 대상 영역에서 JSTypedArray.external_pointer 리다이렉션이 실패하면 대신 WasmTrustedInstanceData.memory0_start를 리다이렉트하십시오. 컴파일된 wasm 바이트 load/store에는 소프트웨어 경계 검사가 없습니다. 시그널 트랩 핸들러는 가드 페이지 폴트만 변환하므로, 매핑되었지만 쓰기 불가능한 영역은 트랩이 아닌 크래시로 이어집니다.
  2. 점프-테이블 쓰기 가능성 프로빙 — wasm 점프-테이블 영역의 보호 속성은 빌드에 따라 다릅니다. try/catch로 바이트 단위로 프로빙하십시오. wasm "out of bounds" 트랩은 가드 페이지(매핑 안 됨)를 의미하고, 실제 SIGSEGV는 매핑되었지만 RX 상태를 의미합니다.
  3. e9 rel32 슬롯 형식 — 많은 라이트업이 가정하는 movabs 형식이 아닌 5바이트 상대 점프(relative jump)입니다. --print-wasm-code 디스어셈블리로 검증되었습니다.

면책 조항

이 저장소는 교육 및 방어적 보안 연구 목적으로만 제공됩니다. 개발 전용(development-only) V8 빌드를 대상으로 패치된 취약점의 악용을 시연합니다. 이는 현대 Chrome을 공격하는 무기가 아니며, V8 샌드박스를 우회하지 않고, 기본값이 아닌 --allow-natives-syntax 플래그를 필요로 합니다. 저자는 어떠한 오용에 대해서도 책임지지 않습니다.

크레딧 / 계보

트리거 프리미티브(가짜 NAME_DICTIONARY_TYPE map + WeakRef 해시 쓰기)는 패치 이후 공개된 in-the-wild Lazarus 익스플로잇에 대한 공개 분석을 따릅니다. 여기에는 Google 및 Exodus Intelligence의 CVE-2024-4947 라이트업이 포함됩니다. 이후 단계(점프-테이블 프로빙, 브리지, 슬롯 패치)는 이 작업 중 이 특정 빌드를 대상으로 실증적으로 도출되었습니다. JIT-스프레이 폴백 개념은 공개된 V8 익스플로잇 기법(예: CVE-2024-5830 make_array 패턴)을 활용합니다.

라이선스

MIT — LICENSE를 참조하세요.

도구 다운로드