webshell是攻击者使用的恶意脚本,其目的是方便攻击者对已经受到攻击的WEB应用程序进行持久控制。webshell本身不能攻击或利用远程漏洞,因此它始终是攻击产生的结果。
攻击者可以利用常见的漏洞,如SQL注入、远程文件包含(RFI)、FTP、命令执行,甚至使用跨站点脚本(XSS)作为攻击的一部分,以上传webshell。webshell的通用功能包括但不限于shell命令执行、代码执行、数据库枚举和文件管理。
webshell通常包含一个后门,允许攻击者远程访问,并能在任何时候控制服务器。这样攻击者省去了每次访问被攻击服务器需要重新利用漏洞的时间。攻击者也可能选择自己修复漏洞,以确保没有其他人会利用该漏洞。这样,攻击者可以保持低调,避免与管理员进行任何交互。值得一提的是,一些流行的webshell使用密码验证和其他技术来确保只有上传webshell的攻击者才能访问它。这些技术包括将脚本锁定到特定的自定义键值对、HTTP头、特定的cookie值、特定的IP地址或这些技术的组合。
文件格式webshell发展史:Web服务器管理页面——> 大马——>小马拉大马——>一句话木马——>加密一句话木马。
AST是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构, 它产生于编译过程中语法分析阶段,由词法分析阶段的Token单元组合而来,然后再经过语义分析阶段、中间代码生成阶段转化成目标机器可识别的机器码。
由于编程语言的本质往往是模棱两可的。为了避免这种歧义可通过抽象语法树提高代码可读性,并对代码进行语义分析,赋予其抽象的属性,同时AST中不包含无关紧要的标点符号和分隔符(大括号、分号、圆括号、空格、换行等),当前webshell的混淆手法基本是将恶意代码进行拆解分散到整个文件,通过遍历AST中节点的属性对代码进行相应的处理,当其属性属于定义中混淆手法中种类时,对其进行处理,最终实现解混淆。
首先来看下AST的优势处理场景,能够做到一个什么样的效果。
1、变量替换
# 处理前
$a = 'assert';
$a($_GET['cmd']);
# 处理后
$a = 'assert';
assert($_GET['cmd']);
2、二元运算求解
# 处理前
$a = 'a'.'s'.'s'.'e'.'r'.'t';
$a($_GET['cmd']);
# 处理后
$a = 'assert';
assert($_GET['cmd']);
3、编码解码
# 处理前
$a = 'eval($_GET['cmd']);';
$b = base64_encode($a);
eval(base64_decode($b));
# 处理后
$a = 'eval($_GET['cmd']);';
$b = 'ZXZhbCgkX0dFVFsnY21kJ10pOw==';
eval('eval($_GET['cmd']);');
1、Parser
array(2) {
[ ]=>
object(PhpParserNodeStmtExpression)
[ ]=>
object(PhpParserNodeExprAssign)
[ ]=>
object(PhpParserNodeExprVariable)
[ ]=>
string(1) "a"
[ ]=>
array(2) {
[ ]=>
int(2)
[ ]=>
int(2)
}
}
[ ]=>
object(PhpParserNodeScalarString_)
[ ]=>
string(6) "assert"
[ ]=>
array(3) {
[ ]=>
int(2)
[ ]=>
int(2)
[ ]=>
int(1)
}
}
[ ]=>
array(2) {
[ ]=>
int(2)
[ ]=>
int(2)
}
}
[ ]=>
array(2) {
[ ]=>
int(2)
[ ]=>
int(2)
}
}
[ ]=>
object(PhpParserNodeStmtExpression)
[ ]=>
object(PhpParserNodeExprFuncCall)
[ ]=>
object(PhpParserNodeExprVariable)
[ ]=>
string(1) "a"
[ ]=>
array(2) {
[ ]=>
int(3)
[ ]=>
int(3)
}
}
[ ]=>
array(1) {
[ ]=>
object(PhpParserNodeArg)
[ ]=>
NULL
[ ]=>
object(PhpParserNodeExprArrayDimFetch)
[ ]=>
object(PhpParserNodeExprVariable)
[ ]=>
string(4) "_GET"
[ ]=>
array(2) {
[ ]=>
int(3)
[ ]=>
int(3)
}
}
[ ]=>
object(PhpParserNodeScalarString_)
[ ]=>
string(3) "cmd"
[ ]=>
array(3) {
[ ]=>
int(3)
[ ]=>
int(3)
[ ]=>
int(1)
}
}
[ ]=>
array(2) {
[ ]=>
int(3)
[ ]=>
int(3)
}
}
[ ]=>
bool(false)
[ ]=>
bool(false)
[ ]=>
array(2) {
[ ]=>
int(3)
[ ]=>
int(3)
}
}
}
[ ]=>
array(2) {
[ ]=>
int(3)
[ ]=>
int(3)
}
}
[ ]=>
array(2) {
[ ]=>
int(3)
[ ]=>
int(3)
}
}
}
2.1 简单语句
$a = 'assert'; 属于变量赋值,则把变量a和其值存入缓存,当后续出现变量a时用’assert’对变量a进行替换。
Expression-FuncCall-variable变成Expression-FuncCall-name。
2.2 函数/类方法
对于白名单中的系统函数以及不存在污点变量的函数调用可以直接执行获取函数结果,比如常用的编码混淆函数.
function t($a){
eval($a);
}
t(“111”)
在解析过程中,t函数的函数体在实际解析过程会变成
function t($a){
$a = “111”;
eval(“111”)
}
2.3 条件判断
2.4 循环语句
该程序基本实现了循环语句的解释器功能,循环语句要小心循环死循环,所以保险起见,对循环次数做了计数
3、webshell研判
https://github.com/nikic/PHP-Parser
索隐实验室是长沙火线云网络科技有限公司的安全研究团队之一,索隐寓意发现隐秘的攻击。索隐实验室聚焦威胁检测与分析技术,包括入侵检测、溯源分析、自动化应急响应等方向。
原文始发于微信公众号(火线云安全研究团队):基于AST的webshell检测
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论