Understanding how CVE-2013-1979 might be exploited

May 24, 2013

CVE-2013-1979 is a more or less just-released locally exploitable 'gives root' Linux kernel vulnerability. Usually when I read CVE bug descriptions I can get at least a vague sense of how something would be exploitable, but this one puzzled me; I could see how the bug was not good but I couldn't see how it would be exploitable. Even the proof of concept code didn't particularly clear this up.

As described in the Red Hat bugzilla the core bug is:

Commit 257b5358b32f ("scm: Capture the full credentials of the scm sender") changed the credentials passing code to pass in the effective uid/gid instead of the real uid/gid.

(See also the Debian CVE entry.)

The first thing to understand is this 'credentials passing'. Simplified, it allows a program that's reading input from a Unix socket to discover the UID and GID of the process that sent the input. Programs can use this to easily implement access control (only certain UIDs can send them input) or authorization (certain UIDs are allowed to do special things), or just use the information for better logging and so on. Crucially, the sending program doesn't need to do anything special to enable this; it's entirely handled by the receiving program. The bug is that at one point the kernel code was changed to tell the receiving program the effective UID (and GID) of the sender, not their real UID and GID. This sounds relatively harmless, but it turns out it isn't. Here's how I think you exploit this.

First you need to find a program or a daemon that uses credentials on Unix domain sockets to make access or authorization decisions and that gives root special privileges. It probably also needs to act on simple, single messages; you connect to it, send it a message, and it does stuff for you. The ideal situation is something that accepts newline delimited ASCII and doesn't drop connections if you send it bad messages. Next you need to find a setuid program that can be tricked into writing a message that you control to standard output or standard error (possibly among other messages). The proof of concept code suggests that that su can be coaxed into doing this under some situations, for selected messages.

(Embedding newlines in command line arguments clearly helps here.)

To perform the actual exploit your wrapper program creates a Unix socket connection to the victim program or daemon, makes the socket connection its standard output and/or standard error, then runs su (or whatever) in such a way that it will print out your evil message. Since this message is actually being printed by a setuid program the daemon will see a valid message being sent to it by a privileged (effective) UID 0 process and proceed to carry out whatever evil you've asked it do for you.

Whether this is exploitable on any particular Linux system depends a lot on what you have running. Building a real exploit would probably take a fair amount of work because I think that most common daemons that talk over Unix domain sockets (such as the DBus daemon) use encoded wire protocols, not simple ASCII messages.

(Possibly I'm wrong here and there's a candidate daemon I'm missing. In any case there's a fix out now so you should be updating pretty fast.)

Written on 24 May 2013.
« My issue with infinite scrolling web pages: the lack of a stopping point
Empirically, modern mailing list services are spam senders »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri May 24 16:00:46 2013
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.