Open hilbix opened 2 years ago
To be more specific:
env -i --
A
then re-enables passing Env with SUID_
prefixedB
then passing "mostly-harmless" environment variables unchanged (no prefix). Dangerous variables are still prefixed.AB
then passes environment completely unchanged, including extremely dangerous variables like LD_PRELOAD
S
to pass even ShellShock variablesAdditionally AB
should NOT work by default, such that if you add this, the command is disabled until explicitly enabled.
Hence we need to invent some way to silence this warning. The idea here is:
suid
is enhanced and detects some more "bad" practice. Then the Magic changes, again.I am currently undecided how to archive that. Here is a plan:
Two things are important:
suid
Either it becomes part of the line (like being added to the flags field)
or it must be added to the next line as a comment (looks like #HASH#
)
I like the latter approach, as this does not need to change the line (which might be error prone)
and can easily be scripted (inserting a line is not a big problem).
Calculating the hash code also can be implemented in linereader
on the fly (if needed).
The "next line" approach also can support #HASH#HASH#HASH#
to enable variants of a line.
This is good for testing and development, when you often change the flags (or other aspects) and do not want to be disturbed by the line become disabled.
Alternatively it can be "previous line", such that we just can remember the previous line in some buffer.
This even leaves opportunities like passing that line into the environment, such that the called script is able to verify that it is legit.
C
(like Context), which then passes some suid
internal possibly security related context to the script (which might not be suitable to scripts which are not aware of this nature)
C
then requires the authenticating line, too.We cannot use C
as it is already taken by arg0 given to cmd is first arg given to 'suid'
Free letters are
E
which I do want to use already, even that it matches "environment"H
perhaps something like H
elpJKLM
a block I want to keep for futureQ
is just too nice for things like Q
uietV
is just too nice for things like V
erboseXYZ
is a block I want to keep unused currentlyI vote for V
, as this puts something "verbosely" into environment. You can also read this as "verify".
List of possibly exploitable environment variables:
IFS
- may affect read
in scriptsTERM
- may affect the used terminal emulatorHOSTALIASES
RESOLV_ADD_TRIM_DOMAINS
RESOLV_MULTI
RESOLV_OVERRIDE_TRIM_DOMAINS
RESOLV_REORDER
RESOLV_SERV_ORDER
RESOLV_SPOOF_CHECK
List of known to be dangerous environment variables:
PATH
- can disturb the search pathPS1
- can make shells execute things on promptLANGUAGE
- see nextLC_*
- may change the outcome of a script
LC_ALL
- may affect outcome of a program and irritate scriptsPOSIXLY_CORRECT
- may make argument processing unpredictableList of highly dangerous environment variables:
LD_*
- also see below
LD_DEBUG_PATH
- may override system files?GLIBC_TUNABLES
- CVE-2023-4911I cannot find information about this in the
glibc
-doc, instead see LFS: http://www.scratchbox.org/documentation/general/tutorials/glibcenv.html
Lists from glibc
(is there a way to automate this?):
MALLOC_CHECK_
GCONV_PATH
HOSTALIASES
LD_AOUT_LIBRARY_PATH
LD_AOUT_PRELOAD
LD_DEBUG_OUTPUT
LD_LIBRARY_PATH
LD_ORIGIN_PATH
LD_PRELOAD
LD_PROFILE
LOCALDOMAIN
LOCPATH
MALLOC_TRACE
NLSPATH
RESOLV_HOST_CONF
RES_OPTIONS
TMPDIR
TZDIR
Note that suid
never will detect presence of files like /etc/suid-debug
,
because it always must behave 100% predicatble and such settings not only affects
the debuged part but everything.
To enable debugging you must alter /etc/suid.conf
or /etc/suid.conf.*/*.conf
files.
Notes:
getconf -a
lists some variablesGLIBC_TUNABLES
is not amongst themLD_*
is not amongst themDue to CVE-2023-4911 I changed my mind:
Apparently it is far too dangerous to pass unknown variables to a script. Hence the new plan is twofold:
SUID_
prefixed should be safe.
env -i
:noenv:
for thissuid
is clumsy due to SUID_
prefix
root
context
SSH_AUTH_SOCK
So this probably better:
A
(keep free B
and V
)A
and B
are missing, pass everything as SUID_
as nowA
for unprivileged context
A
like "All"A
for privileged context (even if called by root
):
A
like "Allowed"SUID_
prefixNotes:
A
always is the first option
Hence the updated idea:
NAME:PW:UID:GID:OPTIONS:DIR:COMMAND
is how a command looks
A
UID
and GID
are privileged:suid:
, :root:
or :toor:
etc. present#NAME ENV1 ENV2 ENV3
then declares the passed environment variablesRationale:
#NAME
protects against artifacts showing up at the wrong location
cat
things together, so we need some guard herevim
)#hash#
) is better than some complicated authentication processFor Authentication, suid
should pass additional environment variables:
SUIDCMD
should carry NAME
SUIDENV
is the space separated list of environment variables (from the next line)
A
optionSUIDOPT
the OPTIONS
SUIDDIR
the directory as given
chroot
marker like /./
SUIDPWD
which passes the "realpath" of the directory before changing into SUIDDIR
SUID_PWD
may carry the logical PWD
from before which may differ from "realpath"But those should go into another issue ..
Currently most environment variables are prefixed with
SUID_
to disarm unknown possible future environmental bombs likeLD_PRELOAD
in the past. But it is a PITA to move all necessary variables back, just in case we need them as-is (and the program is secure like statically compiled).Hence proposal for a new way to handle environment:
TERM
, defaultPATH
,SUIDUID
,SUIDGID
andSUIDPWD
B
like Before)A
like Attention)PATH
andLD_*
variables (and in future possibly others).AB
)S
to allow ShellShockAlternatives:
/usr/bin/env:-i:--:
is similar to the proposed above new default.Rationale:
suid
.YZ
orXY
do not sound as good asAB
. Hence proposingAB