Warning! See "Security" section at the end.
Somewhat an inverse to sudo
but with security first.
git clone https://github.com/hilbix/suid.git
cd suid
make
sudo make install
Afterwards you can run something as
suid command args..
suid
is inverse to sudo
in the sense, that sudo
is user->command
, where suid
is command->user
.
Return values:
See /etc/suid.conf
sample file and /etc/suid.conf.d/
sample directory.
Why not sudo
?
sudo
becomes the parent of the called program. This is for additinal safety, because in former times you were able to send signals to suid
programs. So the forked suid
programs cannot access the PID of the caller (and sudo
does not expose the parent to the child either).
I do not like sudo
to allow users to do things on a system level. Also the sudoers
file syntax is far from intuitive and the calling convention of sudo
is ugly. Instead I think it is far more easy to wrap it like suid
does and empower the called command to sort things out (safely).
suid
is very easy to use, as it does not involve passwords (for now).
suid
allows to call (and control) SUID-aware programs without need to set SUID flags in filesystem
Call a script?
#!
) was lost in suid
v1.1.0 after using fexecve
(POSIX.1-2008) in favor of execve
(POSIX.1-2001).W
now. This has the disadvantage that it leaks the file descriptor of the script to the interpreter.:sh:/path/to/script:args..
instead of :/path/to/script:args..
/bin/sh
, so it looses the bit better security of fexecve
compared to execve
(see NOTES
section in man fexecve
).:sh
is the short form of :/bin/sh:-c:--:exec "$0" "$@"
Call a suid capable program?
root:root
and have mode 755
or even less./etc/suid.conf
configure it as usual./path/to/bin
with suid:
, that's all.socklinger80::::::suid:/usr/local/bin/socklinger:outeripv4address\:80:./miniweb.sh
/usr/local/bin/socklinger
has no SUID flag set.socklinger
is a suid capable program./miniweb.sh
in the current directory.suid:
then ./miniweb.sh
would be served as root.socklinger80::nobody:nogroup::/:root:/usr/local/bin/socklinger:outeripv4address\:80:/srv/miniweb.sh
root:
is a convenience to call the program as root, but preseed the unprivileged user with the given nobody:nogroup
.socklinger
drops privileges, it will become nobody:nogroup
/srv/miniweb.sh
does.nobody:nogroup
to whatever you expect in production.Why is :
escaped to \\:\:
and arguments should be followed by \\:
?
:
can be written as-is with separating spaces changed to :
\
, it is sufficient to add a \
in front of each literal :
in a command\
, you need to append \\:
on the argument to allow the next separator.\:
sequences in the argument, fully escape :
with \\:\:
to make it unambiguous.:
to \\:\:
\\::
def es(*cmd): return "\\\\::".join([str(a).replace(":", "\\\\:\\:") for a in cmd])
/(?<!\\):/
\:
with :
\:
with the empty string.def de(s): return [a.replace("\\:",":").replace("\\:","") for a in re.split(r'(?<!\\):', s)]
suid
is a bit faster and a bit more clever than this
as no regex are needed, also only a single character at-a-time needs to be looked at::
is encountered check the previous character for \
. If not, it is a separator.\:
, so remove the \
. Look at the characer before.\
, then remove the caracter, too, we are ready (the :
is swallowed).\:
, so just output :
(note that we already removed the \
).:
then state=state2 and return, else output c and return\
then state=state3 and return, else output separator and goto state0\
then state=state0 and return, else output :
and goto state0Is suid
secure?
Hope so. I did my best to avoid common pitfalls. But no guarantees, though.
If you find a bug, please open an Issue at GitHub.
When sending pull requests, please stick to the "license". (This is, abandon all Copyright from what you wrote.)
suid
does not automagically secure your wrappers in /etc/suid.conf
, so do not use insecure directories like /tmp/
(dirs with write access only from root
should be ok).
It is designed with following design principles in mind:
Other conf?
For security reasons suid
configuration is kept in /etc/suid.conf
and files /etc/suid.conf.d/*.conf
It would be very difficult to allow several different suid
wrappers with autoconfig. So there is only one supported.
Missing privilege separation directory: /var/run/sshd
This can happen if you try to run suid sshd
when /etc/suid.conf
has a line like:
sshd::::D:/:/usr/sbin/sshd:-D
Solution: Wrap sshd
a bit deeper:
sshd::::D:/:/bin/sh:-c:mkdir -pm700 /var/run/sshd && { flock -nx 1 && exec /usr/sbin/sshd -D </dev/null; } >> /var/run/sshd/lock 2>&1
This way you can start sshd
on Windows 10 with a .bat
like this:
echo exec suid sshd; | C:\Windows\System32\bash.exe
This then looks very nice and natural (here with putty localhost
):
$ pstree -p init(1)───sshd(2)───sshd(5)───sshd(38)─┬─bash(39)───vim(134) └─bash(92)───pstree(135)
Debianized version?
I'm working on it, extremely slowly.
However I probably do not have time to become a Debian maintainer myself.
License?
See License below.
Yes, this is not really a license, but it defines the rules.
This Works is placed under the terms of the Copyright Less License, see file COPYRIGHT.CLL. USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
Read:
This is free as in free beer, free speech and free baby.
Copyright on DNA is contradicting human rights.
suid
has a strict "secure by default" policy.
This section records the security related changes.
If any major or minor security flaw is fixed:
suid
will default to the most secure variant,Hence, if your setup is broken afterwards, you perhaps lived in danger. (If not does not mean you lived safe!) Now you can check and perhaps enable the option which opens the security hole again. But then you apparently know what you are doing.
Version 0.1.0 adds ShellShock prevention
bash
ususally is safe against ShellShock nowadays.S
to allow the ShellShock patternVersion 1.0.0 closes a major security hole
Version 2.0.0 protects against CVE-2016-2779
setsid()
is used to disable TIOCSTI attacks on /dev/tty
T
to get rid of setsid()
end re-enable TIOCSTI.Version 2.4.0 changes debug output (flag 'D') and corrects some other infos
suid.conf.d.example/sudo-cve-2021-3156.conf.ex
Version 3.0.0 closes a MAJOR security flaw for :root:
modifier, and repairs :sh:
and :bash:
:root:
modifier and this command was writeable by the targeted user as well. This error can still be made easily by executing a shell as command which then runs a script of a foreign user. Hopefully the now working :bash:
and :sh:
modifiers can help to prevent that common mistake better (as you do not need to run a shell, just use the right modifier to execute the script). Note that suid
cannot protect magically against calling the wrong script from the configured command. (Today. In future perhaps namespaces can protect even against that.)suid
's point of view, but probably not MAJOR from your view. However the changes are MAJOR too, affecting all 3 modifiers (but nothing else). When upgrading to this version, please thorougly test all commands which use :root:
, :sh:
or :bash:
.:bash:
and :sh:
were ridiculously broken, while the old :root:
behavior can be gained by wrapping the command into /bin/bash
or similar (as the shell is owned by root, suid
cannot detect any permission problem on what the shell does).:sh:
and :bash:
improve security, because suid
is able to test the permissions of both, the script and the shell this way. So instead you wrapping it into the shell, just use the script directly and use the modifier.Version 3.2.0 might be affected by CVE-2023-4911 if statically linked
glibc
is updatedmake static
target in Makefile
and some people might accidentally be able to use that