Publisher
Test your enumeration skills on this boot-to-root machine.
Recon
Let's start with a nmap scan. We find two ports open. Port 22 with SSH and port 80 with an Apache web server.
┌──(kali㉿kali)-[~]
└─$ nmap -p- publish.thm -T4
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-08 11:41 IST
Nmap scan report for publish.thm (10.10.91.245)
Host is up (0.15s latency).
Not shown: 65530 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 101.71 seconds
┌──(kali㉿kali)-[~]
└─$ nmap -sC -sV -p 22,80 publish.thm -T4
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-08 12:00 IST
Nmap scan report for publish.thm (10.10.91.245)
Host is up (0.15s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 44:5f:26:67:4b:4a:91:9b:59:7a:95:59:c8:4c:2e:04 (RSA)
| 256 0a:4b:b9:b1:77:d2:48:79:fc:2f:8a:3d:64:3a:ad:94 (ECDSA)
|_ 256 d3:3b:97:ea:54:bc:41:4d:03:39:f6:8f:ad:b6:a0:fb (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Publisher's Pulse: SPIP Insights & Tips
|_http-server-header: Apache/2.4.41 (Ubuntu)
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 12.26 seconds
We start a directory scan using feroxbuster. Here we discover the directory spip
.
┌──(kali㉿kali)-[~]
└─$ feroxbuster -u http://publish.thm/ -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -n
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.10.3
───────────────────────────┬──────────────────────
🎯 Target Url │ http://publish.thm/
🚀 Threads │ 50
📖 Wordlist │ /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.10.3
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
🏁 HTTP methods │ [GET]
🚫 Do Not Recurse │ true
🎉 New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 GET 9l 31w 273c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
403 GET 9l 28w 276c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 354l 770w 5959c http://publish.thm/style.css
200 GET 142l 610w 69796c http://publish.thm/images/image_02.jpg
301 GET 9l 28w 311c http://publish.thm/images => http://publish.thm/images/
200 GET 32l 224w 17917c http://publish.thm/images/ads.jpg
200 GET 237l 1368w 110318c http://publish.thm/images/image_01.jpg
200 GET 150l 766w 8686c http://publish.thm/
301 GET 9l 28w 309c http://publish.thm/spip => http://publish.thm/spip/
[####################] - 13m 207638/207638 0s found:7 errors:102
[####################] - 13m 207629/207629 269/s http://publish.thm/
We do not discover anything on the index page.

In the spip directory, we find a blog created with SPIP, a free and open-source content management system (CMS). SPIP is designed for managing web-based publications and enabling collaborative work.

Examining the source code, we identify that version 4.2.0 is in use. This might be our entry point.

Initial Access
After some research on SPIP 4.2.0, we discover an exploit that allows for remote code execution (RCE) without authentication.
Let's try using the Metasploit framework. We find an RCE exploit for SPIP that was disclosed around the same time as the one on exploitdb. This could be the same exploit.

After we have set the necessary parameters and run the exploit, we get a meterpreter session.

In the session, we can spawn a shell
, and we are the user www-data
. This user has permission to access the home directory of the user think and read the files there, allowing us to obtain the first flag.

In the home directory of the user think, we find a private SSH key. We copy this key and adjust the permissions accordingly.

After setting the permissions, we use the key to log in to the machine via SSH as the user think. Initially, it seems we now have a more stable shell. However, we quickly notice some restrictions: we can't write in the home directory, other writable directories like /tmp are also inaccessible, and the /opt directory is not readable. It appears our access is more limited than we expected.

Privilege Escalation
During enumeration, we discover a custom binary with the SUID bit set, meaning it executes in the context of the owner, which is root.

We can quickly inspect the binary using strings
or cat
, which reveals that it only executes a script located at /opt/run_container.sh
. Notably, this script is run with bash -p
, meaning it executes with root privileges.

The /opt
directory should be readable, suggesting another mechanism might be restricting access.

We can read the script located in /opt
but cannont not identify any vulnerabilities or entry points for injecting commands or parameters.

It seems like we'll need to bypass our current shell restrictions. One possible approach could involve modifying the contents of run_container.sh.
It appears that AppArmor is imposing restrictions, particularly on the shell ash
and programs in /usr/bin
and /usr/sbin
. The rules deny access to /opt/
and apply a ruleset inherited by /usr/bin/**
and /usr/sbin/**
which restricts certain operations.
Interestingly, there is a flaw in the AppArmor profile: while /dev/shm/
and /dev/tmp/
have deny rules, they lack the /**
wildcard, unlike /tmp/
. This allows us to still write to /dev/shm
and /var/tmp
.

The user's shell, as listed in /etc/passwd
, is set to ash
.

We copy /bin/bash
to /var/tmp
and run it. We can now access /opt
.

Fortunately, we are allowed to write on run_container.sh
.
We'll create a script that copies /bin/bash
to /var/tmp
and sets the SUID bit. This way, when executed, the script runs with root privileges, allowing us to obtain a root shell.


After running the bash1
binary inside /var/tmp
with the tag -p
we gain a root shell and find the final flag in /root/root.txt
.

Last updated
Was this helpful?