
PoC for CVE-2026-2005
PoC exploit for a heap-based buffer overflow in the PostgreSQL pgcrypto
extension's PGP session key parsing, leading to arbitrary memory read/write
and privilege escalation to superuser.
For full technical details, see the Zeroday Cloud advisory.

Clone and compile PostgreSQL from the vulnerable commit so the binary's symbol offsets match exactly. The exploit resolves the ASLR base by matching leaked pointers against ELF symbol offsets - different builds or versions will have different offsets and will fail.
git clone https://github.com/postgres/postgres.git
cd postgres
git checkout 4b324845ba5d24682b9b3708a769f00d160afbd7
./configure \
--prefix="$HOME/projects/pg/pgsql" \
--with-libxml \
--with-libxslt \
--enable-debug \
--with-ssl=openssl
make -j$(nproc)
make install-world-bin
pip install -r requirements.txt
python poc.py \
--binary "$HOME/projects/pg/pgsql/bin/postgres" \
--dbname test-db \
--host 127.0.0.1 \
--port 5432 \
--user test-user \
--password secret \
--cmd id
The exploit proceeds in 7 stages:
Heap pointer leak - A crafted PGP message corrupts the mdst buffer's
malloc chunk header. When PostgreSQL calls pfree() on the corrupted chunk,
the allocator emits an error containing the pointer address, leaking the
heap location of mdst->data.
Arbitrary read - A second overflow overwrites mdst->data to point at
(leaked_ptr - 0x10000). After decryption, mbuf_steal_data() returns
the contents at that address as decrypted output, dumping heap memory that
may contain stale code pointers.
Pointer scan - The hex dump is scanned for 8-byte little-endian values
that look like code addresses (>= 0x500000000000) but are not in the
heap region. These are candidate PIE (Position Independent Executable)
pointers.
PIE base voting - Each candidate address is tested against ELF symbol
offsets from the postgres binary. For each (addr - sym_offset) pair
where the page offset matches, a vote is cast. Candidates with 10+ votes
are kept; the smallest base (PIE is the lowest-mapped ELF segment) sorted
by votes is the top candidate.
PIE base validation - Using the arbitrary read primitive, the exploit
reads CurrentUserId at and
compares it against the session's known OID. A match confirms the PIE base.
pip install -r requirements.txt)pgcrypto enabledThis Proof of Concept is for educational and defensive research purposes only. Use only against systems you own or have explicit authorization to test.
| Argument | Default | Description |
|---|
--binary | (postgres binary) | Path to postgres binary for symbol extraction |
--dbname | postgres | Target database name |
--host | localhost | PostgreSQL host |
--port | 5432 | PostgreSQL port |
--user | postgres | Database user |
--password | (empty) | Database password |
--cmd | whoami | OS command to execute after privilege escalation |
--gdb | (flag) | Attach GDB via tmux at the overflow point |
(candidate_base + current_user_offset)Arbitrary write - The overflow corrupts both msrc and mdst MBuf
headers. Forged msrc->data/read_pos point at an embedded sym-encrypted
packet containing encrypted superuser OID (10). Forged mdst->data points
at CurrentUserId - 4 (the -4 accounts for SET_VARSIZE in
pgp-pgsql.c:533 writing the output length into the first 4 bytes).
Privilege escalation - With CurrentUserId overwritten to 10
(bootstrap superuser), COPY FROM PROGRAM executes the specified OS
command as the postgres system user.