## https://sploitus.com/exploit?id=4821D68D-41FC-5A67-AFDE-A3B9D9382B77
# PNG Parser Vulnerability Research
A reverse-engineering and exploit-development case study focused on a stripped, statically linked x86-64 PNG metadata parser.
The project investigates how malformed PNG metadata can expose memory-safety weaknesses in native software. It combines binary analysis, custom test-case generation, vulnerability validation, information-leak analysis and return-oriented programming research in a controlled Linux lab environment. This project was developed as a part of COMP4703 Vulnerability Research and Exploit Mitigation at the Australian National University.
## Project Summary
The target was a stripped **static-PIE** Linux binary that parsed and displayed PNG metadata. The investigation identified an embedded version of **libpng 1.6.28** and examined unsafe handling of PNG text metadata.
The analysis produced two main findings:
1. **Stack-based buffer overflow** โ an oversized `tEXt` metadata value reaches an application callback that copies attacker-controlled data into a fixed-size stack buffer without an adequate application-level bounds check.
2. **Stack information disclosure** โ a profile-formatting routine can request more output bytes than its local buffer contains, exposing adjacent stack data, including a stack canary and a code pointer.
The project also explored how the findings could be combined into a multi-stage exploit under modern mitigations. A ROP chain and same-process FIFO staging technique were designed, but the final control-flow stage is blocked by a `strlen()` constraint: the null byte in the valid stack canary terminates the copied text before the return address can be reached.
This limitation is documented deliberately. The repository demonstrates a rigorous security investigation rather than claiming an end-to-end exploit that was not achieved.
## Key Outcomes
- Identified a third-party library and exact version inside a stripped static binary.
- Built and applied custom **Ghidra Function ID databases** for glibc and libpng.
- Recovered application and library function boundaries from a binary containing more than one statically linked codebase.
- Generated valid and malformed PNG files directly from Python using binary packing, CRC calculation and zlib compression.
- Determined the precise stack-buffer boundary through controlled test cases.
- Analysed active mitigations including **ASLR, PIE, NX, Full RELRO and stack canaries**.
- Developed a reliable PNG-triggered information leak for recovering process-specific values.
- Designed a ROP chain for `setuid` and `execve` and documented why it cannot be reached under the discovered copy semantics.
- Compared vulnerable and patched parser behaviour to validate the root cause.
## Technical Skills Demonstrated
### Reverse engineering
- Ghidra static analysis and function renaming
- Function ID database construction and matching
- x86-64 disassembly and stack-frame analysis
- Identification of application code within statically linked libraries
- Cross-referencing strings, call sites and imported library behaviour
### Vulnerability research
- Stack-buffer overflow analysis
- Information-disclosure analysis
- Stack canary recovery
- ASLR/PIE base-address calculation
- Root-cause analysis across library and application boundaries
- Controlled crash reproduction and boundary testing
### Exploit development
- Python and pwntools
- ROP gadget discovery and chain construction
- Linux x86-64 syscall conventions
- SUID process and real/effective UID behaviour
- Multi-stage exploit orchestration with named pipes
- Binary parsing with `struct`, `zlib` and CRC32
### Engineering and communication
- Reproducible test-case generators
- Clear documentation of assumptions and blockers
- Evidence-driven debugging
- Technical reporting and security impact explanation
- Honest distinction between demonstrated behaviour and proposed exploitation
## Repository Contents
| File | Purpose |
|---|---|
| `exploit.py` | Research harness that generates the leak and overflow PNGs, parses leaked values and documents the proposed ROP stage. |
| `make_text_cases.py` | Generates normal, oversized, malformed and compressed PNG metadata cases for differential testing. |
| `make_png.py` | Low-level helpers for constructing valid PNG chunks and files. |
| `libc_zoo.c` | Reference program used to build a Ghidra Function ID database for common libc functions. |
| `libpng_zoo.c` | Reference program used to build a Function ID database for libpng functions. |
| `Makefile` | Build targets for the reference binaries used during FID analysis. |
| `WRITE-UP.md` | Detailed technical methodology, findings, mitigation analysis and exploit-development notes. |
| `CHECKPOINT-1.md` / `CHECKPOINT-2.md` | Historical investigation notes retained for traceability. Consider excluding these from a public portfolio repository. |
| `*.fidb` | Ghidra Function ID databases generated for the analysis environment. |
| `*.gar` | Archived Ghidra project containing reverse-engineering annotations. |
## Investigation Workflow
```text
Initial reconnaissance
โ
Identify architecture, linking model and mitigations
โ
Recover embedded library and exact version
โ
Build libc and libpng FID reference databases
โ
Apply signatures and isolate application functions
โ
Generate targeted PNG metadata test cases
โ
Reproduce overflow and determine exact boundary
โ
Locate and analyse stack information disclosure
โ
Recover canary and PIE base at runtime
โ
Design same-process staging and ROP chain
โ
Document the strlen/canary constraint blocking control-flow hijack
```
## Requirements
The analysis was developed for a controlled **Ubuntu 22.04 x86-64** environment.
Recommended tools:
- Python 3.10+
- pwntools
- Ghidra
- GCC and Make
- GDB with GEF or a similar extension
- `file`, `strings`, `readelf`, `objdump` and `checksec`
Install the Python dependency in a virtual environment:
```bash
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install pwntools
```
## Running the Safe Test-Case Generator
Generate the PNG test corpus:
```bash
python3 make_text_cases.py
```
This creates several files representing normal and malformed metadata conditions, including:
- a normal `tEXt` chunk;
- a very large `tEXt` chunk;
- many repeated text chunks;
- malformed text without a required null separator;
- oversized compressed and international text metadata.
These files should only be opened with software you are authorised to test. A crash is possible when a vulnerable parser processes them.
## Running the Research Harness
The exploit-development harness expects an authorised local test binary:
```bash
python3 exploit.py /path/to/authorised/pngviewer
```
The script:
1. creates an information-leak PNG;
2. starts the target with a regular PNG and a named FIFO;
3. reads the first-stage leak;
4. extracts the stack canary and return address;
5. calculates the PIE image base;
6. generates the second-stage overflow test case;
7. records whether the target exits, crashes or reaches the proposed control-flow stage.
### Current status
| Stage | Status |
|---|---|
| Library/version identification | Complete |
| Controlled overflow reproduction | Complete |
| Stack information leak | Complete |
| Canary extraction | Complete |
| PIE base calculation | Complete |
| ROP chain design | Complete |
| End-to-end shell | **Not achieved** |
The ROP stage is not reached because the text length is determined with `strlen()`. A valid stack canary begins with a null byte, so including the correct canary at the overflow boundary causes the copy length to stop before the saved return address. Replacing that byte allows the overwrite to continue but causes stack-canary validation to abort the process.
## Building the Ghidra FID Reference Binaries
Review the paths and compiler settings in the `Makefile`, then build the reference programs:
```bash
make libc_zoo
make libpng_zoo
```
The reference binaries can then be imported into Ghidra and used to populate Function ID databases. Compiler version, optimisation level, static-linking configuration and library version should closely match the target; otherwise signature quality will be reduced.
## Real-World Relevance
Image parsers operate on untrusted files and are used in browsers, document systems, messaging applications, content-management platforms and backend processing pipelines. A flaw in metadata handling can therefore affect much more than a standalone image viewer.
This case study reflects practical security work performed during:
- vulnerability research and product-security assessments;
- malware and crash-sample triage;
- reverse engineering of stripped software;
- secure-code reviews of native parsers;
- incident response involving malformed media files;
- verification that vendor patches correctly reject dangerous input.
It also demonstrates an important real-world lesson: a vulnerable dependency does not act alone. Exploitability depends on how the application uses library output, the process privilege model, compiler mitigations, runtime layout and subtle string-handling behaviour.
## Defensive Lessons
The findings reinforce several secure-development practices:
- Validate untrusted lengths at every trust boundary, including application callbacks.
- Never assume a library-provided length is safe for a fixed-size destination.
- Use the actual number of bytes stored by `snprintf`, not the number that would have been written to an unlimited buffer.
- Prefer size-aware interfaces and dynamically sized buffers for metadata.
- Test parsers with oversized, malformed, repeated and compressed ancillary chunks.
- Keep third-party parsing libraries patched and verify patch behaviour with regression tests.
- Treat crashes as security-relevant until their reachability and impact are understood.
## Limitations and Future Work
Possible extensions include:
- replacing the original assessment binary with a purpose-built open-source demonstration target;
- adding automated regression tests for vulnerable and patched behaviour;
- integrating AddressSanitizer and UndefinedBehaviorSanitizer builds;
- converting the PNG corpus into a coverage-guided fuzzing seed set;
- adding structured logging and machine-readable test results;
- investigating alternate primitives that do not depend on copying a null-containing canary through `strlen()`;
- documenting remediation through a minimal vulnerable/patched code comparison.
## Authors
**Shiv Suresh**
Australian National University
**Sarthak Pathak**
Australian National University