Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Thu, 21 Feb 2019 03:41:09 +0100
From: Adam Zabrocki <>
Subject: Re: Re: LKRG 6.0 Exploit Detection bypass


At the beginning I would like to thank you for looking and evaluating new 
version of LKRG! The more eyes, the more problems can be discovered and 
fixed, so thanks again ;-)

I've spent some time on what you've researched. Here a are couple of notes:

 - Before we published LKRG 0.6 Alexander suggested a feature to panic() the 
kernel in case of SMEP violation if lkrg.ci_panic=1. I thought it is not 
needed for now since new version of LKRG has tons of new code which requires 
testing. This means I might have overlooked something in case of SMEP strict 
rules which would result in some incompatibility issues. Nevertheless, I 
haven't seen one, and I believe it could be a good mitigation for various 
variants of bypasses.
 - All versions of the bypasses are detected by LKRG via detection of SMEP 
violation, nevertheless only 2 of the variants are being blocked:
   a. variants (1) and (2) are blocked
   b. variants (3) and (4) are correctly detected but not blocked:
     I. variant (3) just detected
     II. variant (4) detected but also Proof Of Concept process is being 
killed. Nevertheless, SIGKILL is delivered to the process which does 
exploitation, but UMH was injected into the queue of kernel threads (that's 
how UMH works) so even though exploit is being killed, UMH continues to run 
in parallel.
   c. variant (5) is additionally detected by Runtime CI (hash doesn't 

so it looks like variant (3) is the most problematic one.

I went one step ahead and:

 1. I'm introducing a new LKRG sysctl interface lkrg.smep_panic which will be 
enabled by default. If LKRG detects SMEP violation it will kill the kernel 
(invoke function panic()). This mitigation should be enough to stop bypasses 
but it is only effective on machines which support SMEP
 2. Additionally, I'm introducing a new LKRG sysctl interface lkrg.umh_lock 
which will be disabled by default. If it is enabled, LKRG completely locks down 
UMH functionality, and nothing can be executed via this interface. It has of 
course side effects e.g. systemd daemon is using UMH to invoke 
"systemd-cgroups-agent". If you enable lkrg.umh_lock then any call to the 
systemd-cgroups-agent will fail. However, not all systems are using systemd. 
Additionally, if you're super paranoid this feature can be useful for you.
 3. For (3) I've also done some research and:
    a. I've placed extra hook on "__queue_work" function where I only do SMEP 
and WP bit verification. I send SIGKILL to any task which enters this function 
when SMEP/WP is disabled and I do reenable them again.
    b. I've placed extra hook on "lookup_fast" function where I do the same 
check as for "__queue_work" + additionally I'm verifying just SP pointer (don't 
do stack walk like full pCFI does).

    it correctly stops (3) as well. 

 4. I've added SMEP and WP bits validation every time, when ED verification is 
being executed and whenever inode is being marked as dirty.

Everything what I mentioned here is a relatively new code, and requires some 
more testing. I've tested it but it needs more verification in the various 
environment / kernels.
It is worth to point out that we might decide to cut / add or modify some of 
the features mentioned here. Until we release a new official and stable version 
of LKRG, I think that changes might be available to the community and I would 
be thankful if more people test them.
These changes are available in the official LKRG repo here:


On Thu, Feb 21, 2019 at 04:02:48AM +0400, Ilya Matveychikov wrote:
> One more ED bypass:
>  - (5) LKRG ED bypass by disabling kprobes (patching the kernel)
> > On Feb 20, 2019, at 9:43 AM, Ilya Matveychikov <> wrote:
> > 
> > Hello,
> > 
> > I’d like to show few more exploit detection bypass techniques:
> >
> > 
> > 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.
> > 
> > Ilya
> > 

pi3 (pi3ki31ny) - pi3 (at) itsec pl

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.