ZINO
HomeResearchBlogTagsPlaygroundStack
⌘K

레드팀 · AI 자동화 · 시스템 엔지니어링

직접 만들고, 실험하고, 기록한다

개인정보처리방침·이용약관

© 2026 ZINO LAB

← 태그 목록

Tag Archive

#v8

이 태그가 포함된 글을 최신순으로 모아봤어요.

6
posts
BLOG2026-06-08
[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (5) — read에서 flag까지: 불가능이라던 부트스트랩을 뒤집고 라이브 서버를 뚫다 — DreamHack EXP-NaN
blog

[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (5) — read에서 flag까지: 불가능이라던 부트스트랩을 뒤집고 라이브 서버를 뚫다 — DreamHack EXP-NaN

4편은 ".at() 무가드 OOB read는 확정, 그런데 write는 여전히 막혀 있고 read→write 다리는 addrof/fakeobj뿐"으로 끝났다. 5편은 그 다리를 건너 라이브 flag까지 가는 기록이다 — 그리고 솔직히 3일이 걸렸다. addrof/fakeobj 부트스트랩이 "nursery monoculture로 불가능"이라던 결론을 뒤집고(진짜 원인은 globalThis 저장이 fold를 deopt시킨 것), fake FixedDoubleArray로 첫 forward 케이지 R/W를 열고, 그게 GC 신뢰성에서 이틀을 막았다가 "오프셋 가정을 런타임 leak으로 바꾸는" 한 줄로 5/5가 됐다. 거기서 fake Float64Array의 base_pointer를 갈아끼워 data_ptr을 절대주소로 지정하는 양방향 R/W로 backward 인스턴스까지 읽고, V12 Revenge에서 쓴 imported_function_targets 덮기로 절대주소 누출 없이 execve("/bin/sh")까지. 익스는 서버 한도(2000B)에 맞춰 1999바이트로 깎았고, 로컬 10/10이 서버에선 0/12로 죽길래 진단을 보냈더니 mapArr 하나만 환경마다 달랐다(0x18d7b9 vs 0x10d7b9) — 그걸 런타임 leak으로 적응시켜 host3.dreamhack.games에서 flag를 회수했다.
#dreamhack#ctf#pwn+8
 
BLOG2026-06-07
[💠 Platinum 1] V8을 V12로 — array-shift 길이 언더플로로 OOB부터 V8 샌드박스 탈출·RCE까지 — DreamHack V12 Revenge
blog

[💠 Platinum 1] V8을 V12로 — array-shift 길이 언더플로로 OOB부터 V8 샌드박스 탈출·RCE까지 — DreamHack V12 Revenge

"V8이 너무 느리다, V12로 갈아타자 (* 내부 함수 없이 *)" — array-shift Torque 빌트인에서 빈 배열 가드 한 줄을 주석 처리한 게 전부인 버그다. 길이 0 배열에 .shift()를 부르면 newLength = 0-1 = -1, 그게 그대로 length 필드로 들어가 length(0xFFFFFFFF) ≫ capacity 인 OOB 배열이 만들어진다. 이 글은 그 OOB에서 케이지 임의 R/W·addrof를 세우고 — 한 번은 "V8 샌드박스가 절대주소 누출을 막아 코드 실행이 불가능하다"고 잘못 결론 내렸다가 — 출제자가 의도한 정석 기법을 찾아 뒤집은 기록이다. 핵심은 WasmInstanceObject의 imported_function_targets: 임포트 함수의 호출 타깃을 담은 "케이지 안 ByteArray"가 실은 raw(샌드박스 밖) 포인터라, 케이지 쓰기만으로 import 호출을 임의 주소로 보낼 수 있다. 거기에 jump_table_start로 RWX를 직접 읽고, 셸코드 실행 순간 살아있는 r14(케이지 베이스)로 wasm 메모리를 가리켜 execve("flag_reader") — 절대주소 누출 없이 샌드박스를 빠져나와 라이브 flag까지 회수했다.
#dreamhack#ctf
BLOG2026-06-07
[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (4) — 근데 .at()이 열려 있었다: 놓친 비-CheckBounds sink — DreamHack EXP-NaN
blog

[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (4) — 근데 .at()이 열려 있었다: 놓친 비-CheckBounds sink — DreamHack EXP-NaN

3편은 "남은 출구를 전수로 두드렸지만 다 닫혔다"로 끝났다. 4편은 그 결론을 내 손으로 뒤집는 기록이다 — 3편이 본 sink는 전부 bracket 접근(`a[i]`)과 CheckBounds 계열이었는데, 딱 하나 안 본 게 있었다. `Array.prototype.at()`. 이건 별도 reducer(js-call-reducer.cc)라 경계검사를 CheckBounds가 아니라 fold 가능한 NumberLessThan 두 개 + bare LoadElement 로 한다. 패치가 그 파일을 안 건드려서 그대로 살아있고, reshape로 typer를 속이면 두 가드가 접혀 무가드 OOB read가 진짜로 열린다(자연 티어업, exit0, 결정적). 다만 store 짝이 없어 write는 여전히 막혀 있고(bracket=trap, TypedArray/fill/with 전멸, a.length는 치유), read→write 다리는 addrof/fakeobj뿐이다. 포인터 압축이 왜 reader 타입을 가르는지, 그리고 그 fakeobj 부트스트랩(타입-매칭 인접)이 왜 nursery monoculture에 막히는지 — V8 reducer 구조부터 쉘 스샷까지 한 단계씩.
#dreamhack#ctf
BLOG2026-06-07
[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (3) — 남은 출구를 전부 두드리다: 의도된 sink마저 막혀 있었다 — DreamHack EXP-NaN
blog

[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (3) — 남은 출구를 전부 두드리다: 의도된 sink마저 막혀 있었다 — DreamHack EXP-NaN

2편은 "표준 값-range 경로(CheckBounds 제거)는 11.2에서 닫혔다"까지였다. 3편은 그 뒤 — CheckBounds를 거치지 않는 *비표준 출구*를 하나하나 전부 두드린 기록이다. fill/copyWithin, foldable 빌트인, TypedArray·DataView, 요소종류 전이, 표현형 변환까지 후보 sink를 전수로 d8에 때려봤고 전부 정화/트랩/in-range로 죽었다. 그리고 가장 뜻밖의 발견 — 이 버그류의 *의도된* 해법인 new Array(len) length-construction마저 이 빌드에선 막혀 있다. 패치가 typer.cc만 건드리고 js-create-lowering의 길이 보호는 안 풀어서다. 어긋남은 살아있는데(자연 티어업에서 INT_MIN으로 발산) 받아줄 sink가 없다. 끝으로 남은 한 수 — 배포 바이너리 직접 부검.
#dreamhack#ctf#pwn
BLOG2026-06-07
[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (2) — 이 버그를 죽인 V8 11.2 하드닝, 소스 부검 — DreamHack EXP-NaN
blog

[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (2) — 이 버그를 죽인 V8 11.2 하드닝, 소스 부검 — DreamHack EXP-NaN

1편에서 타입혼동을 인덱스까지 살려 보냈지만 거기서 트랩으로 끊겼다. 2편은 "왜 트랩인가"를 V8 11.2 소스로 부검한다. CheckBounds가 기계어가 되는 경로, typer가 인덱스를 in-bounds로 증명하면 검사를 제거가 아니라 abort로 바꾸는 무조건 하드닝(kAbortOnOutOfBounds), 그리고 doar-e식 우회를 정조준해 막아둔 element-access 빌더의 두 번째 CheckBounds까지 — 소스 주석째로 들고 본다. 끝으로, 같은 시기 하드닝 켜진 V8을 실제로 뚫은 익스(구글 v8CTF·openECSC)가 왜 값-range typer 버그가 아니라 length/element-kind를 직접 손상시키는 다른 버그 클래스를 쓰는지 대조한다.
#dreamhack#ctf#pwn
BLOG2026-06-06
[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (1) — 트리거는 됐는데 OOB가 안 자란다 — DreamHack EXP-NaN
blog

[💎 Diamond 1] Math.exp가 NaN을 잊을 때 (1) — 트리거는 됐는데 OOB가 안 자란다 — DreamHack EXP-NaN

d8 패치 한 줄이 TurboFan에게 "Math.exp는 절대 NaN을 만들지 않는다"고 거짓말을 시킨다. 하지만 Math.exp(NaN)은 NaN이다. 타입혼동 트리거까지는 깔끔하게 된다. 문제는 그 어긋남을 OOB로 키우는 단계 — NaN은 인덱스로 가는 모든 길에서 정화되고, Object.is 불리언은 폴딩되거나 Boolean으로 남고, 자연 티어업에선 어긋남이 인덱스까지 살아 도달하는데 거기서 11.2가 무조건 박아둔 kAbortOnOutOfBounds 하드닝이 트랩으로 끊어버린다. 이 글(1편)은 버그·트리거와, 공개된 typer-OOB 기법이 V8 11.2 하드닝에 어떻게 막히는지를 실측으로 끝까지 추적한다.
#dreamhack#ctf#pwn+6
#pwn
+6
 
#pwn
+7
 
+7
 
+7