oss-sec mailing list archives

Re: Follow-up on Exploiting "BadIRET" vulnerability (CVE-2014-9322)


From: Andy Lutomirski <luto () amacapital net>
Date: Wed, 8 Jul 2015 17:34:48 -0700

On 07/04/2015 12:23 AM, Adam Zabrocki wrote:
Hi,

The journey into CVE-2014-9322 is not straightforward but it is worth to spend some time on it and analyze all 
available information. I will try my best...


1) Introduction - non-technical (almost)

Everything starts from the CVE-2014-9090. This vulnerability was discovered by Andy Lutomirski which allows you 
(quoting MITRE):

"The do_double_fault function in arch/x86/kernel/traps.c in the Linux kernel through 3.17.4 does not properly handle faults 
associated with the Stack Segment (SS) segment register, which allows local users to cause a denial of service (panic) (...)"

which essentially may results in local DoS attack. It doesn't sounds so critical from the defender's point of view (but 
still it takes attention especially from the nature of vulnerability point of view) neither from the attackers perspective. 
Mainly because of the potential limited benefits after successful exploitation.

The "fun" starts after Borislav Petkov asked some questions about CVE-2014-9090. Andy Lutomirski discovered another 
vulnerability in the same functionality which was masked by first one. (Un)fortunately this time it was very serious (I would say 
critical) flaw. Linux kernel does not properly handle faults associated with the Stack Segment (SS) register in the x86 
architecture. Quoiting MITRE again:

"(...) allows local users to gain privileges by triggering an IRET instruction that leads to access to a GS Base address 
from the wrong space."


Good writeup.

For what it's worth, there are two issues that combine to make the BadIRET bug interesting.

1. Linux mishandled #SS during IRET. IRET can fail due to #SS, #NP, or #GP. All x86_64 OS authors seem to have realized that #GP is possible, but #SS and #NP are easy to overlook.

2. Linux gives flexible enough control over the LDT to cause IRET to fail with #SS. This is not a bug -- it just means that bug #1 matters. (Linux used to allow this attack through the GDT as well, but I fixed that separately.)

One might reasonably wonder whether other OSes are affected by #1 or, more severely, by #1 and #2. Here's my summary from memory:

FreeBSD was fully vulnerable. See the attachment. They seem to have fixed it, but I can't find an advisory.

OpenBSD appears to have bug #1 (or did, anyway -- I haven't checked recently), but AFAICT there is no way to modify the GDT or LDT at all on OpenBSD, so #2 isn't present and exploitation is impossible.

I think that Darwin had bug #1 but fixed it before I tried to exploit it (not sure when). I don't remember whether Darwin has #2.

OpenSolaris had #1 but, due to a whole pile of complicated double-checks, I couldn't find any way to get #2, despite the fact that fairly extensive descriptor manipulation is possible.

I don't know about Windows.

Xen is unusual and doesn't seem to use SWAPGS, so the underlying issue doesn't exist. That doesn't rule out the possibility of other bugs due to #NP or #SS, but Xen seems to survive my Linux test case.

I didn't check NetBSD, DragonFlyBSD, Mach, Hurd, or any of the L4 variants.

ESX could be an interesting target, although this would only make sense as part of an exploit chain or if paravirtual guests still exist and are enabled.

--Andy

Attachment: iret_ss_freebsd.c
Description:


Current thread: