kernel-hardening.lists.openwall.com archive mirror
 help / color / mirror / Atom feed
* [kernel-hardening] BPF JIT spray attack - proof of concept code for modern kernel
@ 2016-05-03  6:38 Reshetova, Elena
  2016-05-03 17:01 ` [kernel-hardening] " Kees Cook
  0 siblings, 1 reply; 4+ messages in thread
From: Reshetova, Elena @ 2016-05-03  6:38 UTC (permalink / raw)
  To: kernel-hardening, Kees Cook; +Cc: Daniel Borkmann


[-- Attachment #1.1: Type: text/plain, Size: 2138 bytes --]

Hi,

 

Following Kees's suggestion, I am posting here a link to the poc code that I
did to show the need of further BPF JIT hardening:
https://github.com/01org/jit-spray-poc-for-ksp

This poc is based on the 2012 poc done by McAllister:
https://github.com/kmcallister/alameda I have kept his commits untouched and
only added mine on top that you can easily see what was modified. 

 

Some description of what it does and why it does work:

 

The original 2012 poc stopped working after the address offset randomization
for loading the BPF was added:
http://lingrok.org/xref/linux-net-next/kernel/bpf/core.c#143 

This was due to the fact that McAllister code relied on random page guessing
and was assuming filter to start at the page start. This approach clearly
doesn't work with new random address allocation since one would need to
guess both page and offset and incorrect guess most commonly results in a
full restart need for normal machine (after which filter address has changed
and you don't gain any knowledge).

 

The main changes I did was to extend the filter size to spawn longer than 1
full page (to make sure it would overrun into the next page) and then repeat
the "get root payload" there in circles with enough of "nope" instructions
to render it for most success. Also, when jumping to a new random page, I
would try to execute the payload a number of times on the same page changing
just an offset that is less than 10
(https://github.com/01org/jit-spray-poc-for-ksp/blob/master/alameda.c#L325 )
to make sure to walk through the "nopes" and invoke the payload if the page
guess was correct. 

 

I have tried the poc on virtual machine with Ubuntu with 4.4 upstream kernel
and it works quite well. It can still in some cases completely stall the
machine that reboot is required, but it does reach its root goal in most of
the cases. 

Also, please not that similarly as 2012 poc code, this is not a real exploit
because it requires an "insecure ko" kernel module to actually make a jump,
but it illustrates the need for further JIT hardening that Daniel is
currently working now on. 

 

Best Regards,
Elena.

 


[-- Attachment #1.2: Type: text/html, Size: 5066 bytes --]

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7586 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [kernel-hardening] Re: BPF JIT spray attack - proof of concept code for modern kernel
  2016-05-03  6:38 [kernel-hardening] BPF JIT spray attack - proof of concept code for modern kernel Reshetova, Elena
@ 2016-05-03 17:01 ` Kees Cook
  2016-05-23 18:52   ` Kees Cook
  0 siblings, 1 reply; 4+ messages in thread
From: Kees Cook @ 2016-05-03 17:01 UTC (permalink / raw)
  To: Reshetova, Elena; +Cc: kernel-hardening, Daniel Borkmann

On Mon, May 2, 2016 at 11:38 PM, Reshetova, Elena
<elena.reshetova@intel.com> wrote:
> Following Kees’s suggestion, I am posting here a link to the poc code that I
> did to show the need of further BPF JIT hardening:
> https://github.com/01org/jit-spray-poc-for-ksp
>
> This poc is based on the 2012 poc done by McAllister:
> https://github.com/kmcallister/alameda I have kept his commits untouched and
> only added mine on top that you can easily see what was modified.
>
> Some description of what it does and why it does work:
>
> The original 2012 poc stopped working after the address offset randomization
> for loading the BPF was added:
> http://lingrok.org/xref/linux-net-next/kernel/bpf/core.c#143
>
> This was due to the fact that McAllister code relied on random page guessing
> and was assuming filter to start at the page start. This approach clearly
> doesn’t work with new random address allocation since one would need to
> guess both page and offset and incorrect guess most commonly results in a
> full restart need for normal machine (after which filter address has changed
> and you don’t gain any knowledge).
>
>
>
> The main changes I did was to extend the filter size to spawn longer than 1
> full page (to make sure it would overrun into the next page) and then repeat
> the “get root payload” there in circles with enough of “nope” instructions
> to render it for most success. Also, when jumping to a new random page, I
> would try to execute the payload a number of times on the same page changing
> just an offset that is less than 10
> (https://github.com/01org/jit-spray-poc-for-ksp/blob/master/alameda.c#L325 )
> to make sure to walk through the “nopes” and invoke the payload if the page
> guess was correct.
>
>
>
> I have tried the poc on virtual machine with Ubuntu with 4.4 upstream kernel
> and it works quite well. It can still in some cases completely stall the
> machine that reboot is required, but it does reach its root goal in most of
> the cases.
>
> Also, please note that similarly as 2012 poc code, this is not a real exploit
> because it requires an “insecure ko” kernel module to actually make a jump,
> but it illustrates the need for further JIT hardening that Daniel is
> currently working now on.

This is great! Thanks for updating this research. It strongly helps
illustrate why instruction blinding is an important defense. I'm
looking forward to Daniel's work landing.

Thanks!

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [kernel-hardening] Re: BPF JIT spray attack - proof of concept code for modern kernel
  2016-05-03 17:01 ` [kernel-hardening] " Kees Cook
