SETUID perl script

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

SETUID perl script

Christopher Zimmermann-4
Hi,

I'm trying to chroot and drop privileges in a perl script. But somehow
I'm not even able to run it setuid root. The setuid bit gets ignored
completely. But as I understand sys/sys/exec_script.h. The
SETUIDSCRIPTS feature is enabled by default. What am I missing?


/tmp% ls -l test.pl
-rwsrwx---  1 root  wheel  165 Apr 24 21:07 test.pl
/tmp% cat test.pl
#!/usr/bin/perl -wT

use strict;

sub ids () { print "RUID=$< EUID=$> RGID=$( EGID=$)\n" }

ids;
$< = $> = 1000;
ids;
$> = $< = 0;
ids;
/tmp% ./test.pl
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001

Reply | Threaded
Open this post in threaded view
|

Re: SETUID perl script

Matthew Weigel
On 24.04.2012 14:22, Christopher Zimmermann wrote:
> Hi,
>
> I'm trying to chroot and drop privileges in a perl script. But
> somehow
> I'm not even able to run it setuid root. The setuid bit gets ignored
> completely. But as I understand sys/sys/exec_script.h. The
> SETUIDSCRIPTS feature is enabled by default. What am I missing?

> /tmp% ls -l test.pl

Check the mount options for whatever filesystem /tmp lives on.  Chances
are
good it's its own filesystem, and is mounted nosuid.
--
  Matthew Weigel
  hacker
  unique & idempot . ent

Reply | Threaded
Open this post in threaded view
|

Re: SETUID perl script

Christopher Zimmermann-4
On Tue, 24 Apr 2012 14:48:18 -0500
Matthew Weigel <[hidden email]> wrote:

> On 24.04.2012 14:22, Christopher Zimmermann wrote:
> > Hi,
> >
> > I'm trying to chroot and drop privileges in a perl script. But
> > somehow
> > I'm not even able to run it setuid root. The setuid bit gets ignored
> > completely. But as I understand sys/sys/exec_script.h. The
> > SETUIDSCRIPTS feature is enabled by default. What am I missing?
>
> > /tmp% ls -l test.pl
>
> Check the mount options for whatever filesystem /tmp lives on.
> Chances are
> good it's its own filesystem, and is mounted nosuid.

Ah, of course. Thanks!

Reply | Threaded
Open this post in threaded view
|

Re: SETUID perl script leaves backdoor open

Christopher Zimmermann-4
After short testing I found a bug or at least a dangerous pitfall.

This leaves a backdoor open (probably in the saved UID):

#!/usr/bin/perl -wT

use strict;
require POSIX;

sub ids () { print "RUID=$< EUID=$> RGID=$( EGID=$)\n" }

print "Running $^X $0\n";

ids;
$> = $< = $<;
ids;
$> = $< = 0;
ids;

======= OUTPUT: ========
Running /usr/bin/perl /dev/fd/3
RUID=1000 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=0 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001


While this drops privileges permanently:

#!/usr/bin/perl -wT

use strict;
require POSIX;

sub ids () { print "RUID=$< EUID=$> RGID=$( EGID=$)\n" }

print "Running $^X $0\n";

ids;
$< = $> = $<;
ids;
$> = $< = 0;
ids;

======= OUTPUT: ========
Running /usr/bin/perl /dev/fd/3
RUID=1000 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001
RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501 1001


Backdoor is still open when doing "$> = $< = 1000" or
"$< = 1000; $> = 1000;". POSIX::setuid($<) works fine.

Reply | Threaded
Open this post in threaded view
|

Re: SETUID perl script leaves backdoor open

Christopher Zimmermann-4
In reply to this post by Christopher Zimmermann-4
After short testing I found a bug or at least a dangerous pitfall.

This leaves a backdoor open (probably in the saved UID):

#!/usr/bin/perl -wT

use strict;
require POSIX;

 sub ids () { print "RUID=$< EUID=$> RGID=$( EGID=$)\n" }

print "Running $^X $0\n";

ids;
$> = $< = $<;
ids;
$> = $< = 0;
ids;

======= OUTPUT: ========
Running /usr/bin/perl /dev/fd/3
RUID=1000 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501
1001 RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9
117 501 1001 RUID=0 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5
9 117 501 1001


While this drops privileges permanently:

#!/usr/bin/perl -wT

use strict;
require POSIX;

 sub ids () { print "RUID=$< EUID=$> RGID=$( EGID=$)\n" }

print "Running $^X $0\n";

ids;
$< = $> = $<;
ids;
$> = $< = 0;
ids;

======= OUTPUT: ========
Running /usr/bin/perl /dev/fd/3
RUID=1000 EUID=0 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9 117 501
1001 RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10 10 0 5 9
117 501 1001 RUID=1000 EUID=1000 RGID=10 10 0 5 9 117 501 1001 EGID=10
10 0 5 9 117 501 1001


Backdoor is still open when doing "$> = $< = 1000" or
"$< = 1000; $> = 1000;". POSIX::setuid($<) works fine.

Reply | Threaded
Open this post in threaded view
|

Re: SETUID perl script leaves backdoor open after dropping privileges

Christopher Zimmermann-4
As requested, here's the same test case a little more readable:

This leaves a backdoor open (possibly in the saved UID):

======================================
#!/usr/bin/perl -wT

use strict;
use English qw(-no_match_vars);

sub ids { print "RUID=$REAL_USER_ID EUID=$EFFECTIVE_USER_ID\n" }

ids;
$REAL_USER_ID = 1000;
$EFFECTIVE_USER_ID = 1000;
ids;
$REAL_USER_ID = $EFFECTIVE_USER_ID = 0;
ids;

======================================
OUTPUT:

RUID=1000 EUID=0
RUID=1000 EUID=1000
RUID=0 EUID=0


Still, changing the order of the "*_USER_ID = 1000" lines or using
POSIX::setuid(1000) works as expected.

Christopher

Reply | Threaded
Open this post in threaded view
|

Re: SETUID perl script leaves backdoor open after dropping privileges

Ted Unangst-6
In reply to this post by Christopher Zimmermann-4
On Wed, Apr 25, 2012 at 07:15, Christopher Zimmermann wrote:
> As requested, here's the same test case a little more readable:
>
> This leaves a backdoor open (possibly in the saved UID):

Yes, if you don't clear the saved uid, you can still switch back to
it.  You should use setresuid if it's available, because the semantics
of setting one uid at a time are a mess.

www.cs.berkeley.edu/~daw/papers/setuid-usenix02.pdf