Full Report
A recent vulnerability in PHP seemed like a good test for variant analysis in other systems. The vulnerability is an integer truncation and sign conversion bug that via an implicitly converts the value. They found a few bugs from this but found an interesting one within SQLite. The unsigned long (2*ZSTR_LEN(unquoted) + 3) is passed to sqlite3_snprintf as the first parameter, which expects a signed integer. The line of code in question is shown below: sqlite3_snprintf(2*ZSTR_LEN(unquoted) + 3, quoted, "'%q'", ZSTR_VAL(unquoted)); Why is this bad? The truncation and conversion has an interesting effect - the meaning of the number can be changed! For instance, a large unsigned number could turn into a negative signed number if not handled correctly. While writing up a quick proof of concept for this bug, they quick ran into an ASAN crash with MySQL in an entirely different location. SQLite has custom format strings, such as %q. While trying to execute the code above, they had ran into an implementation issue on one of the format string handlers. This vulnerability was a linear stack based buffer overflow resulting from an integer overflow. This overflow comes from a really simple addition (+3) being done on a variable without checking to see if this could somehow overflow. With this wildcopy type of crash, they wanted to find a way to write only the necessary bytes while making the overflow still happen. By adding a single quote (') and not finishing out the string, an inner loop could run that would input a ton of data but only output a limited amount. This allows for the overflowed size to be controllable AND the amount of bytes being output to also be controllable. Pretty neat trick! This allows for an overwrite of the RIP of the stack but we would need an information leak to leak the stack canary for this to work, sadly. SQLite has 100% branch test coverage and has fuzzing setup on it. How was this missed!? There is an internal memory limit of 1GB for SQLite itself. However, external programs, such as calling from the C API, don't have this limitation. By providing astronomically large values, it was possible to hit this. Additionally, 100% branch coverage means every line of code was hit but NOT how hard or how many times. I really appreciated this insight from Trail of Bits here. Overall, awesome and thorough post on the vulnerability and how they found it.
Analysis Summary
# Vulnerability: Integer Overflow and Stack Buffer Overflow in SQLite `printf` Implementations
## CVE Details
- CVE ID: CVE-2022-35737
- CVSS Score: Not explicitly provided in the text, but exploitation details suggest High severity (Arbitrary Code Execution possible).
- CWE: CWE-190 (Integer Overflow or Wraparound), CWE-121 (Stack-based Buffer Overflow)
## Affected Systems
- Products: SQLite library API usage, specifically where applications use `sqlite3_snprintf` (or related `printf` functions supporting `%Q`, `%q`, or `%w`) with large string inputs.
- Versions: SQLite version 1.0.12 (released October 17, 2000) through prior to 3.39.2 (released July 21, 2022).
- Configurations: Exploitable on 64-bit systems where large string inputs are passed combined with specific format specifiers (`%Q`, `%q`, or `%w`). Arbitrary code execution (ACE) is confirmed when compiled without stack canaries.
## Vulnerability Description
CVE-2022-35737 stems from two interacting issues originating from an implicit integer truncation/conversion bug (identified during analysis of a PHP bug) which leads to a direct stack-based buffer overflow in SQLite's custom `printf` implementations (specifically those handling `%Q`, `%q`, or `%w`).
1. **Integer Issue:** A calculation producing the required buffer size, `(2*ZSTR_LEN(unquoted) + 3)`, uses an `unsigned long` that is implicitly converted or truncated when passed as the size argument to `sqlite3_snprintf`, which expects a signed integer. Large values can wrap around to become negative, leading to incorrect size allocation or handling.
2. **Buffer Overflow:** An integer overflow occurs during a simple addition (`+3`) within the formatting logic, leading to an insufficient buffer size being calculated relative to the amount of data written. This results in a linear stack-based buffer overflow.
When the exploit uses specially crafted input—such as an unclosed quote character (`'`) in the input string containing large amounts of data—it allows the attacker to control both the size of the overflow and the amount of data written to the stack, potentially overwriting the RIP (Instruction Pointer).
## Exploitation
- Status: PoC available (Specific PoC for PHP PDO SQLite module and general SQLite focus described).
- Complexity: Medium/High (Requires specifically large inputs and potentially bypassing mitigation like stack canaries for ACE).
- Attack Vector: Likely Local or Adjacent, depending on how the vulnerable application accepts the large string input (e.g., via SQL query processing).
Impact details:
- **ACE:** Confirmed when stack canaries are absent.
- **Denial of Service (DoS):** Confirmed in all cases (program crash or infinite loop).
- **Control:** Achievable control over the overwritten stack RIP if canaries are bypassed.
## Impact
- Confidentiality: High (If ACE is achieved, data leakage is possible).
- Integrity: High (Arbitrary code execution allows for system modification).
- Availability: High (Confirmed Denial of Service via crash or infinite loop).
## Remediation
### Patches
- SQLite version **3.39.2**, released July 21, 2022, contains the fix.
- Applications using the SQLite library should upgrade to this version or later.
### Workarounds
- Compile the SQLite library with security features enabled, such as stack canaries/stack protectors, which confirmed a DoS condition but prevented confirmed ACE in that specific scenario.
- Avoid passing astronomically large string inputs to `sqlite3_snprintf` when using format specifiers `%Q`, `%q`, or `%w`.
- Since the vulnerability was triggered via the PHP PDO SQLite module in the initial finding, disabling or avoiding the use of these specific format specifiers in custom quoting functions may serve as a temporary mitigation if upgrading is impossible.
## Detection
- **Indicators of Compromise:** Crashes or abnormal termination of applications linked against vulnerable SQLite versions, especially when dealing with exceptionally large string data processed via SQL quoting mechanisms.
- **Detection Methods and Tools:** Static analysis tools looking for integer overflow leading to buffer overflows, especially around `sqlite3_snprintf` calls involving user-controlled variable sizes interacting with signed/unsigned conversions.
## References
- Vendor Advisory (SQLite Fix): hxxps://www.sqlite.org/releaselog/3_39_2.html
- Vulnerability Disclosure (Trail of Bits): hxxps://blog.trailofbits.com/2022/10/25/stranger-strings-an-exploitable-flaw-in-sqlite/
- NVD Entry: hxxps://nvd.nist.gov/vuln/detail/CVE-2022-35737
- PoC Exploits: hxxps://github.com/trailofbits/exploits/tree/main/sqlite3-2022-vappendf