BLOG2026-06-07
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#pwn+7