0x00 命令注入
payload:
127.0.0.1 | ipconfig
13||ipconfig
127.0.0.1&ipconfig
127.0.0.1&&ipconfig
上面的方式主要是通过管道符让系统执行了命令。‘
以下是常用的管道符:
0x01 windows系列支持的管道符
|
直接执行后面的语句
||
如果前面执行的语句出错,则执行后面的语句,前面的语句只能为假
&
如果前面的语句为假则直接执行后面的语句,前面的语句可假可真
&&
如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句只能为真
0x02 linux支持的管道符:
;
执行完前面的语句再执行后面的语句
|
显示后面语句执行的结果
||
当前面的语句执行出错时,执行后面的语句
&
如果前面的语句为假则直接执行后面的语句,前面的语句可假可真
&&
如果前面的语句为假则直接出错,也不执行后面的,前面的语句只能为真
0x01php代码注入
0x01 挑战1
由下图可以看出,页面直接输出了url中的参数data的值,
检测是否会造成代码执行,
http://127.0.0.1/btslab/vulnerability/phpinjection/challenge1.php?data=phpinfo(),
可以看到,这里存在命令注入漏洞
0x02 挑战2
页面将data参数的值转换为大写输出到了页面
再次测试,是否存在命令执行
payload:http://127.0.0.1/btslab/vulnerability/phpinjection/challenge2.php?data=phpinfo()
可以看到,服务器并没有解析执行,
再次尝试:http://127.0.0.1/btslab/vulnerability/phpinjection/challenge2.php?data=<?php phpinfo();?>
,发现页面没有输出,说明服务器存在过滤
payload:http://127.0.0.1/btslab/vulnerability/phpinjection/challenge2.php?data=${phpinfo()}
代码注入成功执行。
我们看看源码
其中最关键的就是preg_replace()函数。
其实最关键的还是正则表达式中的/e
参数,正是由于该参数,preg_replace
函数中的第二个参数replacement会被解析为php代码来执行,下面是官方文档说明
其实就是一句话,当正则表达式中存在/e
参数时,preg_replace
函数中的第二个参数replacement就会被当做是eval
函数的参数来执行,这就是造成代码执行的原因所在。正是由于这个原因,所以在php版本的更新中可以看到,这个函数已经用 preg_replace_callback() 代替。
但是这里还有一个问题,如果有留意就会发现:
http://127.0.0.1/btslab/vulnerability/phpinjection/challenge2.php?data=phpinfo()
没有代码执行;
http://127.0.0.1/btslab/vulnerability/phpinjection/challenge2.php?data=${phpinfo()}
则会造成代码执行。
why???
两个请求的差别就在于${}
,还是不明,why???
我们先看看,去掉e
,正则匹配到的结果是啥,我们将之打印出来
可以从上图清楚的看到,正则匹配的结果是strtoupper("${phpinfo()}")
,即在e
匹配模式下,传递到eval()
函数中的参数是strtoupper("${phpinfo()}")
,所以最终的结果就是eval(strtoupper("${phpinfo()}"))
这条语句执行的结果,
所以,这就是preg_replace
函数会造成代码执行的根本原因。
为了对比,我们看看http://127.0.0.1/btslab/vulnerability/phpinjection/challenge2.php?data=phpinfo()
,
正则匹配结果:strtoupper("phpinfo()")
执行结果eval(strtoupper("phpinfo()"))
,函数phpinfo()
并没有并解析执行