EDIT3: Brad Spengler also wrote an exploit for this and published it. The bug triggering is based on our exploit which leaked to Brad though the private vendor-sec mailing list. He implements the personality trick Tavis and I published in June to bypass mmap_min_addr and also makes use of a feature that allows any unconfined user to gain the right to map at address zero in Redhat's default SELinux policy. He wrote a reliable shellcode for this one that should work pretty much anywhere on x86 and x86_64 machines.
EDIT4: if you use Debian or Ubuntu on your machine, I have specifically updated the kernelsec Debian/Ubuntu GrSecurity packages to protect against this bug and others.
EDIT5: Zinx wrote an ARM Android root exploit
EDIT6: Ramon de Carvalho Valle wrote a PPC/PPC64/x86_64/i386 exploit
Tavis Ormandy and myself have recently found and investigated a Linux kernel vulnerability (CVE-2009-2692). It affects all 2.4 and 2.6 kernels since 2001 on all architectures. We believe this is the public vulnerability affecting the greatest number of kernel versions.
The issue lies in how Linux deals with unavailable operations for some protocols. sock_sendpage and others don't check for NULL pointers before dereferencing operations in the ops structure. Instead the kernel relies on correct initialization of those proto_ops structures with stubs (such as sock_no_sendpage) instead of NULL pointers.
At first sight, the code in af_ipx.c looks correct and seems to initialize .sendpage properly. However, due to a bug in the SOCKOPS_WRAP macro, sock_sendpage will not be initialized. This code is very fragile and there are many other protocols where proto_ops are not correctly initialized at all (vulnerable even without the bug in SOCKOPS_WRAP), see bluetooth for instance.
So it was decided that instead of patching all those protocols and continue to rely on this very fragile code, sock_sendpage would get patched to check against NULL. This was already the way sock_splice_read and others were handled.
Since it leads to the kernel executing code at NULL, the vulnerability is as trivial as it can get to exploit (edit: that's for local privilege escalation and on Intel architectures): an attacker can just put code in the first page that will get executed with kernel privileges. Our exploit took a few minutes to adapt from a previous one:
$ ./leeches
// ------------------------------------------------------
// sendpage linux local ring0
// ---------------- taviso@sdf.lonestar.org, julien@cr0.org
// leeches.c:Aug 11 2009
// GreetZ: LiquidK, lcamtuf, Spoonm, novocainated, asiraP, ScaryBeasts, spender, pipacs, stealth, jagger, redpig, Neel and all the other leeches we forgot to mention!
Enjoy some photography while at ring0 @ http://flickr.com/meder
For our webapp friends, here is an XSS executing at ring 0: javascript:alert(1);
shellcode now executing chmod("/bin/sh", 04755), welcome to ring0
Killed
$ sh
# id
uid=1000(julien) gid=1000(julien) euid=0(root)
On x86/x86_64, this issue could be mitigated by three things:// ---------------- taviso@sdf.lonestar.org, julien@cr0.org
// leeches.c:Aug 11 2009
// GreetZ: LiquidK, lcamtuf, Spoonm, novocainated, asiraP, ScaryBeasts, spender, pipacs, stealth, jagger, redpig, Neel and all the other leeches we forgot to mention!
Enjoy some photography while at ring0 @ http://flickr.com/meder
For our webapp friends, here is an XSS executing at ring 0: javascript:alert(1);
shellcode now executing chmod("/bin/sh", 04755), welcome to ring0
Killed
$ sh
# id
uid=1000(julien) gid=1000(julien) euid=0(root)
- the recent mmap_min_addr feature. Note that this feature has known issues until at least 2.6.30.2. See also this LWN article.
- on IA32 with PaX/GrSecurity, the KERNEXEC feature (x86 only)
- not implementing affected protocols (a.k.a., reducing your attack surface by disabling what you don't need): PF_APPLETALK, PF_IPX, PF_IRDA, PF_X25, PF_AX25, PF_BLUETOOTH, PF_IUCV, IPPROTO_SCTP/PF_INET6, PF_PPPOX, PF_ISDN, but there may be more. (Update: See RedHat's mitigation)
You can read our advisory here.
Note: this has been featured on Slashdot, OSNews, TheRegister, ZDNet and others
It's not exploitable for code execution on all architectures. My sparc server for instance is safe ;)
ReplyDeleteIt's already been patched, just make sure you've run the update.
ReplyDeleteI'm safe, I run Windows
ReplyDeleteOne more reason I'm glad to have PaX and GrSecurity.
ReplyDeletegood thing i run plan9
ReplyDeleteHow about some exploit code??
ReplyDeleteFirst person to release c0de gets a beer on me!
What if you have IPX completely disabled in your kernel? Looking at your discovery, I can see how this would be a problem for people with very modular kernels/
ReplyDeletehttp://www.securityfocus.com/bid/36038/exploit
ReplyDeletebeer please now
This is one reason so many 64b systems (Tru64 on Alpha being a good example) prevent mapping the first 32 bits of address space. Surprising that Linux doesn't do the same.
ReplyDelete> This is one reason so many 64b systems
ReplyDelete> (Tru64 on Alpha being a good example
> prevent mapping the first 32 bits of
> address space. Surprising that Linux
> doesn't do the same.
?? First of all - the whole problem has nothing to do with architecture of the used CPU (intel, non-intel, 32bit, 64bit).
Secondly - Linux also offers such protection, but it was somehow flawed until one of the kernel versions
3rdly - It is guaranteed on some systems (SVR4) that the fisrt page is always mapped (PROT_READ afair), so linux tries to emulate that behavior via the personality mechanism - http://linux.die.net/man/2/personality - and that is where the bug lied (the one with mapping zero page).
Good find, great work.
ReplyDeleteExploit code has been available at http://grsecurity.net/~spender/wunderbar_emporium.tgz
ReplyDeleteWorks on all affected kernels: both x86 and x64, 4k stacks or 8k stacks, cred framework or not. Disables SELinux, AppArmor, LSM, and auditing. Also plays an embedded movie if the host is up to it.
-Brad
Can anybody explain why http://www.securityfocus.com/bid/36038/exploit only works once?
ReplyDeleteCongrats for the discover !
ReplyDeleteYet another reason to use some alternative with better track record wrt security, like Solaris or *BSD.
ReplyDeleteLooks like it's finally kernel upgrade time!
ReplyDeleteGoodbye Linux_2.6.19, I'll miss you.
Codifex
Don't use the one from securityfocus, they have an old version of the exploit.
ReplyDeleteUNABLE TO MAP ZERO PAGE! on up to date Fedora with SELinux. Problem addressed by Red Hat when fixing CVE-2009-1895 recently?
ReplyDeleteWhy can't the kernel track the process that map page zero and does extra stuff when switching from user mode to kernel mode (update mmu to make it not excecutable, ...)
ReplyDeleteOf course this will slowdown these processes but are there performance program that depend of that ?
Wine ?
Looks like you where to fast when you thanked Dan, because SELinux does indeed stop this:
ReplyDelete$ LANG=C sh wunderbar_emporium.sh
runcon: invalid context:
unconfined_u:unconfined_r:initrc_t:s0-s0:c0.c1023: Invalid argument
UNABLE TO MAP ZERO PAGE!
Doesn't work with SELinux, although you claim the opposite in the source:
ReplyDeletesh wunderbar_emporium.sh
runcon: invalid context:
unconfined_u:unconfined_r:initrc_t:s0-s0:c0.c1023: Invalid argument
UNABLE TO MAP ZERO PAGE!
and the raw audit message for this:
localhost.localdomain type=AVC msg=audit(1250278420.753:27501): avc: denied { mmap_zero } for pid=16933 comm="exploit" scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=memprotect
So obviously you were to fast when you thanked Dan for "great SELinux bypass".
Fedora's SELinux policy (asuuming you leave it enforcing) protects from the exploit (runcon can't change the type).
ReplyDeleteSo there's actually two bugs. One is NULL pointer dereference and the other is allowing to mmap (presumably unmmapable) memory at 0x0 location (even if /proc/sys/vm/mmap_min_addr > 0).
ReplyDeleteHere's a reply to some of the comments (not all, sorry):
ReplyDelete- @Anonymous: you're correct, about SPARC. Interestingly, IA32 could also be safe but is not for performances reasons (unless you use Linux 2.0 or PaX KERNEXEC/UDEREF). x86_64 however killed segmentation :(
- About mapping to Null. This should be protected by mmap_min_addr since Linux 2.6.23. Last month, Tavis and I published a way to bypass it by using personalities and Pulseaudio. Brad Spengler then implemented this technique in an exploit and noticed that it worked even without the Pulseaudio trick. The reason was the default SELinux policy allowing unconfined users to mmap at address zero.
This definetly does not work on fedora with selinux enforcing.
ReplyDeletemy fedora 11 with SELinux enforcing is also safe, the exploit doesnt work or did i miss something?
ReplyDeleteIt did exploit Fedora SELinux up until August 13, then was patched. I successfully exploited Kernel 2.6.29.6-213.fc11.i586 with this mechanism.
ReplyDeletehttp://www.doecirc.energy.gov/bulletins/t-217.shtml
ReplyDeleteJulien can u give more info about this vuln and how to trigger it.
thanks
oo thanx bro. good bilgi..
ReplyDeleteIs it not normal procedure to inform the Kernel maintainers before publishing an exploit to the world? It took until 13th August for a patch to be released.
ReplyDelete@John: I have no idea what you're talking about. We also worked on the patch, which was released even before the advisory.
ReplyDeleteI even link to it from the blog post.
I have no idea
ReplyDelete