I'm messing around with the security of a setuid binary (with the intention of disclosing anything I find to the author, obviously). I'm pretty sure it has an arbitrary code execution vulnerability because it invokes a shell script and it doesn't sanitize the environment - I thought of bash's export -f
but I can't actually make a proof of concept work.
The basic problem is that for some reason, BASH_FUNC_foobar%%
(where foobar
is the function being exported) is mysteriously vanishing from the environment in some subprocesses. It works with non-shells:
% env 'BASH_FUNC_foobar%%=() { echo pwd lol; }' env | grep BASH
BASH_FUNC_foobar%%=() { echo pwd lol; }
But if I replace env | grep BASH
with the actual program name, modified to dump the environment (basically just system("env")
in the C source), this variable is removed. The same happens when I specify sh
as the command to invoke, although weirdly enough, if I specify bash
then the function is picked up just fine.
Note that on my test system /bin/sh
is provided by dash
.
What the heck is going on? Why is this variable disappearing?
sh
?sh
.system()
clears that one up. Something likeextern char **environ; for (char **p = environ; *p; p++) printf("%s\n", *p);
should show the ones with non-valid names too.