核心功能: - 6 层检测管线: L0 结构分析 → L1 ClamAV → L2 文档深度检测 → L3 关键词匹配 → L4 YARA → L5 PE/二进制 - FastAPI + PostgreSQL + Redis + Docker Compose 架构 - 客户端 HMAC-SHA256 签名鉴权 + 限流 + 幂等性 - 控制台 UI (登录/Dashboard/诊断中心/策略管理/任务列表/测试中心/产品介绍页) - 三层诊断定时器 (error_scan 30s / db_aggregate 30s / container_check 5min) 并发与稳定性修复: - 诊断定时器 Redis 时间槽位锁 (多 worker 同一槽位只有一个执行) - JSONL 存储 fcntl 跨进程排他锁 + 容错解码 + 原子重写 - 移除 SQLite fallback, 统一 PostgreSQL - API_CLIENTS 脱敏为环境变量, .env 已 .gitignore
346 lines
14 KiB
Plaintext
346 lines
14 KiB
Plaintext
// =============================================================================
|
||
// MeshSafe L2B YARA 规则集 — Webshell 专项(C3)
|
||
// =============================================================================
|
||
//
|
||
// 设计原则:
|
||
// - 所有规则使用 2-3 个特征组合命中,避免单一关键词导致误杀
|
||
// - 光闸场景误报代价极高(阻断合法文件传输),宁可漏报不轻易阻断
|
||
// - 命中后作为 finding 交给 PolicyEngine 权重累加,不直接零容忍
|
||
//
|
||
// 元数据规范:
|
||
// risk_level = critical | high | medium | low
|
||
// category = "C3"
|
||
// false_positive_rate = low | medium | high
|
||
//
|
||
// 维护:
|
||
// - 新 Webshell 工具/变体出现时,优先新增"工具特征"组合规则
|
||
// - 纯 PHP/JSP 反序列化 payload 单特征也可能有价值,但组合原则仍适用
|
||
// =============================================================================
|
||
|
||
|
||
// =============================================================================
|
||
// PHP Webshell —— 一行马 / 变形马
|
||
// =============================================================================
|
||
|
||
// PHP 一行 eval($_POST) 组合(常见的菜刀/蚁剑/冰蝎基础形态)
|
||
// 单一 eval + $_GET/$_POST 误伤太大,必须"动态执行入口 + 用户输入 + 输出回显"三点组合
|
||
rule C3_PHP_Webshell_Oneliner {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C3"
|
||
false_positive_rate = "low"
|
||
reference = "OWASP Web Shell Cheat Sheet"
|
||
description = "PHP 一行 Webshell:eval + 超全局变量 + 输出回显 组合命中"
|
||
strings:
|
||
$entrypoint = /eval\s*\(\s*\$\s*_(GET|POST|REQUEST|COOKIE)\s*\[.+\]\s*\)/ ascii
|
||
// 备选入口:assert / create_function / preg_replace / system
|
||
$entryp2 = /assert\s*\(\s*\$\s*_(GET|POST|REQUEST)/ ascii
|
||
$entryp3 = /create_function\s*\(\s*['"]['"]\s*,\s*\$\s*_(GET|POST|REQUEST)/ ascii
|
||
// 回显手段:print / echo / var_dump / die
|
||
$echo = /print|echo|var_dump|die/ ascii
|
||
condition:
|
||
($entrypoint or $entryp2 or $entryp3) and $echo
|
||
}
|
||
|
||
// PHP Webshell —— 多层解码(base64 + gzinflate + str_rot13)
|
||
rule C3_PHP_Webshell_Obfuscated {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C3"
|
||
false_positive_rate = "medium"
|
||
reference = "典型 Webshell 变形手段"
|
||
description = "PHP 解码链组合(base64_decode + gzinflate / str_rot13 + eval)"
|
||
strings:
|
||
$b64 = "base64_decode" ascii wide
|
||
$eval = "eval(" ascii wide
|
||
$gzinflate = "gzinflate" ascii wide
|
||
$rot13 = "str_rot13" ascii wide
|
||
$assert = "assert(" ascii wide
|
||
$createfn = "create_function" ascii wide
|
||
condition:
|
||
// base64_decode + (eval|assert|create_function) = 解码后动态执行
|
||
$b64 and ($eval or $assert or $createfn)
|
||
or
|
||
// 解码链:base64 + gzinflate / str_rot13 + 执行
|
||
$b64 and ($gzinflate or $rot13) and ($eval or $assert)
|
||
}
|
||
|
||
// PHP Webshell —— 变量变形($$a = $_POST['cmd'];$$a($_POST['arg']))
|
||
rule C3_PHP_Webshell_VariableDeformation {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C3"
|
||
false_positive_rate = "medium"
|
||
reference = "PHP 变量变形 Webshell 特征"
|
||
description = "PHP 可变变量组合:$$ 或 ${$ 配合超全局变量"
|
||
strings:
|
||
$doubledollar = /\$\$\w+\s*=\s*\$\s*_(GET|POST|REQUEST)/ ascii
|
||
$curlyvar = /\$\{\$\w+\}\s*\(/ ascii
|
||
$superglobal = /\$_/ ascii
|
||
$invoke = /\$\$\w+\s*\(/ ascii
|
||
condition:
|
||
($doubledollar or ($curlyvar and $invoke)) and $superglobal
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// JSP / Java Webshell —— 反射执行 + 反序列化
|
||
// =============================================================================
|
||
|
||
// JSP Runtime.exec + ProcessBuilder 反射执行链
|
||
rule C3_JSP_Webshell_RuntimeExec {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C3"
|
||
false_positive_rate = "low"
|
||
reference = "https://blog.csdn.net/JavaWebshell"
|
||
description = "JSP 通过 Runtime.exec / ProcessBuilder 执行命令,配合反射 / 密码变量(cmd/pass/pwd)"
|
||
strings:
|
||
$runtime = "Runtime.getRuntime()" ascii
|
||
$exec = ".exec(" ascii
|
||
$processbuilder = "ProcessBuilder" ascii
|
||
$cmdparam = /(cmd|pass|pwd|exec|shell)\s*=/ ascii
|
||
$reflection = /Class\.forName|getMethod|getDeclaredMethod|Method\.invoke/ ascii
|
||
$requestparam = /request\.getParameter\s*\(\s*['"](cmd|pass|pwd|exec|shell)['"]/ ascii
|
||
$printwriter = /PrintWriter|getWriter|out\.println/ ascii
|
||
condition:
|
||
// Runtime.exec + 命令参数名 + 回显 = 完整 Webshell
|
||
$runtime and $exec and ($requestparam or $printwriter)
|
||
or
|
||
// ProcessBuilder + 命令参数名
|
||
$processbuilder and ($cmdparam or $requestparam)
|
||
or
|
||
// 反射链 + getRuntime().exec
|
||
$runtime and $exec and any of ($reflection*)
|
||
}
|
||
|
||
// JSP 反序列化 CommonsCollections / ysoerial
|
||
rule C3_JSP_Webshell_Deserialization {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C3"
|
||
false_positive_rate = "low"
|
||
reference = "https://github.com/frohoff/ysoserial"
|
||
description = "Java 反序列化利用链:CommonsCollections / Gadgets / InvokerTransformer"
|
||
strings:
|
||
$icc = "InvokerTransformer" ascii wide
|
||
$lzy = "LazyMap" ascii wide
|
||
$trn = "TransformerFactory" ascii wide
|
||
$ccimpl = "TemplatesImpl" ascii wide
|
||
$gadget = "CommonsCollections" ascii wide
|
||
$readobj = /readObject\s*\(/ ascii wide
|
||
$objectinputstream = "ObjectInputStream" ascii wide
|
||
$execchain = /getRuntime\(\)\.exec|ProcessBuilder/ ascii wide
|
||
condition:
|
||
// 反序列化链:readObject + InvokerTransformer / LazyMap / TemplatesImpl + Runtime.exec
|
||
$readobj and ($icc or $lzy or $trn or $ccimpl or $gadget) and any of ($execchain*)
|
||
or
|
||
// 直接 ObjectInputStream + 已知 Gadget
|
||
$objectinputstream and ($icc or $ccimpl or $gadget)
|
||
}
|
||
|
||
// JSP Servlet Filter / Listener 注入型内存马
|
||
rule C3_JSP_Webshell_MemoryShell {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C3"
|
||
false_positive_rate = "medium"
|
||
reference = "Tomcat / JBoss 内存马分析"
|
||
description = "JSP 动态注册 Filter / Listener / Valve 实现内存 Webshell"
|
||
strings:
|
||
$filterdef = "FilterDef" ascii
|
||
$applicationfilter = "ApplicationFilterConfig" ascii
|
||
$addfilter = /addFilterDef|addFilterMap|addListener/ ascii
|
||
$servletcontext = /ServletContext|getServletContext/ ascii
|
||
$filter = "implements Filter" ascii
|
||
$listener = /implements\s+(HttpSession|Servlet|Request)Listener/ ascii
|
||
$standardctx = "StandardContext" ascii
|
||
// 命令执行特征
|
||
$runtime = "Runtime.getRuntime()" ascii
|
||
$execchain = /getRuntime\(\)\.exec|ProcessBuilder/ ascii wide
|
||
condition:
|
||
// 动态 Filter 注册链:StandardContext + addFilterDef + FilterDef + ApplicationFilterConfig
|
||
$standardctx and $addfilter and $filterdef and $applicationfilter
|
||
or
|
||
// Listener 注册链:ServletContext + Listener interface + addListener
|
||
$servletcontext and $listener and any of ($addfilter)
|
||
or
|
||
// Filter 接口 + 命令执行(反射/内联)
|
||
$filter and ($runtime or $execchain)
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// 冰蝎 / 哥斯拉 / 蚁剑 —— 工具专属特征
|
||
// =============================================================================
|
||
|
||
// 冰蝎(Behinder)—— AES 加密通道 + 固定类名特征
|
||
rule C3_Webshell_Behinder {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C3"
|
||
false_positive_rate = "low"
|
||
reference = "https://github.com/rebeyond/Behinder"
|
||
description = "冰蝎 Webshell 特征:AES/CBC/PKCS5Padding 或反射解密"
|
||
strings:
|
||
$aes = /AES\s*\/?\s*CBC\s*\/?\s*PKCS5Padding|AES\/CBC\/PKCS5Padding/ ascii wide
|
||
$cipherget = "Cipher.getInstance" ascii wide
|
||
$doFinal = /\.doFinal\s*\(/ ascii wide
|
||
$secret = /secretKey|SecretKeySpec|PasswordKey/ ascii wide
|
||
$toolname = /Behinder|behinder|冰蝎/ ascii wide nocase
|
||
// JSP 命令执行特征
|
||
$execchain1 = /getRuntime\(\)\.exec/ ascii wide
|
||
$execchain2 = "ProcessBuilder" ascii wide
|
||
// PHP 执行特征
|
||
$phpdecrypt = "openssl_decrypt" ascii
|
||
$phpb64 = "base64_decode" ascii
|
||
$phpeval = "eval(" ascii
|
||
$phpassert = "assert(" ascii
|
||
condition:
|
||
// 冰蝎 JSP:AES 加密解密 + secretKey + Runtime.exec
|
||
$cipherget and $aes and $doFinal and $secret and any of ($execchain*)
|
||
or
|
||
// 冰蝎 PHP:openssl_encrypt + base64 + eval/assert
|
||
$phpdecrypt and $phpb64 and ($phpeval or $phpassert)
|
||
or
|
||
// 直接工具名(极低概率误报)
|
||
$toolname
|
||
}
|
||
|
||
// 哥斯拉(Godzilla)—— 加密通信 + 动态字节码加载
|
||
rule C3_Webshell_Godzilla {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C3"
|
||
false_positive_rate = "low"
|
||
reference = "https://github.com/whale1017/godzilla"
|
||
description = "哥斯拉 Webshell 特征:ASM 字节码生成 + ClassLoader 动态加载"
|
||
strings:
|
||
$asm = "org.objectweb.asm" ascii wide
|
||
$classloader = /defineClass|ClassLoader|loadClass/ ascii wide
|
||
$bytes = /toByteArray|writeByteArray/ ascii wide
|
||
$reflect = /setAccessible|getDeclaredMethod/ ascii wide
|
||
$deserialize = "deserialize" ascii wide
|
||
$toolname = /Godzilla|godzilla|哥斯拉/ ascii wide nocase
|
||
condition:
|
||
// ASM 字节码 + ClassLoader.defineClass = 动态加载
|
||
$asm and ($classloader or $bytes) and any of ($reflect*)
|
||
or
|
||
// 反序列化 + ClassLoader
|
||
$deserialize and $classloader
|
||
or
|
||
$toolname
|
||
}
|
||
|
||
// 蚁剑(AntSword)—— 基础 eval + 加密通信 + 自定义 Header
|
||
rule C3_Webshell_AntSword {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C3"
|
||
false_positive_rate = "medium"
|
||
reference = "https://github.com/AntSwordProject/AntSword-Labs"
|
||
description = "蚁剑 Webshell 特征:assert + 特定请求参数加密 + 自定义 HTTP 头"
|
||
strings:
|
||
$phpassert = /assert\s*\(\s*\$\s*_(GET|POST|REQUEST)/ ascii
|
||
$phpcipher = /openssl_(encrypt|decrypt)|mcrypt_(encrypt|decrypt)/ ascii
|
||
$header = /X-Request-Id|AntSword|antsword/ ascii
|
||
$jspcipher = /AES|DES|RSA|Cipher/ ascii wide
|
||
condition:
|
||
// PHP:assert + openssl/mcrypt + 蚁剑特征 header
|
||
$phpassert and $phpcipher and $header
|
||
or
|
||
// JSP:加密算法 + 特征 header(可能是蚁剑 JSP 变体)
|
||
any of ($jspcipher) and $header
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// ASP / ASP.NET Webshell
|
||
// =============================================================================
|
||
|
||
// ASP.NET Eval / Execute + Server.CreateObject("Wscript.Shell")
|
||
rule C3_Webshell_ASPNET {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C3"
|
||
false_positive_rate = "low"
|
||
reference = "ASP.NET Webshell 常见手法"
|
||
description = "ASP.NET Webshell:Eval/Execute + Server.CreateObject/Wscript.Shell + Process.Start"
|
||
strings:
|
||
$eval = /\bEval\s*\(\s*Request\s*\(/ ascii wide
|
||
$execute = /\bExecute\s*\(\s*Request\s*\(/ ascii wide
|
||
$wscript = /Server\.CreateObject\s*\(\s*["']Wscript\.Shell["']\s*\)/ ascii wide
|
||
$processstart = /Process\.Start|Diagnostics\.Process/ ascii wide
|
||
$reflect = /Activator\.CreateInstance|Assembly\.Load|BinaryFormatter/ ascii wide
|
||
condition:
|
||
// Eval + 动态执行
|
||
($eval or $execute) and ($wscript or $processstart or any of ($reflect*))
|
||
or
|
||
// Wscript.Shell + Process.Start
|
||
$wscript and $processstart
|
||
or
|
||
// BinaryFormatter 反序列化 + 命令执行
|
||
any of ($reflect*) and $processstart
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// ASP Classic (VBScript)
|
||
// =============================================================================
|
||
|
||
rule C3_Webshell_ASP_Classic {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C3"
|
||
false_positive_rate = "medium"
|
||
reference = "ASP Classic Webshell"
|
||
description = "ASP Classic (VBScript) Webshell:Execute + Wscript.Shell + Request"
|
||
strings:
|
||
$execute = /\bExecute\s*\(\s*Request\s*\(/ ascii
|
||
$wscript = "WScript.Shell" ascii
|
||
$shellrun = /\.Run\s*\(\s*["']cmd/ ascii
|
||
$servercreate = "Server.CreateObject" ascii
|
||
$request = "Request(" ascii
|
||
condition:
|
||
// Execute + Request 取参
|
||
$execute and $request
|
||
or
|
||
// Server.CreateObject(WScript.Shell) + cmd Run
|
||
$servercreate and $wscript and $shellrun
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// 通用:所有 Webshell 类(PHP/JSP/ASP)的 ProcessBuilder + 输出回显
|
||
// =============================================================================
|
||
|
||
rule C3_Webshell_CommandExecutionEcho {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C3"
|
||
false_positive_rate = "low"
|
||
reference = "综合 Webshell 命令执行链"
|
||
description = "任何语言的 Webshell:命令执行 + 输出回显(三特征同时命中)"
|
||
strings:
|
||
$exec_php = /(system|exec|passthru|shell_exec|popen|proc_open)\s*\(\s*\$\s*_(GET|POST|REQUEST)/ ascii
|
||
$exec_java = /Runtime\.getRuntime\(\)\.exec|ProcessBuilder/ ascii
|
||
$exec_asp = /\.Run\s*\(\s*["']cmd|Process\.Start/ ascii
|
||
// 回显通道
|
||
$echo_php = /echo|print|passthru/ ascii
|
||
$echo_java = /getWriter|getOutputStream|PrintWriter|out\.println|response\.getWriter/ ascii
|
||
$echo_asp = /Response\.Write|output\.Write/ ascii
|
||
// 参数来源(外部可控)
|
||
$param_java = /request\.getParameter|HttpServletRequest|getParameter/ ascii wide
|
||
$param_php = /\$_(GET|POST|REQUEST)\s*\[/ ascii
|
||
$param_asp = /Request\("|\bRequest\(/ ascii
|
||
condition:
|
||
// PHP 路径
|
||
$exec_php and $echo_php and $param_php
|
||
or
|
||
// Java/JSP 路径
|
||
$exec_java and any of ($echo_java*) and any of ($param_java*)
|
||
or
|
||
// ASP 路径
|
||
$exec_asp and $echo_asp and ($param_php or $param_asp)
|
||
}
|