Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1336 CNY

100%

CVE-2025-1094 PoC — PostgreSQL quoting APIs miss neutralizing quoting syntax in text that fails encoding validation

Source
Associated Vulnerability
Title:PostgreSQL quoting APIs miss neutralizing quoting syntax in text that fails encoding validation (CVE-2025-1094)
Description:Improper neutralization of quoting syntax in PostgreSQL libpq functions PQescapeLiteral(), PQescapeIdentifier(), PQescapeString(), and PQescapeStringConn() allows a database input provider to achieve SQL injection in certain usage patterns. Specifically, SQL injection requires the application to use the function result to construct input to psql, the PostgreSQL interactive terminal. Similarly, improper neutralization of quoting syntax in PostgreSQL command line utility programs allows a source of command line arguments to achieve SQL injection when client_encoding is BIG5 and server_encoding is one of EUC_TW or MULE_INTERNAL. Versions before PostgreSQL 17.3, 16.7, 15.11, 14.16, and 13.19 are affected.
Description
It is an input sanitization flaw caused by an encoding mismatch, allowing crafted input to bypass filters. If a server is vulnerable, an attacker can inject malicious SQL that the backend executes.
Readme
#I have written this exploit with reference to the PoC available at [CVE-2025-1094](https://github.com/ishwardeepp/CVE-2025-1094-PoC-Postgre-SQLi/)

# CVE‑2025‑1094 | PostgreSQL Input Sanitization Vulnerability 

## Overview

**CVE‑2025‑1094** is an input sanitization vulnerability in PostgreSQL’s `libpq` escape functions and the `psql` interactive tool. It stems from the improper handling of multi-byte encodings when the client encoding is set to `BIG5`. Under certain conditions, this can lead to the mishandling of escape characters, allowing attackers to bypass intended query boundaries.

This vulnerability was discovered by Rapid7 during analysis of CVE‑2024‑12356, a separate issue in BeyondTrust appliances. The PostgreSQL behavior was exploited as part of a broader chained vulnerability to further influence backend behavior.

## How It Works

When a web server or application passes user input directly into SQL queries executed through `psql`, and the `client_encoding` is set to `BIG5`, specially crafted input can terminate a SQL statement early and append malicious SQL.

This allows for additional operations such as reading local files (e.g., `/etc/passwd`) via PostgreSQL’s `lo_export`, `pg_read_file`, or similar functions.

This is not a remote code execution (RCE) vulnerability in PostgreSQL by default. Rather, it is a misuse of PostgreSQL client APIs that, when improperly filtered or escaped, can be abused to leak sensitive file contents or potentially execute dangerous SQL.

## Impact

* Enables file read access from the PostgreSQL server if configured insecurely.
* Allows attackers with valid credentials to exploit `COPY TO`, `pg_read_file`, or `lo_export` when combined with SQL injection in client applications.
* Exploits are only effective when the client encoding is `BIG5` and input is not properly sanitized.


## Conditions Required for Exploitation

* The attacker has valid PostgreSQL credentials (authenticated context) or Access to web server which send inputs direclty to PostgreSQL server.
* The backend SQL is PostgreSQL and uses a vulnerable version (prior to patched versions in June 2025).
* The application directly passes unsanitized input into SQL.
* The PostgreSQL client is configured with `client_encoding=BIG5`.

## Exploit Demonstration

```python
import psycopg2

conn = psycopg2.connect(
    host="127.0.0.1",
    dbname="test",
    user="test",
    password="Test"
)
conn.set_client_encoding("BIG5")
cursor = conn.cursor()

# Payload to read /etc/passwd into a server-accessible file
sql = \
"""
DO $$ DECLARE f text; BEGIN f := pg_read_file('/etc/passwd', 0, 1000);
RAISE NOTICE '%%', f; END $$;
"""

cursor.execute(sql)
conn.commit()
```

##✅ What Does This Exploit.py do:

Sets PGCLIENTENCODING=BIG5 in the environment (trigger condition).

Crafts an SQL injection payload to break out of a query and insert a new COPY TO PROGRAM command.

Sends the payload via a GET request to the vulnerable web server (/search?q=...).

If the backend uses psql and unsanitized input, the COPY TO PROGRAM executes and writes the result or opens a shell.

⚠️ The reverse shell will only succeed if the server:

    Executes SQL using psql (not parameterized DB drivers)

    Allows COPY TO PROGRAM (requires superuser)

    Has outbound connectivity to the attacker

#The Python script sends a specially crafted payload to a vulnerable web server that passes input directly to a PostgreSQL psql process with BIG5 encoding:
Steps to Use:

Start a listener on the terminal:

```nc -lvnp 4444```

Edit the exploit script:

  Set TARGET_URL to the target server’s IP or domain.
  Confirm the ENDPOINT matches the route (e.g., /search).
  Adjust REVERSE_IP and REVERSE_PORT to match your attack box.

Execute the script in Different Terminal :

```python3 exploit.py```

Result: If successful, you will receive a connection on your listener. If not, try reading files (e.g., /etc/passwd) using pg_read_file payloads instead.

## Lab Environment

To test this:

* PostgreSQL 14.x (or earlier vulnerable versions).
* Initialized with `EUC_TW` or similar encoding.
* The application layer (e.g., Flask) interacts with PostgreSQL using `psql` or unescaped dynamic SQL.
* The PostgreSQL user must have access to functions like `pg_read_file` or `lo_export`.

## Mitigations

* Upgrade to patched PostgreSQL versions (≥ 17.3, 16.7, 15.11, 14.16, 13.19).
* Avoid `client_encoding=BIG5` unless explicitly needed.
* Never pass raw user input into SQL execution contexts.
* Use prepared statements and input validation libraries.

## References

* Rapid7 Blog: [Technical Analysis](https://attackerkb.com/topics/cve-2025-1094)
* PostgreSQL Advisory: [Security Release June 2025](https://www.postgresql.org/about/news/)
* CVE Details: [CVE-2025-1094](https://nvd.nist.gov/vuln/detail/CVE-2025-1094)
File Snapshot

Log in to view the POC file snapshot cached by Shenlong Bot

Log in to view
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →