# msilib.OpenDatabase Type Confusion

msilib.OpenDatabase passed an arbitrary persist value to MsiOpenDatabase, which treats large values as string pointers, causing type confusion and arbitrary memory read.

- Payout: $1,000
- Severity: medium
- Program: Internet Bug Bounty
- Credited: johnleitch
- Disclosed: 2016-09-20
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/167688
- Library page: https://bugbountylibrary.com/r/h1%3A167688
- Tags: domain:desktop impact:data-leak impact:dos kind:bounty platform:hackerone sev:medium tech:python tech:windows technique:source-review vuln:info-disclosure vuln:memory-corruption

**Target:** msilib.OpenDatabase (Python stdlib, Windows msi.dll)
**Root cause:** MsiOpenDatabase's szPersist parameter is overloaded: MSIDBOPEN_* constants select a mode, but larger values are dereferenced as a string pointer. msilib.OpenDatabase forwarded the persist argument without whitelist validation.
**Steps:**
1. Run `import msilib; msilib.OpenDatabase("", 0x41414141)` on Windows Python 2.7
2. Observe crash in KERNELBASE!lstrlenA reading address 0x41414141
3. Confirm stack: msiopendb -> CApiConvertString -> lstrlenA dereferences persist as pointer
**How found:** Code review of msilib.OpenDatabase's pass-through of persist to MsiOpenDatabase, combined with knowledge of the win32 API's overloaded szPersist semantics; confirmed via debugger crash dump.
**Exploitation:** Not demonstrated end-to-end; author theorizes ASLR/DEP probing, arbitrary memory disclosure, and heap spray to control the persist string and create an MSI at an attacker-chosen path for potential RCE.
**Escalation:** Theorized chain: memory spray -> controlled persist pointer -> attacker-controlled MSI file creation -> RCE.
**Insight:** When a Python wrapper forwards an int to a Win32 API parameter that is overloaded as either a constant or a pointer, fuzz the boundary values (e.g. 0x41414141) to expose type confusion in the underlying DLL.
