oss-sec mailing list archives
Re: Re: Address Sanitizer local root
From: Rich Felker <dalias () libc org>
Date: Thu, 18 Feb 2016 20:07:30 -0500
On Thu, Feb 18, 2016 at 11:19:10PM +0000, Darren Martyn wrote:
Hi List, Figured I would add this to the thread to keep it amusing. Here is a fully functioning local root by clobbering /etc/ld.so.preload instead of /etc/shadow (which breaks things spectacularly). I am using a fairly messy "symlink spray"/"symlink carpet bombing" technique. Simply point it at a setuid-root binary compiled with asan and away it goes. Video: https://www.youtube.com/watch?v=jhSIm3auQMk PoC Code: https://gist.github.com/0x27/9ff2c8fb445b6ab9c94e Development/Testing was done on a Debian 8.3 VM that was last updated last week. Now, I wonder - what can actually be done to mitigate against this, besides "don't use ASAN in production"? Is there something that can be done ASAN-side? Because due to how ld.so.preload is parsed so, uh, forgivingly, all the attacker needs to control is one line in the output file. Could it check for symlinks before writing the log?
Fixing this whole class of bugs is trivial -- just don't process environment vars or other invoker-controlled input when run suid. For most things you would want to call secure_getenv (glibc) or issetugid (BSD) to achieve this but for sanitizer libs it may make more sense to just access the aux vector directly and check AT_SECURE and related items. Of course there's a lot more state that the attacker invoking a suid binary controlls -- resource limits, open file descriptors, controlling ttys, signal state, etc. This also needs to be dealt with. On a more general level, the kind of diagnostic introspection the sanitizer libs do is just unsafe in general. Once you have a known-compromised process state, the only thing safe to do is inducing program termination asap. Processing complex data structures is unsafe. Unwinding is unsafe. Function calls (especially via GOT/PLT) and even normal system calls (on i386 where the vdso syscall pointer is stored just after the thread stack) are unsafe. For hardening purposes you need either an inline __builtin_trap() (and hope nobody's catching SIGILL/SIGSEGV/SIGABRT) or ideally an inline [rt_sigprocmask, getpid, kill] syscall sequence. Analysis of the crashing process, if desired, should be left to an external debugger, not put in the sanitizer libs just because it's "convenient". Rich
Current thread:
- Re: Address Sanitizer local root, (continued)
- Re: Address Sanitizer local root Konstantin Serebryany (Feb 17)
- Re: Address Sanitizer local root Daniel Micay (Feb 17)
- Re: Address Sanitizer local root Rich Felker (Feb 19)
- Re: Address Sanitizer local root Daniel Micay (Feb 19)
- Re: Address Sanitizer local root Daniel Micay (Feb 17)
- Re: Address Sanitizer local root Konstantin Serebryany (Feb 17)
- Re: Address Sanitizer local root Hanno Böck (Feb 18)
- Re: Address Sanitizer local root Balint Reczey (Feb 18)
- Re: Address Sanitizer local root Daniel Micay (Feb 18)
- Re: Address Sanitizer local root Gynvael Coldwind (Feb 18)
- Re: Address Sanitizer local root Robert Święcki (Feb 18)
- Re: Address Sanitizer local root Darren Martyn (Feb 18)
- Re: Re: Address Sanitizer local root Rich Felker (Feb 18)
- Re: Re: Address Sanitizer local root Gynvael Coldwind (Feb 18)