Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 1 Oct 2017 00:00:11 +0200
From: Solar Designer <solar@...nwall.com>
To: "?$BCfB<M:0l / NAKAMURA?$B!$YUUICHI" <yuichi.nakamura.fe@...achi.com>
Cc: kernel-hardening@...ts.openwall.com,
	"yamauchi@...okayama-u.ac.jp" <yamauchi@...okayama-u.ac.jp>,
	Adam Zabrocki <pi3@....com.pl>
Subject: Re: [RFC] A method to prevent priviledge escalation

Hi,

On Fri, Sep 22, 2017 at 02:49:59AM +0000, ?$BCfB<M:0l / NAKAMURA?$B!$YUUICHI wrote:
> As we said in Linux Security Summit 2017, 
> we would like to post a patch to prevent privilege escalation attack.
> 
> The concept is here:
> http://events.linuxfoundation.org/sites/events/files/slides/nakamura_20170831_1.pdf

We were not aware of your work, but FWIW we happen to have similar
functionality, also in early development/testing stage, in LKRG by Adam
Zabrocki (who is CC'ed on this reply, so he might chime in):

http://openwall.info/wiki/p_lkrg/Main#Exploit-Detection

LKRG is not publicly available yet, but it probably will be soon.

Unlike your implementation, LKRG is a kernel module, not a patch.
LKRG can be built for and loaded on top of a wide range of mainline and
distros' kernels, without needing to patch those.  There are other
implementation differences as well - indeed, hopefully we are not
actually introducing vulnerabilities with our code, although the risk is
always there, so it would need to be justified.  And this brings us to:

Frankly, we're skeptical about the value that this approach provides.
Much of the value could be in diversity - if most systems do not have
this sort of runtime checks, then canned exploits and even some capable
human attackers would not care or know to try and bypass the checks.
However, if this functionality becomes standard, so will the bypasses.
Now, are there cases (such as specific kernel vulnerabilities) where a
bypass is not possible, not practical, not reliable, or would complicate
the exploit so much it becomes less generic and/or less reliable?
Perhaps yes, and this would mean there's some value in this approach
even if it becomes standard.  Another option may be to have a lighter
standard version and a heavier and more extensive limited distribution
version (which could also be a way to receive funding for the project).

Speaking of addressing a sensible threat model, I suggested to Adam that
we add validation of credentials right after the kernel's original
permissions check on the module loading syscalls.  (Or we might
duplicate those permission checks first, since that's easier to do when
we're also a kernel module rather than a patch.)  Then we'll achieve
sensible overall functionality: can't use those unauthorized credentials
for much time, and can't easily backdoor the running kernel through
having exploited a typical kernel vulnerability (due to LKRG's integrity
checking of the rest of the kernel and, with this extra check, not being
able to perform an unauthorized kernel module load by official means,
which LKRG's integrity checking wouldn't otherwise catch).

The credentials checks would need to be extended to cover cap_*, etc. -
there's already a (partial?) list of those other credential-like data
items on the wiki page above.  And they will need to be performed in
more places - I think in particular on open(), as otherwise even a very
brief exposure of the unauthorized credentials would let the attacker
retain an fd e.g. to a block device corresponding to the root filesystem
and then install persistent backdoors in there without hurry (e.g.,
pattern-match a critical system binary and introduce own code in there).

Of course, the action on detected integrity violation (of the kernel
itself or of its critical data) should not be limited to logging a
warning, as we do for testing now.  What exact action is best might be a
non-trivial question.  Panic the kernel?  Lock the kernel from any
further syscalls, log what happened, sync the disks, and then panic?

Attempt to undo the unauthorized change whenever possible - e.g.,
restore the credentials from our shadow copy that couldn't be tampered
with as easily?  But then an alternative would appear to be to protect
the main credentials to the same extent, e.g. keeping them read-only
most of the time or/and encrypted with a per-boot key (trickier to do
when we're a kernel module, though).  This undoing the damage is
probably bad as it'd allow the attack to repeat until all races are won,
unless we combine it e.g. with blacklisting of attack sources such as by
uid when a threshold is reached.  It's also bad in that it requires
exploits to replace just one set of credentials - the more trusted
(and better protected?) one - rather than both, as would be the case if
we choose panic.  For some vulnerabilities, an exploit would probably
only be able to perform one write in a while (e.g., per syscall), so
needing to replace both sets of credentials improves the chances of
detection.

We welcome any other thoughts - be it criticism, feedback, or anything.

Thanks,

Alexander

Powered by blists - more mailing lists

Your e-mail address:

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