Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 20 Feb 2019 12:13:29 +0100
From: Solar Designer <solar@...nwall.com>
To: lkrg-users@...ts.openwall.com
Subject: Re: LKRG 6.0 Exploit Detection bypass

Hi Ilya,

On Wed, Feb 20, 2019 at 09:43:53AM +0400, Ilya Matveychikov wrote:
> I'd like to show few more exploit detection bypass techniques:
> https://github.com/milabs/kernel-exploits/commit/6bd99d97c3f99a0a743a012b9cb90fb2fe1c0970

Thank you!

Adam is in another timezone, so I expect he will comment later, but
here's my thinking out loud for now:

> By this commit we have the list of following:
>  - (1) LKRG ED bypass using UMH and chmod + chwon, the very first bypass
>  - (2) LKRG ED bypass by owerwriting inode->i_{uid,gid,mode} using simple_setattr()
>  - (3) LKRG ED bypass by owerwriting inode->i_{uid,gid,mode} directly
>  - (4) LKRG ED bypass by unlocking "UMH lock down" with LD_PRELOAD
>  - LKRG "poor man's CFI" bypass
> 
> (1) and (2) were introduced few months before.
> 
> (3) is the improvement of (2) which uses DKOM technique to manipulate inode
> directly without being detected by simple_setattr() hook.
> 
> (4) is the bypass of "UMH locking by using whitelist of programs" which basically
> allows one to use LD_PRELOAD to inject his payload to /sbin/modprobe or similar.
> 
> Since the use of (3) and (4) is locked by pCFI (poor man's Control Flow Integrity)
> mitigation introduced in LKRG 6.0 I had to add the "rich man's CFI bypass" which
> wraps calls to all of the listed bypasses with 2 macros which are actually fakes
> the call stack for the time of exploitation so LKRG could not see this.

If I understand correctly, all of the new bypasses rely on SMEP having
been disabled by the ROP chain in the exploit, or on hardware (or VM)
lacking SMEP support.  Correct?

If so, I guess (4) and your poor man's CFI bypass through having custom
code prepare pCFI-passing fake stack frames would be defeated on
SMEP-capable systems if LKRG's SMEP enforcement is made stricter.
Specifically, right now LKRG's p_pcfi_schedule_entry_smep() merely
re-enables SMEP if it finds that it's been disabled.  A similar check
could be performed in a shared function to be called from all other
places where pCFI is enforced, including on UMH, and the enforcement
action should be at least killing of the current task (so e.g. UMH
wouldn't proceed to use the environment you prepare for it).

As to (3), similar pCFI & SMEP enforcement calls could also be added to
user_path_at_empty() and (too many?) other kernel functions that provide
pointers to useful kernel objects.  However, I guess you'd bypass this
by not disabling SMEP until after having called one of those functions
from a ROP chain.  You'd need to somehow store/recall this function's
result across the SMEP-disabling portion of the ROP chain, which might
take extra gadgets to do.  Then you'd only have the direct writes left
to do with SMEP disabled, which LKRG would be very unlikely to detect in
time.  (You also do cleanup like the path_put(), but it's optional, it's
too late by then anyway, and you could even re-enable SMEP before doing
it to stay undetected.)

The more elaborate combination of a SMEP-disabling ROP chain and (3)
that I described above looks really tough for LKRG to protect against,
and possibly not worth it.  If so, we could in fact go back and
reconsider/drop some other (existing and potential) defenses if those
are relevant in the same scenarios as this.

On a related note, today on kernel-hardening:

Subject: [PATCH] x86/asm: Pin sensitive CR4 bits
https://www.openwall.com/lists/kernel-hardening/2019/02/20/1

As I understand, this would break the gadget this exploit uses to
disable SMEP.  I guess LKRG could at its load time live-patch that
gadget out of a running kernel as well, perhaps patching
native_write_cr4()'s MOV instruction to be a CALL into LKRG instead.
Whether this is worth it or not depends on how likely it is or not that
another suitable gadget is present in the kernel image anyway (not
necessarily an intentional MOV to CR4 instruction, but just the
corresponding byte sequence anywhere).

Alexander

P.S. There's no LKRG 6.0 yet.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.