|
Message-ID: <20181118132923.GA31102@openwall.com> Date: Sun, 18 Nov 2018 14:29:23 +0100 From: Solar Designer <solar@...nwall.com> To: lkrg-users@...ts.openwall.com Subject: Re: LKRG Exploit Detection bypass (LOL again) Hi Ilya, On Sun, Nov 18, 2018 at 01:49:32AM +0400, Ilya Matveychikov wrote: > One more bypass: > > https://github.com/milabs/kernel-exploits/commit/3c9758def171b672d4df4318514efc2bfb4ce8e5 Thanks, this is quite helpful to our current discussion. Here's a peek (excerpts from two of my e-mails to Adam yesterday): On Sat, Nov 17, 2018 at 07:04:25PM +0100, Solar Designer wrote: > I think LKRG possibly already went too far by having CI at all, and as a > non-optional feature. > > And yes, maybe we should just accept that an exploit going after a very > specific kernel version and calling kernel functions can do whatever it > wants. So maybe we shouldn't defeat Ilya's bypass. > > As an alternative to UMH, he could probably call lower-level > implementations behind chmod() and chown(), which are normally used past > privilege checks - lookup the dentry, lookup the inode, change the > inode in 3 separate calls or so. This could become filesystem type > specific if he's not reading the corresponding function pointers from > structs (would need to locate those structs first), but so what. Assuming your new bypass works, you've demonstrated that only the dentry needs to be looked up explicitly (I think I erroneously recalled ancient APIs pre-dating "struct path"; I'm rusty) and that it's possible to use the generic simple_setattr(). When I grepped the kernel tree for this yesterday, I ended up thinking simple_setattr() would only be right for fs types without an inode->i_op->setattr. Now I see ramfs_file_inode_operations defines .setattr to simple_setattr, so maybe that's why it works for you - I guess on tmpfs? Anyway, it's helpful to have this approach validated. So thanks again. There's also: On Sat, Nov 17, 2018 at 08:51:26PM +0100, Solar Designer wrote: > A simpler and more portable alternative would probably be > override_creds(), *chmod(), *chown(), revert_creds(). This is probably > similar to what kernel nfsd does legitimately. We didn't support override_creds() in LKRG before 0.5, but that caused occasional false positives. Adam reluctantly added an exception for override_creds() ... revert_creds() in 0.5. Exploits can use this too, mimicking normal kernel behavior. There are many other convenient bypass possibilities as well. Adam's thinking is we could detect many (ab)uses of kernel APIs from unexpected places by analyzing call chains (through stack frames). My thinking is we didn't intend to become a control flow integrity enforcement project, and doing so from an LKM would be at best difficult. Then, if we're to provide "security through diversity" only, then even having non-optional code integrity checking is excessive - exploits typically don't patch kernel code, but only modify process credentials. LKRG's code integrity checking does happen to detect some pre-existing rootkits, though: https://www.defensive-security.com/blog/playing-with-linux-kernel-runtime-guard-lkrg Discussion on Twitter: https://twitter.com/cr0nym/status/1063368081530077184 https://twitter.com/solardiz/status/1063782606779469824 So rather than try to address these bypasses via ROP chains, maybe we should take a step back and make CI optional, to be able to more consistently target only typical exploits that don't try to bypass LKRG. On the offensive side, you could want to look into making exploits such as Andrey's PoC you started with more portable across different kernel builds. Instead of hard-coding many per-kernel offsets, can you possibly find and program a weird machine that would pattern-search for all other offsets it needs? Would this weird machine program require fewer hard-coded addresses than it needs to find for the actual exploit? If so, it'd be a net win. Pattern search is easier done when you're running custom code (I had pattern search for WinExec in my Windows NT shellcode in late 1996 for some portability across Windows builds while not dealing with lower-level syscalls directly), and is harder to do from a ROP chain (I'm not aware of this having been implemented yet - so it sounds like fun and an appropriate challenge for you now). This would be relevant both with and without LKRG. Alexander
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.