Tommy has asked for the wisdom of the Perl Monks concerning the following question:
So it turns out you can do suid perl scripts without suid Perl installed. Sort of.
The "Sort of" part of the above statement is what leads me to seek the wisdom of the Perl Monks yet again. I want to change the "Sort of" into a "That's right".
I got the idea yesterday that I'd like to have an suid Perl script, because, because. It's to run on my Linux machine, and I'm the only user. Yes, I'm aware of sudo. Yes I'm aware of security implications in a multi-user environment or on an enterprise server. However this is my machine and I want to do it, just to see if it can be done.
In order to make sure users on a system don't accidentally run PAR apps that unzip to the same location and accidentally wipe out one another's PAR temp files, the executable creates its temporary directory with permissions of 0770, and then immediately checks if it is owned by $<. If it is not, the executable immediately bails with a message like "./suid_script: private subdirectory /tmp/par-746f6d6d79 is unsafe (please remove it and retry your operation)". So you get it: unless the temp directory is owned by the real UID running the script (not the assumed ID of root in an suid scenario), your PAR app takes its marbles and goes home. Not fun, but indeed a good security practice by the author of the code, I must admit.
Still, this leaves me with a problem. I thought I would try to take things into my own hands and I patched $DIST/myldr/mktmpdir.c of the module. Patched is a glorified word for "I commented out the if statement in the C code that does the ownership check". I then rebuilt and reinstalled the distribution. I recompiled the PAR executable -- now without the restriction in place, and ran it. Segfault. NOOOOO!
Oh look! If you watch the executable in action with strace, you can see that it segfaults for a good reason, even if I don't like it. With the ownership check removed in mktmpdir.c, my PAR executable runs...right into a wall. The compiled script which has been chown()'ed to root:root and chmod()'ed u+s, runs in suid mode as expected. The aforementioned pseudo-random temp directory is created with root ownership and permissions of 0700. But somewhere in the inner-workings of things unseen, for reasons I don't understand (yet), my PAR suid executable tries to extract its payload into the temp directory as $<. Naturally, that's never going to work, because user "tommy" can't write to root's mode 700 directory. And that's where head starts hitting the desk. I don't think I can outfox this one without help. So, do any ideas come to mind? (Smiling nervously).
This doesn't really make a difference. The problem happens in the PAR executable before this code ever runs.
#!/usr/bin/env perl use 5.017; # I have a tasty perlbrew use strict; use warnings; say 'Hello world'; exit;
#!/bin/bash sudo rm -rf /tmp/par* && sudo rm -rf suid_script && pp --clean -o suid_script suid_script.pl && sudo chown root:root suid_script && sudo chmod +x suid_script && sudo chmod u+s suid_script && stat suid_script && rm -rf /tmp/par*
Hopefully someone out there has some idea of what I can try next. In the mean time I'm going to try some more "patching"...
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: suid Perl with App::PAR::Packer (pp)
by Tommy (Chaplain) on Oct 13, 2013 at 00:57 UTC | |
by Tommy (Chaplain) on Oct 13, 2013 at 19:50 UTC | |
by Anonymous Monk on Oct 13, 2013 at 20:05 UTC | |
by Tommy (Chaplain) on Oct 14, 2013 at 04:12 UTC |