
Attacking hardened Linux systems with kernel JIT spraying - Symmetry
http://mainisusuallyafunction.blogspot.com/2012/11/attacking-hardened-linux-systems-with.html
======
tptacek
Fun! If you're interested in Linux kernel security, you should read the whole
post, rather than jumping to conclusions about what it means right now.

SMEP is a processor feature that will disallow execution of instructions from
pages marked as belonging to userland when the CPU is executing in CPL0
(kernel mode). SMEP makes life annoying for memory corruption exploit authors
because it prevents them from using the userland memory they already control
to hold shellcode.

BPF is part of the network monitoring code in the Linux (and BSD) kernel; it's
what tcpdump expressions compile down to. BPF is a trivial two-register VM
that implements matching on packet fields to select which packets will be
shuttled (at great expense) into userland for pcap programs to look at. Modern
Linux kernels have BPF implementations that compile down to native code.

JIT-spraying is a technique Dion Blazakis invented (and my friend Chris Rohlf,
formerly on the Matasano team, spent several years working with). It notices
that systems implementing JITs often give attackers control over executable
code, even though the system is being careful not to allow data to be treated
as instructions. JIT-spray attacks give a victim JIT code that when compiled
will help abet an exploit; it's "sprayed" because the attacker does this
repeatedly in order to fill the victim's memory with malicious code to make it
easier to jump to during an exploit.

The coolest trick in this post is how they've accomplished the "spraying";
because there's a limit on open files and only one BPF filter can be attached
to one, they need a way around resource limits. So they use explicit file
descriptor passing, which is an obscure Unix feature that allows unrelated
processes to send and receive open files over Unix domain sockets using
sendmsg(2). By sending sockets with malicious BPF code attached, the technique
forces the kernel to keep those BPF filters resident, while allowing the
exploit code to close its own copy, freeing up space for a new socket.

The point of this post isn't "OMG Linux is doomed"; it's that it's difficult
to blunt memory corruption attacks with simple countermeasures. 15 years ago,
researchers thought they'd killed memory corruption code execution off for
good with stack cookies; the years that followed have been a story of new
countermeasures introduced, hailed as a single bullet, bypassed by clever
attacks, and then fit into a patchwork of defenses that have made exploits
progressively harder, but not close to impossible, to build.

~~~
jevinskie
But at least hardware vendors (Intel in this case) are giving software (Linux)
more tools to protect themselves. Unfortunately, just like with the great
hardware security provided by IBM for the PS3, software bugs mitigate many of
these hardware protections!

------
jbangert
Luckily pax anticipated that attack when releasing the KERNEXEC patch and
fixed it a while ago.

~~~
ibotty
i remember reading something i guess in the grsec forums about it (by
"paxteam" afair). i cannot find it right now, care to send a link? the only
thing i found is this post[1], which gives a very nice introduction to
smap/smep.

[1]:
[https://forums.grsecurity.net/viewtopic.php?f=7&t=3046](https://forums.grsecurity.net/viewtopic.php?f=7&t=3046)

~~~
jbangert
As taken from spenders twitter, here are the relevant parts of the patch:

<http://grsecurity.net/~spender/jit_prot.diff>

------
spullara
I hardly think that this exploits hardened Linux systems since the JIT it
exploits it is currently disabled by default. Maybe it should be titled
"Attacking softened Linux systems...".

~~~
sophacles
I think you're missing the point. The kernel module he exploits is also
something that no sane sysadmin would choose to load. The technique "JIT
spraying" targets JITs, however the broader methodology is "finding places to
put stuff in memory without the NX bit set", the JIT used here is just one
example. A relatively simple example. There are other things that do this too.

It's much like a "hello world" tutorial. You choose simple goals, use
simplified but demonstrative non core parts, and show the overall
method/technique/code/whatever in an easily digestible manner.

Further, I think a bigger takeaway than even the technique here is the good
use of many different parts, each innocuous on its own, but in combination a
path to owning the system. Its a clever combination of side-effects and
primary effects, but with goals never considered by the original authors.

~~~
spullara
That is fine take away and I agree with it and really your whole comment.
Except for the missing the point part. The title was inflamatory, link-bait
and mostly inaccurate.

------
kabdib
Can I just say that putting a JIT into a kernel is a really bad idea? That
putting /any/ executable code in a trusted environment that isn't utterly
static, cryptographically signed, and well armored, is just going to end
badly, over and over again?

We have enough trouble with user-space code generation, and with return-
oriented-programming. Actual code generation at the driver level seems utterly
wrong.

~~~
haberman
_Actual code generation at the driver level seems utterly wrong._

"Utterly wrong" is a pretty black-and-white judgement. A JIT in the kernel has
costs and benefits. You could as easily say that the ability to load modules
dynamically into the kernel is "utterly wrong," since it opens up a code-
injection vector that makes rootkits and other malware much easier to write.
In some ways dynamically-loadable modules could be seen as even more risky
than a JIT, because a JIT can only generate a subset of all possible machine
code. It would be pretty hard to write a rootkit as a Berkeley Packet Filter
program.

~~~
jbangert
However, it wouldn't be impossible. I am quite sure (although I don't have a
proof) that the BPF bytecode can be made turing complete, so an arbitrary
program (maybe a rootkit, much more likely patches to a few kernel structures)
could be implemented in it. Examples of things that are very unintendedly
turing complete include HTML5 without JS(the clicky rule 110), ELF relocations
(you can write a program to be interpreted by the loader in a few symbols and
relocations without changing code, see elf-bf-tools on GitHub) and the Intel
interrupt handling mechanism(unreleased, see talk at 29c3).

Furthermore, you don't need dynamically loadable modules in the kernel for
kernel code injection, see
[http://www.phrack.org/issues.html?id=7&issue=58](http://www.phrack.org/issues.html?id=7&issue=58)

~~~
haberman
elf-bf-tools is an impressive hack, thanks for the link! To add to your list,
you might want to mention that simply _parsing_ C++ is turing-complete; see
<http://yosefk.com/c++fqa/web-vs-c++.html#misfeature-3> . The short of it is
that you have to perform full template instantiation in some cases just to
parse code that uses those templates!

As to your point about /dev/kmem, to me that is just another argument against
the idea of banning JITs from the kernel. There are already lots of vectors
for getting attack payloads into the kernel; the JIT angle only helps an
attack if you somehow can make the kernel jump to a specified address but
don't have root.

------
Symmetry
I think this just goes to illustrate that not only are non-self-synchronizing
instruction sets bad for decoding, they're also bad for security. In point of
fact you could use this method to execute one arbitrary instruction in a
modern variable length instruction set like Thumb-2, but only one.

------
flyinRyan
Why was this only tested against grsec but not SELinux? Is there some reason
that it's not interesting to test SELinux against this exploit??

~~~
jbangert
SELinux does not aim to protect or harden the kernel. SELinux aims to enforce
a more complicated(maybe expressive), MAC policy on the filesystem and a few
related objects. The SELinux threat model is helpless against a kernel
vulnerability because it does not address application security.

------
alexanderh
innuendo galore.

