
# CVE-2026-85046 개념 증명 및 기술 분석 CVE-2026-85046에 대한 개념 증명(PoC) 및 기술 분석 자료로, 인라인 `Array.prototype.sort`에서 발생하는 V8 타입 혼동(type confusion) 취약점을 다룹니다. 근본 원인(root cause), 패치 diff, 그리고 Chrome < 152.0.7977.82에 대한 익스플로잇 체인을 포함합니다.
| 필드 | 값 |
|---|
| CVSS | 8.8 (High) |
| CWE | CWE-843 (Type Confusion) |
| 구성 요소 | V8 JavaScript 엔진 -- Maglev/Turbofan 인라인 정렬 |
| 영향 범위 | Chrome < 152.0.7977.82, 모든 Chromium 기반 브라우저 |
| 수정 버전 | Chrome 152.0.7977.82 (2026-09-03) |
| 수정 커밋 | e0562d87ad9c17042b581582c99237d798572e67 |
| CISA KEV | 2026-09-04 추가, 마감 2026-09-18 |
| 실제 악용 | 예 (Google 확인) |
| 보고자 | Salvatore Gulizia (Serotav) |
인라인 정렬 최적화는 다형성(polymorphic) 요소 종류 피드백(PACKED_SMI_ELEMENTS + PACKED_ELEMENTS)을 허용합니다. 비교 함수가 arr.fill(0)을 호출하면 V8은 수신자 맵을 PACKED_ELEMENTS에서 PACKED_SMI_ELEMENTS로 역방향 마이그레이션합니다. 원래 피드백 세트에 PACKED_SMI_ELEMENTS가 포함되어 있었기 때문에 정렬 후 맵 검사는 통과합니다. 복사-백(copy-back)은 SMI 전용 요소를 주장하는 맵을 가진 배열에 객체 포인터를 기록합니다.
수정 사항은 정렬을 인라인하기 전에 피드백의 모든 수신자 맵이 동일한 elements_kind를 공유하도록 요구하는 사전 조건을 추가합니다.
| 파일 | 설명 |
|---|---|
patch-analysis.md | 근본 원인, 트리거 메커니즘, 악용 프리미티브 평가를 포함한 전체 패치 diff 분석 |
patch-analysis.json | 구조화된 데이터: 커밋 해시, CWE, 영향 버전, 악용 프리미티브 |
v8-research.md | V8 요소 종류 심층 분석, 기존 PoC (CVE-2020-6418, CVE-2025-2135, CVE-2024-4947 등), 샌드박스 아키텍처, 탈출 기법 |
poc-minimal.js | d8용 최소 타입 혼동 트리거 (d8 --allow-natives-syntax poc-minimal.js) |
poc.html | 전체 악용 체인: 타입 혼동, addrof 프리미티브, 힙 스프레이, 백킹 스토어 오버랩을 통한 fakeobj, 정보 유출 |
exploit-notes.md | 기술 문서: 단계별 체인, 힙 레이아웃 다이어그램, 포인터 압축, 샌드박스 영향, 탐지 지표, 수정 사항 |
# V8 디버그 헬퍼 사용
d8 --allow-natives-syntax poc-minimal.js
# 사용하지 않음 (String()을 통한 휴리스틱 검증)
d8 poc-minimal.js
Chrome < 152.0.7977.82에서 poc.html을 엽니다. 익스플로잇은 자동으로 실행되며 각 단계를 페이지와 개발자 콘솔에 기록합니다. 단계:
arr.fill(0)을 통한 타입 혼동 트리거addrof 프리미티브 -- 압축된 힙 포인터를 정수로 유출fakeobj -- 제어된 정수에서 객체 참조 위조트레이닝 (2000회 반복)
|
v
타입 혼동: PACKED_ELEMENTS 맵 -> PACKED_SMI_ELEMENTS 맵
(백킹 스토어는 여전히 객체 포인터 보유)
|
v
addrof: String(confused_array)가 포인터를 정수로 유출
|
v
fakeobj: double/object 배열 오버랩이 제어된 포인터 기록
|
v
제어된 요소 포인터를 가진 가짜 JSArray -> 임의 R/W (케이지 내부)
|
v
V8 샌드박스 내 코드 실행 (전체 RCE에는 샌드박스 탈출 필요)
kMaxInlineSortLength)arr.fill()을 호출해야 함PACKED_SMI 및 PACKED_ELEMENTS 배열이 모두 전달되어야 함