Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20150526222149.GB4292@chaz.gmail.com>
Date: Tue, 26 May 2015 23:21:49 +0100
From: Stephane Chazelas <stephane.chazelas@...il.com>
To: oss-security@...ts.openwall.com
Subject: Re: Re: hwclock(8) SUID privilege escalation

2015-05-26 17:30:40 +0200, up201407890@...nos.dcc.fc.up.pt:
[...]
> >No, bash does NOT drop privileges if ruid != euid when called as
> >sh either . If it were, it would break those commands that use
> >system()/popen() from suid/sgid executables (which arguably they
> >shouldn't be doing) and expect the euid/egid to be preserved.
[...]
> I'm talking about this:
> 
> # gcc -xc - -otest <<< 'main(int argc, char *argv[]){system(argv[1]);}'
> # chmod +s test
> # exit
> $ ls -l ./test /bin/sh
> lrwxrwxrwx. 1 root root 9 May 24 11:58 /bin/sh -> /bin/bash
> -rwsrwsr-x. 1 root root 8497 May 26 15:36 test
> $ ./test /bin/sh
> $ whoami
> saken
> 
> $ su
> Password:
> # ln -sf /bin/dash /bin/sh
> # exit
> $ ./test /bin/sh
> # whoami
> root

I do get "root" with both dash and bash, but after
investigation, that's because I'm on a Debian based system. So
we're both right, but my version is only true on Debian.

Since 1999, Debian (and derivatives) does disable the dropping
of privileged when called as sh.
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=52586

$ cat bash-4.3/debian/patches/privmode.diff
# DP: XXX missing description
# DP:
# DP: Comment from Chet Ramey <chet@...e.ins.cwru.edu>:
# DP:
# DP: Nope.  This will allow setuid scripts if not called as `sh' and not
# DP: called with the -p option.  I won't install this.


--- a/shell.c
+++ b/shell.c
@@ -492,7 +492,7 @@
   if (dump_translatable_strings)
     read_but_dont_execute = 1;

-  if (running_setuid && privileged_mode == 0)
+  if (running_setuid && privileged_mode == 0 && act_like_sh == 0)
     disable_priv_mode ();

   /* Need to get the argument to a -c option processed in the

(looks like from the comment, Chet misinterpreted the patch. It
will allow setuid scripts if called as sh with or without -p.
When not called as sh, you need -p to allow setuid (not drop
privileges)).

[...]
> I believe that's what setuid()/seteuid()/setreuid() are for if you
> really want to execute stuff as another user.
> 
> Setting setuid(0) before the system() call on my test and executing
> /bin/sh (which is linked to bash) would drop me into a root shell.
> This doesn't happen if there is no setuid(0) call.
> The same doesn't happen when /bin/sh is linked to dash, there is no
> need for setuid(0), it will drop me instantly into a root shell.
[...]

But then if you do that, the shell can no longer detect it is
called as setuid and cannot enter the privileged mode (which
disables export functions importing, BASH_ENV...).

You'd need to call sh with -p, but system()/popen() won't do
that for you.

IOW, to work around that security restriction in non-Debian
bash, one could end up doing something less safe (not only call
system() in a setuid command, but also do it in a way that
prevents the shell from taking precautions).

-- 
Stephane

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

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