
Hacking with environment variables - pentestercrab
https://www.elttam.com/blog/env/
======
awirth
See also the sudo bad environment variable list[1], which I recently found a
15 year old typo in.[2]

[1]: [https://github.com/sudo-
project/sudo/blob/master/plugins/sud...](https://github.com/sudo-
project/sudo/blob/master/plugins/sudoers/env.c#L138) [2]:
[https://www.sudo.ws/repos/sudo/rev/bdf9c9e7f455](https://www.sudo.ws/repos/sudo/rev/bdf9c9e7f455)

~~~
cookiengineer
This is such a good example on why security is hard.

I mean, good intentions, should've worked, but a single mistake wasn't
discovered among all of the features involved in locking it down as hard as
possible.

Security is a fight nobody can win, because it's an N-1 relationship of
reassuring your own mistakes vs. finding a single mistake as an opportunity.

~~~
hannob
Isn't this more an example of "fail-open design is bad, use fail-close"? Or in
other words "make an allowlist, not a blocklist"?

I mean look at those variables, this seems like a loosing battle. PERLLIB,
PERL5LIB etc. - what if there's a PERL6LIB at some point or a
NEWSCRIPTINGLANGUAGELIB variable?

~~~
awirth
Yes. This is why running without `env_reset` is considered inherently insecure
and the typo fix wasn't considered a security fix by the sudo maintainers.

The list is still relevant to this discussion though as a nice "greatest hits"
cheat-sheet of fun environment variables to play with here.

------
shanemhansen
I did something like this once. My University had an full screen kiosk browser
that was locked down. Well it turns out that you could "customize" Firefox,
add in a missing button, get to the print screen and change the executable
from "lpr" to $TERM which would immediately pop a shell.

Good times.

~~~
plett
My university let students put procmail files in their home directories to
filter their incoming email. I created a .procmailrc file which set a DISPLAY
env variable and then spawned an xterm process. That popped up a terminal on
the machine I was sitting at with a shell on the mail server which had write
access to every student's home directory.

------
lunixbochs
This was a huge component of a 2020 DEFCON CTF qualifier challenge that only
Samurai and PPP solved, where you had to get code execution or arbitrary file
read out of as many setuid binaries as possible, after installing basically
every cli Debian package and changing them to setuid.

There are some very interesting ways to load shared objects or read files with
environment variables, and we even found ways to leverage common libraries
like readline and gconv to pop apps that used them.

~~~
rwmj
Why would you change "every cli Debian package" to setuid and not expect
hundreds of exploits? Solution is not to do something so silly.

~~~
dmurray
Because in the real world, you might have a vulnerability that lets you run
one of those packages as root. The competition is to show how many of those
you could exploit.

Of course some of them are trivial, you don't get any props for showing
arbitrary file reading when you can run bash or perl as root. But exploiting
readline that way is pretty interesting!

------
RcouF1uZ4gsC
>An unexpected exception to this is the antigravity module. The Python
developers included an easter egg in 2008 which can be triggered by running
import antigravity. This import will immediately open your browser to the xkcd
comic that joked that import antigravity in Python would grant you the ability
to fly.

> As for how the antigravity module opens your browser, it uses another module
> from the standard library called webbrowser. This module checks your PATH
> for a large variety of browsers, including mosaic, opera, skipstone,
> konqueror, chrome, chromium, firefox, links, elinks and lynx. It also
> accepts an environment variable BROWSER that lets you specify which process
> should be executed.

It was the possibility of security vulnerabilities that made software
companies (more specifically Microsoft[0]) eschew easter eggs. Every feature,
every line of code potentially increases your attack surface, especially if it
interacts with other features.

0\. [https://docs.microsoft.com/en-
us/archive/blogs/larryosterman...](https://docs.microsoft.com/en-
us/archive/blogs/larryosterman/why-no-easter-eggs)

~~~
userbinator
_It was the possibility of security vulnerabilities that made software
companies (more specifically Microsoft[0]) eschew easter eggs._

...and yet there are plenty of horror stories about Win10 coming with lots of
other "surprises" like Candy Crush installed by default, ads that fetch
resources over the Internet, etc. I can almost hear a PM somewhere say "but
they're not easter eggs, because they are documented somewhere." I'm sure
people would be far less surprised and disgusted by a "real easter egg" that
did something simple like developer's credits. Corporate bureaucracy at its
worst...

~~~
cortesoft
They aren't Easter eggs because they were probably paid to include them.

------
mmastrac
> A generic solution for Ruby has not been found yet. Ruby does accept an
> environment variable RUBYOPT to specify command-line options. The man page
> states that RUBYOPT can contain only -d, -E, -I, -K, -r, -T, -U, -v, -w, -W,
> --debug, --disable-FEATURE and --enable-FEATURE. The most promising option
> is -r which causes Ruby to load the library using require. However, this is
> limited to files with an extension of .rb or .so.

Interesting - could the -r option load a .so file with a .ctor section?

~~~
pentestercrab
Yes, that works fine. The hard part is finding a suitable .so already on the
system. The following (credit to Tavis Ormandy) creates /tmp/testing

    
    
      $ RUBYOPT="-r/usr/lib64/libpcprofile.so" PCPROFILE_OUTPUT="/tmp/testing" ruby /dev/null

------
xucheng
I understand this kind of techniques were common to attack unsafe CGI web
servers in the old time.

I wonder whether it is still the case nowadays. Is CGI still being used?

~~~
fit2rule
The Linux world is not just about servers and online.

For example, a sub-contractor at BigCo., Inc. could use a lot of this
knowledge to exfiltrate stuff.

I mean, CGI web servers are still out there - but careful that you don't
overlook a wider market for these sploits.

------
teddyh
Regarding Python scripts: All Python scripts runnable by more than one user
should really have the “-I” option on the shebang line; this, among other
things, ignores all PYTHON* environment variables. (Note: Python 3 only.)

~~~
josephcsible
Why? Isn't it safer to just have sudo always handle resetting the environment?
Or do you mean if you're using a custom setuid wrapper?

~~~
teddyh
I said nothing about sudo or setuid; I simply meant what I wrote: A Python
program runnable by more than one user, where I meant user as in uid.

~~~
josephcsible
That makes even less sense then. Are you trying to protect users from
attacking themselves? What specific threat do you think you'd mitigate by
doing that?

------
mkesper
When you control environment variables, can't you also LDPRELOAD scary stuff?

~~~
pentestercrab
The second sentence of the blog post states:

    
    
       We were also unable to control the contents of a file on disk, and bruteforcing process identifiers (PIDs) and file descriptors found no interesting results, eliminating remote LD_PRELOAD exploitation.

~~~
mkesper
Oops, have overseen that one.

------
svnpenn
Warning, website wont load at all unless JavaScript is enabled.

~~~
chrismorgan
Delete the first element in the body, <section id="preloader">, which sits on
top of the rest and blocks it from view.

This is one of the two standard failure techniques. (I glom <body
style="opacity:0"> and the likes in the same category as this site.) The other
category is where the body has no content, and JavaScript injects it. I’m
undecided which is worse, but I think that it’s probably this one, because the
developer pretty much went out of their way to slow things down in the name of
subjective prettiness (and perhaps just because they wrote the rest of the
markup/styling/code badly), and thereby broke things. Whereas I can at least
understand _why_ you’d do the whole thing in JavaScript, even if it’s not
something I’m willing to do.

~~~
StavrosK
Is that to avoid the FOUC?

~~~
chrismorgan
Typically, yes.

But I just want to be clear on this reason: it’s a fundamentally bad technique
that slows things down and harms accessibility, both of which are far more
important than your website potentially appearing _slightly_ imperfectly while
it loads, like just >99.4% of websites. (And if you’re doing something that
means that your page looks worse than most while loading, you’re probably
loading your resources in the wrong way somehow, e.g. putting a critical
stylesheet at the end of the document rather than in the head.)

Other reasons for doing this are:

• A splash screen sort of experience. Yeah, there are still some around doing
this, though it’s fortunately uncommon. It’s often a precursor to this second
reason:

• A misguided desire to animate things into place at the right time (kind of
an extension of the FOUC, I guess). Gratuitous animating-in of content as you
scroll, which this meshes with, is a horrible thing to do, by the way:
although it’s decidedly popular on homepages, most people dislike it (ranging
from mild displeasure to rage-quitting the site), because it’s distracting,
slows things down and adds _nothing_. Just _don’t do it_.

In short, I see no legitimate reason to _ever_ set document opacity to zero or
to put a loading spinner on top of everything else, _in CSS_. (In JavaScript,
maybe—there are defensible reasons; but never in CSS.)

