## https://sploitus.com/exploit?id=3E770CA1-3FD1-5CD8-90A6-AA20D9AD021C
# Chrome Issue 992914 โ 32-bit Port (Windows)
> **๋ค์ ์ฌ๋ฆฌ๋ ์ด์ / Re-upload notice**
>
> **KR** โ 2019๋
Exodus Intelligence๊ฐ ๊ณต๊ฐํ 64๋นํธ ์ต์คํ๋ก์์ ์ ๊ฐ **32๋นํธ Windows Chrome์ฉ์ผ๋ก ํฌํ
**ํ๋ฉด์ ์ ๋ฆฌํด ๋ ์๋ฃ์
๋๋ค. ์์ ์ GitHub์ ์ฌ๋ ธ๋ค๊ฐ ๋ด๋ ธ๋ ์ ์ฅ์๋ฅผ, ๊ธฐ๋ก ๋ณด์กด ์ฐจ์์์ ๊ทธ๋๋ก ๋ค์ ๊ณต๊ฐํฉ๋๋ค. (์์ฑ ์์ : 2019~2021, ๋ด์ฉ์ ๋น์ ๊ทธ๋๋ก์ด๋ฉฐ ์ดํ ๊ฐฑ์ ์์)
>
> **EN** โ This is an old project: a **32-bit Windows port** of Exodus Intelligence's original 64-bit exploit for Chromium bug 992914. It was published here years ago, taken down, and is now **re-uploaded as-is for archival purposes**. Written 2019โ2021; unchanged since.
---
## ๊ฐ์ / Overview
**KR** โ Chromium V8์ **sealed/frozen elements kind type confusion** (Chromium bug **992914**) ์ทจ์ฝ์ ์ต์คํ๋ก์์
๋๋ค. ์๋ณธ์ Exodus Intelligence์ "patch-gapping" ์ฐ๊ตฌ์์ ๊ณต๊ฐ๋ **64๋นํธ** ๋ฒ์ ์ด๊ณ , ์ด ์ ์ฅ์๋ ์ด๋ฅผ **32๋นํธ Chrome (Windows)** ํ๊ฒฝ์ ๋ง๊ฒ ๋ณํํ ๊ฒ์
๋๋ค.
**EN** โ The bug is a type confusion in V8's handling of sealed/frozen element kinds (Chromium bug **992914**). Exodus published a working **64-bit** exploit as part of their patch-gapping research; this repository contains a **32-bit Windows port** of that exploit, together with the slide deck describing how the conversion was done.
* **Original 64-bit exploit author / ์๋ณธ 64๋นํธ ์ต์คํ๋ก์ ์ ์:** Exodus Intelligence
* **32-bit port / 32๋นํธ ๋ณํ:** this repository
* **Tested on / ํ
์คํธ ํ๊ฒฝ:** Windows 10, **32-bit** Chrome 76.0.3809.100 / 76.0.3809.132
## ์ด ๋ฌธ์์ ๋ชฉ์ / Purpose
**KR** โ ๋จ์ํ ๋์ํ๋ ์ต์คํ๋ก์์ ํ๋ ๋ ๊ณต๊ฐํ๋ ค๋ ๊ฒ์ด ์๋๋ผ, **64๋นํธ ์ต์คํ๋ก์์ 32๋นํธ๋ก ์ง์ ์ด์ํด ๋ณด๋ ๊ณผ์ ์ ํตํด ํฌ๋กฌ(V8) ์ต์คํ๋ก์์ ๋ํ ์ดํด์ ํญ์ ๋ํ๋ ๊ฒ**์ด ์ด ์๋ฃ์ ๋ชฉ์ ์
๋๋ค.
๋จ์ด ๋ง๋ 64๋นํธ ์ต์คํ๋ก์์ ๊ทธ๋๋ก ์คํํด ๋ณด๋ ๊ฒ๊ณผ, ๊ทธ๊ฒ์ ๋ค๋ฅธ ์ํคํ
์ฒ๋ก ์ฎ๊ธฐ๋ ๊ฒ์ ์๊ตฌ๋๋ ์ดํด๋๊ฐ ๋ค๋ฆ
๋๋ค. ํฌํ
์ ํ๋ ค๋ฉด ๊ฐ ๋จ๊ณ๊ฐ *์* ๊ทธ๋ ๊ฒ ๋์ํ๋์ง๋ฅผ ์์์ผ ํ๊ณ , ๊ทธ ๊ณผ์ ์์ ์์ฐ์ค๋ฝ๊ฒ ๋ค์์ ํ๊ณ ๋ค๊ฒ ๋ฉ๋๋ค.
* V8์ ๊ฐ์ฒด ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์ โ Map, elements, properties backing store๊ฐ ํ์ ์ด๋ป๊ฒ ๋ฐฐ์น๋๋๊ฐ
* 32๋นํธ์์์ SMI/ํฌ์ธํฐ ํ๊น
๊ณผ double ํํ โ ์ ํ๋์ double(64๋นํธ) ์์ 32๋นํธ ํฌ์ธํฐ ๋ ๊ฐ๋ฅผ ๋ฃ์ด ๋ค๋ค์ผ ํ๋๊ฐ
* 64๋นํธ ๊ธฐ์ค์ผ๋ก ํ๋์ฝ๋ฉ๋ ์คํ์
ยท์ธ๋ฑ์ค๋ฅผ 32๋นํธ ๊ธฐ์ค์ผ๋ก ์ด๋ป๊ฒ ๋ค์ ๊ณ์ฐํ๋๊ฐ
* `WebAssembly.Instance` โ `WasmExportedFunctionData` โ RWX ํ์ด์ง๋ก ์ด์ด์ง๋ ์ฝ๋ ์คํ ์ฒด์ธ์ด ์ํคํ
์ฒ๋ณ๋ก ์ด๋ป๊ฒ ๋ฌ๋ผ์ง๋๊ฐ
* d8๊ณผ ์ค์ ๋ธ๋ผ์ฐ์ ์์ ํ ์ํ๊ฐ ์ด๋ป๊ฒ ๋ฌ๋ผ์ง๊ณ , ๊ทธ๊ฒ์ด ์ต์คํ๋ก์ ์ ๋ขฐ์ฑ์ ์ด๋ค ์ํฅ์ ์ฃผ๋๊ฐ
์ฒจ๋ถํ ๋ฐํ ์๋ฃ(`.pptx`)๋ ์ด ๋ณํ ๊ณผ์ ์ ๋จ๊ณ๋ณ๋ก ๋ฐ๋ผ๊ฐ๋ฉฐ ์ ๋ฆฌํ ๊ฒ์ผ๋ก, ๊ฒฐ๊ณผ๋ฌผ์ธ ์ฝ๋๋ณด๋ค **๊ฑฐ๊ธฐ๊น์ง ๊ฐ๋ ๊ณผ์ **์ ์ด์ ์ ๋ง์ถ๊ณ ์์ต๋๋ค.
**EN** โ The point of this repository is not to publish yet another working exploit. It is to use the **port from 64-bit to 32-bit as a vehicle for broadening one's understanding of Chrome/V8 exploitation**.
Running someone else's 64-bit exploit and moving that exploit to a different architecture demand very different levels of understanding. Porting it requires knowing *why* each step works the way it does, and in doing so you end up digging into:
* V8's object memory layout โ how the Map, elements, and properties backing stores are arranged on the heap
* SMI/pointer tagging and double representation on 32-bit โ why a single 64-bit double has to carry and be manipulated as two 32-bit pointers
* How offsets and indices hardcoded for 64-bit must be recomputed for 32-bit
* How the `WebAssembly.Instance` โ `WasmExportedFunctionData` โ RWX page code-execution chain differs between architectures
* How the heap state differs between d8 and the real browser, and what that does to exploit reliability
The attached slide deck (`.pptx`) walks through the conversion step by step; it focuses on **the reasoning that leads to the result** rather than on the finished code.
## ํ์ผ ๊ตฌ์ฑ / Files
| File | ์ค๋ช
/ Description |
| --- | --- |
| `exp_32bit.html` | **KR** ์ต์คํ๋ก์ ์ง์
์ . `print()` / `hex()` / `hexdump()` ํฌํผ๋ฅผ ์ ์ํ๊ณ `chrome_992914_32bit.js`๋ฅผ ๋ก๋ํฉ๋๋ค.**EN** Exploit entry point. Defines the `print()` / `hex()` / `hexdump()` helpers and loads `chrome_992914_32bit.js`. |
| `chrome_992914_32bit.js` | **KR** ๋ธ๋ผ์ฐ์ ์ฉ 32๋นํธ ์ต์คํ๋ก์ ๋ณธ์ฒด (type confusion โ addrof/AAR/AAW โ WASM RWX โ shellcode).**EN** The 32-bit exploit itself, for the browser (type confusion โ addrof/AAR/AAW โ WASM RWX โ shellcode). |
| `d8_32bit_ex.js` | **KR** d8(V8 ์
ธ)์์ ๋๋ฒ๊น
์ฉ์ผ๋ก ์ฐ๋ ๋ณํ๋ณธ. ๋ก๊ทธ๊ฐ ๋ ์์ธํ๊ณ ์ผ๋ถ ๋จ๊ณ๊ฐ ์ฃผ์ ์ฒ๋ฆฌ๋์ด ์์ต๋๋ค.**EN** A variant used for debugging under d8 (the V8 shell): more verbose logging, with some stages commented out. |
| `How_to_convert_Chrome_Issue992914_exploit_to_32-bit_on_Windows.pptx` | **KR** 64๋นํธ โ 32๋นํธ ๋ณํ ๊ณผ์ ์ ์ ๋ฆฌํ ๋ฐํ ์๋ฃ (์ฝ 34MB).**EN** Slide deck documenting the 64-bit โ 32-bit conversion (~34 MB). |
## ๋์ ๋ฐฉ์ ์์ฝ / How it works
**KR**
1. Sealed/frozen element kind ํ์
ํผ๋์ ์ด์ฉํด ์ธ์ ํ `float_array`์ ๊ธธ์ด/๋ฐ์ดํฐ ํฌ์ธํฐ๋ฅผ ๊นจ๋จ๋ฆฝ๋๋ค.
2. ๊นจ์ง float ๋ฐฐ์ด๋ก **relative OOB read/write**๋ฅผ ์ป๊ณ , ์ด๋ฅผ `addrof` ํ๋ฆฌ๋ฏธํฐ๋ธ๋ก ํ์ฅํฉ๋๋ค.
3. 32๋นํธ์์๋ ํ๋์ double(64๋นํธ) ์์ ๋ ๊ฐ์ 32๋นํธ ํฌ์ธํฐ๊ฐ ๋ค์ด๊ฐ๋ฏ๋ก, `setHighUint32()` / `float_to_low_32bit()` ๊ฐ์ ํฌํผ๋ก ์ยทํ์ 32๋นํธ๋ฅผ ๋๋ ๋ค๋ฃจ๋ฉฐ **์์ ์ฃผ์ ์ฝ๊ธฐ/์ฐ๊ธฐ(AAR/AAW)** ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
4. `WebAssembly.Instance` โ `WasmExportedFunctionData` โ instance ์ค๋ธ์ ํธ๋ฅผ ๋ฐ๋ผ๊ฐ **RWX ํ์ด์ง ์ฃผ์**๋ฅผ ์ป์ต๋๋ค.
5. RWX ํ์ด์ง์ ์
ธ์ฝ๋๋ฅผ ์ฐ๊ณ , ์ต์คํฌํธ๋ WASM ํจ์(`wfunc()`)๋ฅผ ํธ์ถํด ์คํํฉ๋๋ค.
๊ธฐ๋ณธ ์
ธ์ฝ๋๋ PEB ์ํน์ผ๋ก `WinExec`๋ฅผ ์ฐพ์ **`calc`** ๋ฅผ ์คํํ๋ 32๋นํธ ์ฝ๋์
๋๋ค (`chrome_992914_32bit.js`์ `shellcode` ๋ฐฐ์ด). ํ ์ํ์ ๋ฐ๋ผ ์คํจํ ์ ์์ด ์ต๋ 500ํ ๋ฐ๋ณตํ๊ณ , ๊ทธ๋๋ ์คํจํ๋ฉด 2์ด ๋ค ํ์ด์ง๋ฅผ ๋ฆฌ๋ก๋ํด ์ฌ์๋ํฉ๋๋ค.
**EN**
1. The sealed/frozen element kind type confusion is used to corrupt the length/data pointer of an adjacent `float_array`.
2. The corrupted float array yields a **relative OOB read/write**, which is extended into an `addrof` primitive.
3. On 32-bit, a single 64-bit double holds two 32-bit pointers, so helpers such as `setHighUint32()` / `float_to_low_32bit()` split it into high and low halves to build **arbitrary address read/write (AAR/AAW)**.
4. Following `WebAssembly.Instance` โ `WasmExportedFunctionData` โ the instance object yields the address of an **RWX page**.
5. The shellcode is written into that RWX page and executed by calling the exported WASM function (`wfunc()`).
The default shellcode is 32-bit code that walks the PEB to resolve `WinExec` and launches **`calc`** (see the `shellcode` array in `chrome_992914_32bit.js`). Because success depends on heap state, the exploit retries up to 500 times, then reloads the page after 2 seconds and tries again.
## ์คํ ๋ฐฉ๋ฒ / Usage
**KR**
1. **32๋นํธ** Chrome 76.0.3809.100 ๋๋ 76.0.3809.132 ๋ฅผ `--no-sandbox` ๋ก ์คํํฉ๋๋ค.
2. ์ด ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ก์ปฌ ์น์๋ฒ๋ก ํธ์คํ
ํฉ๋๋ค. (์: `python -m http.server 8000`)
3. ๋ธ๋ผ์ฐ์ ์์ `http://localhost:8000/exp_32bit.html` ์ ์ ์ํฉ๋๋ค.
4. ์ฑ๊ณตํ๋ฉด ๊ณ์ฐ๊ธฐ๊ฐ ๋น๋๋ค. ์งํ ๋ก๊ทธ๋ DevTools ์ฝ์์์ ํ์ธํ ์ ์์ต๋๋ค.
**EN**
1. Launch **32-bit** Chrome 76.0.3809.100 or 76.0.3809.132 with `--no-sandbox`.
2. Host this directory with a local web server (e.g. `python -m http.server 8000`).
3. Browse to `http://localhost:8000/exp_32bit.html`.
4. On success, the calculator pops. Progress messages are visible in the DevTools console.
```
chrome.exe --no-sandbox
python -m http.server 8000
```
d8๋ก ๋๋ฒ๊น
ํ ๋ / For debugging under d8:
```
d8.exe --allow-natives-syntax d8_32bit_ex.js
```
## ์ฃผ์ / Disclaimer
**KR**
* ๋์ ์ทจ์ฝ์ ์ **2019๋
์ ์ด๋ฏธ ํจ์น**๋์์ต๋๋ค. ์ต์ Chrome์์๋ ๋์ํ์ง ์์ต๋๋ค.
* ์ด ์ฝ๋๋ **์ฐ๊ตฌยท๊ต์ก ๋ชฉ์ **์ผ๋ก๋ง ๊ณต๊ฐํฉ๋๋ค. ๋ฐ๋์ ๋ณธ์ธ ์์ ์ด๊ฑฐ๋ ๋ช
์์ ์ผ๋ก ํ๊ฐ๋ฐ์ ๊ฒฉ๋ฆฌ๋ ํ
์คํธ ํ๊ฒฝ์์๋ง ์คํํ์ธ์.
* ์
ธ์ฝ๋๊ฐ ํฌํจ๋์ด ์์ผ๋ฏ๋ก ์ค ์ฌ์ฉ ์ค์ธ ๋จธ์ ์์ ์คํํ์ง ๋ง์๊ณ , VM์์ ํ
์คํธํ์๊ธฐ ๋ฐ๋๋๋ค.
* ์๋ณธ ์ต์คํ๋ก์์ ์ ์๊ถ/ํฌ๋ ๋ง์ Exodus Intelligence์ ์์ต๋๋ค.
**EN**
* The vulnerability was **patched back in 2019**. This does not work against current Chrome.
* Published for **research and educational purposes only**. Run it only in an isolated test environment you own or have explicit permission to test.
* It contains shellcode โ do not run it on a machine you actually use; test in a VM.
* Credit and copyright for the original exploit belong to Exodus Intelligence.
---
*Originally written 2019โ2021. Re-uploaded unchanged. / 2019~2021๋
์์ฑ, ๋ด์ฉ ๋ณ๊ฒฝ ์์ด ์ฌ์
๋ก๋.*