@ 2016-05-23 18:52   ` Kees Cook
  2016-05-24  7:21     ` Reshetova, Elena
  0 siblings, 1 reply; 4+ messages in thread
From: Kees Cook @ 2016-05-23 18:52 UTC (permalink / raw)
  To: kernel-hardening; +Cc: Daniel Borkmann, Reshetova, Elena

On Tue, May 3, 2016 at 10:01 AM, Kees Cook <keescook@chromium.org> wrote:
> On Mon, May 2, 2016 at 11:38 PM, Reshetova, Elena
> <elena.reshetova@intel.com> wrote:
>> Following Kees’s suggestion, I am posting here a link to the poc code that I
>> did to show the need of further BPF JIT hardening:
>> https://github.com/01org/jit-spray-poc-for-ksp
>>
>> This poc is based on the 2012 poc done by McAllister:
>> https://github.com/kmcallister/alameda I have kept his commits untouched and
>> only added mine on top that you can easily see what was modified.
>>
>> Some description of what it does and why it does work:
>>
>> The original 2012 poc stopped working after the address offset randomization
>> for loading the BPF was added:
>> http://lingrok.org/xref/linux-net-next/kernel/bpf/core.c#143
>>
>> This was due to the fact that McAllister code relied on random page guessing
>> and was assuming filter to start at the page start. This approach clearly
>> doesn’t work with new random address allocation since one would need to
>> guess both page and offset and incorrect guess most commonly results in a
>> full restart need for normal machine (after which filter address has changed
>> and you don’t gain any knowledge).
>>
>>
>>
>> The main changes I did was to extend the filter size to spawn longer than 1
>> full page (to make sure it would overrun into the next page) and then repeat
>> the “get root payload” there in circles with enough of “nope” instructions
>> to render it for most success. Also, when jumping to a new random page, I
>> would try to execute the payload a number of times on the same page changing
>> just an offset that is less than 10
>> (https://github.com/01org/jit-spray-poc-for-ksp/blob/master/alameda.c#L325 )
>> to make sure to walk through the “nopes” and invoke the payload if the page
>> guess was correct.
>>
>>
>>
>> I have tried the poc on virtual machine with Ubuntu with 4.4 upstream kernel
>> and it works quite well. It can still in some cases completely stall the
>> machine that reboot is required, but it does reach its root goal in most of
>> the cases.
>>
>> Also, please note that similarly as 2012 poc code, this is not a real exploit
>> because it requires an “insecure ko” kernel module to actually make a jump,
>> but it illustrates the need for further JIT hardening that Daniel is
>> currently working now on.
>
> This is great! Thanks for updating this research. It strongly helps
> illustrate why instruction blinding is an important defense. I'm
> looking forward to Daniel's work landing.

Just to follow up on this: the eBPF JIT blinding code has landed in
Linus's tree (which should ultimately appear in v4.7)!

See the commits in and around:
http://git.kernel.org/linus/4f3446bb809f20ad56cadf712e6006815ae7a8f9

If a system already sets the bpf_jit_enable sysctl to 1 (0 is the
kernel default), the new bpf_jit_harden sysctl can be 0 (off, the
current kernel default, which will hopefully change in the future), 1
(unprivileged users get JIT blinding), or 2 (all users get JIT
blinding).

As always, there's a few more things to do AIUI, if anyone has time
and interest:
- we need a blinding test added (either to lib/test_bpf.c or elsewhere)
- remaining archs (ARM, MIPS, PowerPC, Sparc) cBPF JIT needs to either
be converted to eBPF or have blinding added directly (the latter is
easier, the former is better all around). i.e. if an arch defines
bpf_jit_enable, but doesn't call bpf_int_jit_compile(), it needs the
eBPF JIT. If it does, but doesn't call bpf_jit_blind_constants(), it's
not blinding eBPF.

Thanks for all the attention on this!

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [kernel-hardening] Re: BPF JIT spray attack - proof of concept code for modern kernel
  2016-05-23 18:52   ` Kees Cook
@ 2016-05-24  7:21     ` Reshetova, Elena
  0 siblings, 0 replies; 4+ messages in thread
From: Reshetova, Elena @ 2016-05-24  7:21 UTC (permalink / raw)
  To: kernel-hardening; +Cc: Daniel Borkmann, Kees Cook

[-- Attachment #1: Type: text/plain, Size: 2076 bytes --]


>> I have tried the poc on virtual machine with Ubuntu with 4.4 upstream 
>> kernel and it works quite well. It can still in some cases completely 
>> stall the machine that reboot is required, but it does reach its root 
>> goal in most of the cases.
>>
>> Also, please note that similarly as 2012 poc code, this is not a real 
>> exploit because it requires an “insecure ko” kernel module to 
>> actually make a jump, but it illustrates the need for further JIT 
>> hardening that Daniel is currently working now on.
>
> This is great! Thanks for updating this research. It strongly helps 
> illustrate why instruction blinding is an important defense. I'm 
> looking forward to Daniel's work landing.

>Just to follow up on this: the eBPF JIT blinding code has landed in Linus's tree (which should ultimately appear in v4.7)!

>See the commits in and around:
>http://git.kernel.org/linus/4f3446bb809f20ad56cadf712e6006815ae7a8f9

>If a system already sets the bpf_jit_enable sysctl to 1 (0 is the kernel default), the new bpf_jit_harden sysctl can be 0 (off, the current kernel default, which will hopefully change in the future), 1 (unprivileged users get JIT blinding), or 2 (all users get JIT blinding).

>As always, there's a few more things to do AIUI, if anyone has time and interest:
>- we need a blinding test added (either to lib/test_bpf.c or elsewhere)
>- remaining archs (ARM, MIPS, PowerPC, Sparc) cBPF JIT needs to either be converted to eBPF or have blinding added directly (the latter is easier, the former is better all around). i.e. if an arch defines bpf_jit_enable, but doesn't call bpf_int_jit_compile(), it needs the eBPF JIT. If it does, but doesn't call >bpf_jit_blind_constants(), it's not blinding eBPF.

>Thanks for all the attention on this!

And I would like to emphasis the fact that Daniel did a great job in such a short time.  This case really shows to us how great things can go, if instead of being sceptical and build barriers, maintainers come to help and just make it happen!

Best Regards,
Elena.

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7586 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-05-24  7:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-03  6:38 [kernel-hardening] BPF JIT spray attack - proof of concept code for modern kernel Reshetova, Elena
2016-05-03 17:01 ` [kernel-hardening] " Kees Cook
2016-05-23 18:52   ` Kees Cook
2016-05-24  7:21     ` Reshetova, Elena

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).