feat: MeshSafe 文件摆渡安全卫士 v1.0 初始提交

核心功能:
- 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
This commit is contained in:
2026-10-28 19:07:11 +08:00
commit 16f134e328
113 changed files with 24604 additions and 0 deletions

307
rules/linux.yar Normal file
View File

@@ -0,0 +1,307 @@
// =============================================================================
// MeshSafe L2B YARA 规则集 —— Linux / 跨平台后门专项(C7)
// =============================================================================
//
// 设计原则:
// - 光闸摆渡场景,所有规则 2-3 特征组合命中,避免单一关键词误伤合法 Shell/Python 代码
// - 覆盖范围:反弹 Shell、持久化(crontab/authorized_keys/systemd/LD_PRELOAD)、
// Rootkit 特征、挖矿通用特征
// - 命中后作为 finding 交给 PolicyEngine 权重累加
//
// 维护:
// - 新后门工具/家族出现时优先补充 "工具名 + 持久化手段" 组合
// =============================================================================
// =============================================================================
// C7-1 反弹 Shell(多种语言实现)
// =============================================================================
rule C7_Linux_ReverseShell_Bash {
meta:
risk_level = "critical"
category = "C7"
false_positive_rate = "low"
reference = "MITRE ATT&CK T1059.004 Bash"
description = "Bash 反弹 Shell 组合:/dev/tcp + bash -i 或 sh -c"
strings:
$devtcp = /\/dev\/tcp\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{2,5}/ ascii
$bash_i = "bash -i" ascii
$sh_c = /sh\s+-c\s+['"]bash -i/ ascii
$exec3 = "exec 3<>/dev/tcp/" ascii
$exec4 = "exec 4>&0 0>&1 1>&4" ascii
condition:
// /dev/tcp/IP:PORT + bash -i 这两个必须同时出现
$devtcp and ($bash_i or $sh_c or $exec3)
or
// exec fd 重定向链
$exec3 and $exec4
}
rule C7_Linux_ReverseShell_NC {
meta:
risk_level = "critical"
category = "C7"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1059.004 Netcat"
description = "nc/ncat 反弹 Shell:-e/-c 参数指定 bash 或 sh"
strings:
$nc1 = /nc\s+[\w.-]+\s+\d{2,5}\s+-e\s+(\/bin\/(ba)?sh|bash|sh)/ ascii
$nc2 = /ncat\s+[\w.-]+\s+\d{2,5}\s+-e\s+(\/bin\/(ba)?sh|bash|sh)/ ascii
$nc3 = /nc\s+[\w.-]+\s+\d{2,5}\s+-c\s+(\/bin\/(ba)?sh|bash|sh)/ ascii
$nc4 = /netcat\s+[\w.-]+\s+\d{2,5}\s+-e/ ascii
$mkfifo = /mkfifo\s+\/tmp\/\w+;\s*(nc|ncat)\s+/ ascii
condition:
any of ($*)
}
rule C7_Linux_ReverseShell_Python {
meta:
risk_level = "high"
category = "C7"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1059.006 Python"
description = "Python 反弹 Shell:socket + exec/bin/sh + pty"
strings:
$socket1 = "import socket" ascii
$socket2 = "socket.socket" ascii
$pty = "import pty" ascii
$sub = "import subprocess" ascii
$sh = /\/bin\/(ba)?sh/ ascii
$osdup2 = "os.dup2" ascii
$execv = "os.execv" ascii
condition:
// socket + pty + /bin/bash = 完整 Python pty 反弹
($socket1 or $socket2) and $pty and $sh
or
// socket + subprocess + /bin/sh + dup2 = 经典模式
($socket1 or $socket2) and $sub and $sh and $osdup2
or
// socket + os.execv + /bin/bash
($socket1 or $socket2) and $execv and $sh
}
rule C7_Linux_ReverseShell_Perl {
meta:
risk_level = "high"
category = "C7"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1059.005 Perl"
description = "Perl 反弹 Shell:IO::Socket + exec + /bin/sh"
strings:
$iosocket = "IO::Socket::INET" ascii nocase
$socketvar = /\$s\s*=\s*IO::Socket/ ascii
$exec = /exec\s+['"]\/bin\/(ba)?sh['"]/ ascii
$open = /open\s*\(.*<&\$\{?s\}?/ ascii
$eval = /eval\s+reverse\s+['"]/ ascii
condition:
($iosocket or $socketvar) and ($exec or $open or $eval)
}
rule C7_Linux_ReverseShell_Socat {
meta:
risk_level = "high"
category = "C7"
false_positive_rate = "low"
reference = "MITRE ATT&CK T1059.004 Socat"
description = "socat 反弹 Shell:TCP-LISTEN + EXEC:/bin/bash"
strings:
$socat1 = /socat\s+(TCP-LISTEN:\d{2,5},?\s*(reuseaddr|fork)?|TCP4:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{2,5})/ ascii
$socat2 = /EXEC:\/bin\/(ba)?sh/ ascii
$socat3 = /EXEC:'\/bin\/(ba)?sh'/ ascii
condition:
any of ($socat1*) and any of ($socat2, $socat3)
}
rule C7_Linux_ReverseShell_Misc {
meta:
risk_level = "medium"
category = "C7"
false_positive_rate = "medium"
reference = "多种语言反弹 Shell 通用特征"
description = "通用反弹 Shell 标记:/dev/tcp 或 /dev/udp 或 reverse shell 工具名"
strings:
$devudp = /\/dev\/udp\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{2,5}/ ascii
$bashc = /bash\s+-c\s+['"].*\/dev\/(tcp|udp)/ ascii
$dash_e = /\/bin\/bash\s+-e\s+['"]/ ascii
$hydra = /Hydra|crackmap|weevely|meterpreter|msfconsole|msfvenom/ ascii nocase
$reverseshell = /reverse[_\s]?shell|shell[_\s]?shock/ ascii nocase
condition:
any of ($devudp, $bashc, $dash_e) or any of ($hydra, $reverseshell)
}
// =============================================================================
// C7-2 持久化 —— crontab / authorized_keys / systemd
// =============================================================================
rule C7_Linux_Persistence_Crontab {
meta:
risk_level = "high"
category = "C7"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1053.003 Cron"
description = "crontab 持久化:下载执行 + .bashrc 注入 + /tmp/.hidden 目录"
strings:
$crontab1 = /\*\s+\*\s+\*\s+\*\s+\*\s+(curl|wget)\s+['"]?https?:/ ascii
$crontab2 = /\*\s+\*\s+\*\s+\*\s+\*\s+(bash|sh)\s+\S+\s+['"]\/dev\/tcp/ ascii
$crontab3 = /crontab\s+-[lre]?\s+\/tmp\/\w+/ ascii
$bashrc = /\.bashrc|\.bash_profile|\.profile/ ascii
$wget = /wget\s+https?:/ ascii
$curl = /curl\s+.*\|\s*(bash|sh)/ ascii
$hidden = /\/tmp\/\.?\w+\s+&&/ ascii
condition:
any of ($crontab1, $crontab2, $crontab3)
or
$bashrc and ($wget or $curl) and $hidden
}
rule C7_Linux_Persistence_AuthorizedKeys {
meta:
risk_level = "high"
category = "C7"
false_positive_rate = "low"
reference = "MITRE ATT&CK T1098 SSH Authorized Keys"
description = "authorized_keys 写入:下载公钥 + 追加到 .ssh/authorized_keys + chmod 600"
strings:
$authkeys = /\.ssh\/authorized_keys/ ascii
$wgetkey = /wget\s+-O\s+.*authorized_keys/ ascii
$curlkey = /curl\s+.*authorized_keys/ ascii
$echokey = /echo\s+['"]ssh-(rsa|ecdsa|ed25519)/ ascii
$chmod = /chmod\s+\d{3,4}\s+\$\{?SSH_DIR\}?authorized_keys/ ascii
condition:
any of ($wgetkey, $curlkey, $echokey) or ($authkeys and any of ($wgetkey, $curlkey, $chmod))
}
rule C7_Linux_Persistence_SystemD {
meta:
risk_level = "high"
category = "C7"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1543.002 Systemd Service"
description = "恶意 systemd unit 文件:ExecStart 指向 /tmp/.hidden + multi-user.target + 反弹命令"
strings:
$unit = /\[Unit\]/ ascii
$service = /\[Service\]/ ascii
$install = /\[Install\]/ ascii
$execstart = /ExecStart=/ ascii
$multiuser = /multi-user\.target/ ascii
$hiddenpath = /\/tmp\/\.?\w+|\/var\/tmp\/\.?\w+/ ascii
$bashsh = /\/bin\/(ba)?sh\s+-c/ ascii
condition:
// 完整 unit 片段 + 可疑路径
$unit and $service and $execstart and ($hiddenpath or $bashsh)
or
// Install multi-user.target + ExecStart 反弹
$install and $multiuser and any of ($execstart, $bashsh)
}
rule C7_Linux_Persistence_LD_PRELOAD {
meta:
risk_level = "high"
category = "C7"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1574.006 LD_PRELOAD"
description = "LD_PRELOAD 劫持:环境变量注入 + .so 文件 + dlopen"
strings:
$ldpreload = /LD_PRELOAD=/ ascii
$sofile = /\.so(\.\d+)?:?/ ascii
$dlopen = "dlopen" ascii
$dlsym = "dlsym" ascii
$exportenv = /export\s+LD_PRELOAD/ ascii
condition:
($ldpreload or $exportenv) and ($sofile or $dlopen or $dlsym)
}
// =============================================================================
// C7-3 Rootkit + 挖矿通用特征
// =============================================================================
rule C7_Linux_Rootkit_KernelModule {
meta:
risk_level = "critical"
category = "C7"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1547.006 Kernel Modules and Extensions"
description = "内核模块加载:insmod/modprobe + .ko + /proc/kallsyms 隐藏"
strings:
$insmod = /insmod\s+.*\.ko/ ascii
$modprobe = /modprobe\s+.*\.ko/ ascii
$ko = /\.ko(\.xz|\.gz)?\b/ ascii
$hiddenproc = /hide_process_from_dcache|hide_module/ ascii
$proc = /\/proc\/kallsyms|\/proc\/modules/ ascii
$netstat = /\/proc\/net\/tcp|\/proc\/net\/udp/ ascii
condition:
any of ($insmod, $modprobe) and any of ($ko, $hiddenproc)
or
any of ($hiddenproc) and any of ($proc, $netstat)
}
rule C7_Linux_Miner_Generic {
meta:
risk_level = "medium"
category = "C7"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1496 Resource Hijacking"
description = "挖矿通用特征:stratum+tcp 协议 + 非标准端口(3333/5555/8080)"
strings:
$stratum = "stratum+tcp://" ascii
$stratums = "stratum+ssl://" ascii
$pool = /pool\.(xmr|mine|nanopool|coin|mining)/ ascii nocase
$port3333 = /:\s*3333\b/ ascii
$port5555 = /:\s*5555\b/ ascii
$highcpu = /nice\s+-n\s+[+-]?\d+|cpulimit\s+-l/ ascii
condition:
any of ($stratum, $stratums, $pool) and any of ($port3333, $port5555)
or
any of ($stratum, $stratums) and $highcpu
}
// =============================================================================
// C7-4 跨平台后门:Ruby + Lua + Node.js
// =============================================================================
rule C7_Misc_Ruby_Lua_ReverseShell {
meta:
risk_level = "medium"
category = "C7"
false_positive_rate = "medium"
reference = "多语言反弹 Shell"
description = "Ruby/Lua 反弹 Shell:TCPSocket + exec/system"
strings:
$ruby = "TCPSocket" ascii
$lua = "loadstring" ascii
$lua2 = "luasocket" ascii
$exec = /(exec|system|IO\.popen)\s+.*\/bin\/(ba)?sh/ ascii
condition:
any of ($ruby, $lua, $lua2) and ($exec or any of ($ruby, $lua, $lua2))
}
// =============================================================================
// C7-5 网络投毒 / MITM 工具(内网横向移动)
// =============================================================================
rule C7_Network_Tools_Malicious {
meta:
risk_level = "medium"
category = "C7"
false_positive_rate = "medium"
reference = "内网攻击工具"
description = "内网攻击工具:ettercap/responder/nmap 扫描 + SMB/DNS 投毒"
strings:
$ettercap = "ettercap" ascii nocase
$responder = /responder(\.py)?/ ascii nocase
$nmap = "nmap" ascii nocase
$smb = /--smb/ ascii
$ms17 = "ms17-010" ascii nocase
$smbghost = "SMBGhost" ascii nocase
$dnsspoof = /dns[-_]spoof|dns[-_]mitm/ ascii nocase
$arppoison = /arp[-_]poison|arp[-_]spoof/ ascii nocase
condition:
any of ($ettercap, $responder, $dnsspoof, $arppoison)
or
$nmap and ($smb or $ms17 or $smbghost)
}

403
rules/pe.yar Normal file
View File

@@ -0,0 +1,403 @@
// =============================================================================
// MeshSafe L2B YARA 规则集 —— Windows PE 恶意程序专项(C1 + C8)
// =============================================================================
//
// 设计原则:
// - 所有规则使用 2-3 特征组合命中(API 组合 + C2 URL + Mutex 持久化等)
// - binary.py 的 PE 结构分析负责:节熵 + 签名 + 可疑导入(单 API)
// - YARA 负责:多 API 组合 + 字符串组合 + 壳 + 勒索专项
// - 命中后作为 finding 交给 PolicyEngine 权重累加,不直接零容忍
//
// 范围:
// - C1: Windows PE 恶意程序(注入器 / 下载器 / RAT / Loader)
// - C8: 勒索 / 挖矿专项
// - C9: 壳 / 签名 / 结构异常(binary.py 已覆盖大部分,YARA 补充壳特征)
//
// 维护:
// - 新恶意家族出现时,优先补充"API 组合 + Mutex 名 + C2 URL"三件套
// - 壳特征(UPX/Themida/VMP)可识别后自动送沙箱深检
// =============================================================================
// =============================================================================
// C1-1 进程注入三件套(VirtualAllocEx + WriteProcessMemory + CreateRemoteThread)
// binary.py 扫了 SuspiciousImports(单个 API),但 3 个同时出现 = 必然是注入器
// =============================================================================
rule C1_PE_ProcessInjection {
meta:
risk_level = "critical"
category = "C1"
false_positive_rate = "low"
reference = "MITRE ATT&CK T1055 Process Injection"
description = "PE 文件同时导入 进程注入三件套 API = 远控/注入器特征"
strings:
$s1 = "VirtualAllocEx" ascii
$s2 = "WriteProcessMemory" ascii
$s3 = "CreateRemoteThread" ascii
// 备选:Nt 系列(NtUnmapViewOfSection + VirtualAllocEx + CreateRemoteThread)
$n1 = "NtUnmapViewOfSection" ascii
$n2 = "NtMapViewOfSection" ascii
$n3 = "ZwUnmapViewOfSection" ascii
// 也可能是 QueueUserAPC 注 APC 注入
$apc = "QueueUserAPC" ascii
// 或 SetWindowsHookEx DLL 注入
$hook = "SetWindowsHookEx" ascii
condition:
// 经典三件套(必须同时命中)
$s1 and $s2 and $s3
or
// Nt 系列内存注入(至少 2 个 Nt + 1 个注入)
(any of ($n1, $n2, $n3) and any of ($s1, $s3, $apc))
or
// APC 注入 + VirtualAllocEx
$apc and $s1
or
// Hook DLL 注入
$hook and $s1
}
// =============================================================================
// C1-2 下载器组合(网络 API + 本地持久化 / 执行)
// 单一 URLDownloadToFile 不致命,但 "下载 + 执行 + 持久化" 三件套 = Loader
// =============================================================================
rule C1_PE_Downloader_Loader {
meta:
risk_level = "high"
category = "C1"
false_positive_rate = "low"
reference = "MITRE ATT&CK T1105 Ingress Tool Transfer"
description = "下载器组合:HTTP/FTP 下载 + 写入到可疑路径 + 执行"
strings:
// 网络下载 API(任选其一)
$net1 = "URLDownloadToFile" ascii
$net2 = "InternetOpenUrl" ascii
$net3 = "WinHttpOpen" ascii
$net4 = "WinHttpOpenRequest" ascii
$net5 = "FtpOpenFile" ascii
$net6 = "DownloadFile" ascii
$net7 = "WinHttpSendRequest" ascii
// 写入/保存到本地
$save1 = "WriteFile" ascii
$save2 = "SaveToFile" ascii
$save3 = "URLDownloadToCacheFile" ascii
// 执行下载的载荷
$exec1 = "WinExec" ascii
$exec2 = "CreateProcess" ascii
$exec3 = "ShellExecute" ascii
$exec4 = "CreateRemoteThread" ascii
// 持久化(注册表/启动项)
$persist1 = "RegSetValueEx" ascii
$persist2 = "SetServiceObjectSecurity" ascii
$persist3 = "CreateService" ascii
$persist4 = "schtasks.exe" ascii
$persist5 = "RUN" ascii // HKCU\Software\Microsoft\Windows\CurrentVersion\Run
condition:
// 下载 + 保存 + 执行(三件套)
any of ($net*) and any of ($save*) and any of ($exec*)
or
// 下载 + 持久化(即使没执行也是准备投毒)
any of ($net*) and any of ($persist*)
or
// 执行 + 持久化(下载可能在运行时动态完成)
any of ($exec1, $exec2, $exec3) and any of ($persist*)
}
// =============================================================================
// C1-3 RAT / 远控特征(C2 通信 + 命令执行 + 持久化)
// =============================================================================
rule C1_PE_RAT_CommandControl {
meta:
risk_level = "critical"
category = "C1"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1071 Application Layer Protocol"
description = "RAT C2 通信特征:WinHTTP/WSASend + 命令执行 API + 可疑 URL/域名"
strings:
// C2 网络通道
$c2_send = /WSASend|send\s*\(|sendto|WinHttpSendRequest|InternetWriteFile/ ascii
$c2_recv = /WSARecv|recv\s*\(|recvfrom|WinHttpReadData|InternetReadFile/ ascii
$c2_connect = /WSAConnect|connect\s*\(|WinHttpConnect|InternetConnect/ ascii
// 命令执行
$cmd = /CreateProcess|ShellExecute|WinExec|system\s*\(|popen/ ascii
// 可疑 C2 URL(可执行文件里出现 http://...exe 或常见 C2 域名)
$c2url1 = /http:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{2,5}/ ascii
$c2url2 = /https?:\/\/[^\"\s'\)]+\.(ru|top|xyz|tk|ml|ga|gq|cf|pw|click|stream|xyz|buzz|loan)\/[^\"\s'\)]*\.exe/ ascii
$c2url3 = /(c2|panel|gate|bot|ops|serv|beacon|stage|stager)\.(ru|top|xyz|cc|io|com|net)/ ascii
condition:
// C2 通信 + 命令执行(至少两个网络 + 一个命令)
any of ($c2_send, $c2_recv, $c2_connect) and any of ($cmd*) and any of ($c2url*)
or
// C2 URL 模式 + 网络 API
any of ($c2url*) and any of ($c2_connect, $c2_send)
}
// =============================================================================
// C1-4 Mutex 互斥体名(勒索 / RAT / Loader 的持久化标记)
// 单一 Mutex 名有一定价值,但必须配合其他特征才触发
// =============================================================================
rule C1_PE_Mutex_Persistence {
meta:
risk_level = "medium"
category = "C1"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1057 Process Discovery (mutex as persistence marker)"
description = "可疑 Mutex 名称 + CreateMutex API = 持久化标记"
strings:
$createmutex = "CreateMutexA" ascii
$createmutexw = "CreateMutexW" ascii
// 常见勒索/RAT Mutex 名(大小写不敏感,含 Unicode 变体用 wide)
// LockBit
$lockbit1 = /Global\\[Ll]ock[Bb]it/ ascii
$lockbit2 = /Local\\[Ll]ock[Bb]it/ ascii
// BlackCat / ALPHV
$blackcat = /Global\\[Bb]lack[Cc]at|[Aa][Ll][Pp][Hh][Vv]/ ascii
// Ryuk
$ryuk = /RyukTask[\d]|Global\\Ryuk/ ascii
// Conti
$conti = /Global\\[Cc]onti|Local\\[Cc]onti/ ascii
// Pseudo/Dharma
$dharma = /Global\\[Dd]harma|Local\\[Dd]harma/ ascii
// 通用可疑模式:Mutex 名包含 "Mutex" + UUID 变体
$generic1 = /Global\\Mutex[0-9a-f]{8}/ ascii
// Kryptik/Qakbot
$qakbot = /[Qq]akbot|[Kk]ryptik/ ascii
// Cobalt Strike named pipe
$cs1 = /\\\\\.\\pipe\\msagent_[0-9a-f]+/ ascii
$cs2 = /\\\\\.\\pipe\\[Bb]eacon_[0-9a-f]+/ ascii
condition:
// CreateMutex + 已知家族 Mutex 名
(any of ($createmutex*)) and any of ($lockbit1, $lockbit2, $blackcat, $ryuk, $conti, $dharma, $qakbot)
or
// Cobalt Strike 命名管道特征(不需要 CreateMutex)
any of ($cs*)
or
// CreateMutex + 通用可疑 UUID Mutex
(any of ($createmutex*)) and $generic1
}
// =============================================================================
// C1-5 DLL 劫持 / LoadLibrary 动态加载
// =============================================================================
rule C1_PE_DLLHijacking {
meta:
risk_level = "high"
category = "C1"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1574 Hijack Execution Flow"
description = "PE 动态加载多个系统 DLL + 非系统路径 = DLL 劫持迹象"
strings:
$loadlib = "LoadLibraryA" ascii
$loadlibw = "LoadLibraryW" ascii
$getproc = "GetProcAddress" ascii
// 可疑加载路径(非 System32)
$path1 = /\\Users\\[^\\]+\\AppData\\Local\\Temp/ ascii
$path2 = /\\AppData\\Local\\Temp/ ascii
$path3 = /\\ProgramData\\/ ascii
$path4 = /\\Public\\Documents\\/ ascii
condition:
// LoadLibrary + 可疑路径 + GetProcAddress = 完整劫持链
(any of ($loadlib*)) and any of ($path*) and $getproc
or
// LoadLibrary + 多个可疑路径
(any of ($loadlib*)) and 2 of ($path*)
}
// =============================================================================
// C1-6 LOLBin(Living Off The Land Binary)调用特征
// 已知合法 Windows 二进制被恶意利用来执行命令
// =============================================================================
rule C1_PE_LOLBin_Usage {
meta:
risk_level = "high"
category = "C1"
false_positive_rate = "low"
reference = "https://lolbas-project.github.io/"
description = "PE 文件中出现 LOLBin 调用:certutil / mshta / rundll32 / regsvr32 / bitsadmin / wmic / msiexec"
strings:
$certutil = /certutil(\.exe)?\s+(-urlcache|-decode|-encode|-hashfile)/ ascii
$mshta = /mshta(\.exe)?\s+(https?:|javascript:|vbscript:)/ ascii
$rundll32 = /rundll32(\.exe)?\s+[A-Za-z0-9_.]+,/ ascii
$regsvr32 = /regsvr32(\.exe)?\s+\/s\s+\/u/ ascii
$bitsadmin = /bitsadmin(\.exe)?\s+(\/transfer|\/create)/ ascii
$wmic = /wmic(\.exe)?\s+(process\s+call\s+create|product\s+call)/ ascii
$msiexec = /msiexec(\.exe)?\s+\/[ia]\s+https?:/ ascii
$installutil = /installutil(\.exe)?\s+\/u\s+\/logfile=/ ascii
$syncapp = /syncapp(\.exe)?\s+\/compattrack/ ascii
$psexec = /psexec(\.exe)?\s+(-accepteula|-i\s+\d+|-w\s+https?:)/ ascii
// 命令执行 API(用于组合条件)
$exec1 = "CreateProcess" ascii
$exec2 = "ShellExecute" ascii
$exec3 = "WinExec" ascii
condition:
// 至少 1 个 LOLBin 调用 + 命令执行 API
any of ($certutil*, $mshta*, $rundll32*, $regsvr32*, $bitsadmin*, $wmic*, $msiexec*, $installutil*, $syncapp*, $psexec*)
and any of ($exec*)
}
// =============================================================================
// C8-1 勒索加密 API 组合(CryptEncrypt + BCrypt* + 文件遍历 + 删除卷影)
// =============================================================================
rule C8_Ransomware_Encryption {
meta:
risk_level = "critical"
category = "C8"
false_positive_rate = "low"
reference = "MITRE ATT&CK T1486 Data Encrypted for Impact"
description = "勒索加密链:CryptEncrypt/BCryptEncrypt + 大量文件遍历 + 卷影删除 = 勒索"
strings:
// 加密 API(至少出现两个)
$enc1 = "CryptEncrypt" ascii
$enc2 = "CryptDeriveKey" ascii
$enc3 = "BCryptEncrypt" ascii
$enc4 = "BCryptDeriveKeyPair" ascii
$enc5 = "CryptGenKey" ascii
// 文件遍历(全盘加密需要)
$enum1 = "FindFirstFileA" ascii
$enum2 = "FindFirstFileW" ascii
$enum3 = "FindNextFileA" ascii
$enum4 = "FindNextFileW" ascii
// 卷影删除(勒索前置)
$vss1 = "vssadmin" ascii
$vss2 = "delete shadows" ascii
$vss3 = "DeleteShadowCopies" ascii
$vss4 = "wmic" ascii
// 勒索信文件名变体(出现在二进制里)
$ransomnote1 = /(HOW_TO_RECOVER|RESTORE_FILES|DECRYPT_INSTRUCTIONS|README|HELP_DECRYPT|_readme|_restore)[\w.-]*\.(txt|html|png|jpg|bmp|url)/ nocase
$ransomnote2 = /\.(locky|zepto|cryptolocker|tor|crpt|encrypted|virus|wallet|pay2)/ nocase
$ransomnote3 = /bitcoin|bitcash|monero|ltc|BTC\b/ ascii
condition:
// 加密 API + 文件遍历 = 加密工具(必须至少 2 个加密 API)
(2 of ($enc*)) and any of ($enum*)
or
// 加密 API + 卷影删除 = 完整勒索
(any of ($enc*)) and any of ($vss*)
or
// 加密 API + 勒索信 + 加密文件扩展名 = 明确勒索
(any of ($enc*)) and (any of ($ransomnote1, $ransomnote2)) and $ransomnote3
}
// =============================================================================
// C8-2 挖矿(xmrig / stratum+tcp / 矿池域名)
// =============================================================================
rule C8_Mining_Monero {
meta:
risk_level = "high"
category = "C8"
false_positive_rate = "low"
reference = "MITRE ATT&CK T1496 Resource Hijacking"
description = "挖矿程序特征:xmrig 命令行参数 / stratum+tcp / 矿池域名"
strings:
// xmrig 命令行特征
$xmrig1 = "xmrig" ascii nocase
$xmrig2 = /--donate-level\s+\d+/ ascii
$xmrig3 = /-o\s+stratum\+tcp/ ascii
$xmrig4 = /--cpu-priority\s+\d/ ascii
$xmrig5 = /--max-threads-hint/ ascii
// 矿池域名(Monero)
$pool1 = "pool.xmrig.com" ascii nocase
$pool2 = "pool.minexmr.com" ascii nocase
$pool3 = "pool.supportxmr.com" ascii nocase
$pool4 = "mine.moneropool.com" ascii nocase
$pool5 = "stratum+tcp://" ascii
// CPU 高占用循环特征
$loop = /(while|for)\s*\(\s*\d+\s*[<>=]/ ascii
$thread = "CreateThread" ascii
condition:
// 至少 2 个 xmrig 特征
(any of ($xmrig1, $xmrig2, $xmrig3, $xmrig4, $xmrig5)) and 2 of ($*)
or
// stratum+tcp 矿池协议 + 多个线程创建
$pool5 and ($thread or 2 of ($xmrig*))
}
// =============================================================================
// C9 壳特征(UPX / Themida / VMProtect / Enigma)
// 壳识别后建议升级到 L3 沙箱深检,不单独阻断
// =============================================================================
rule C9_Packer_UPX {
meta:
risk_level = "medium"
category = "C9"
false_positive_rate = "low"
reference = "UPX Packer"
description = "UPX 加壳 PE:节名 UPX0 / UPX1 + UPX 签名"
strings:
$upx0 = "UPX0" ascii
$upx1 = "UPX1" ascii
$upx2 = "UPX!" ascii
$upx3 = /UPX\s+\d+\.\d+/ ascii // "UPX 3.96" 这类版本字符串
$upx4 = /UPX\b/ ascii
condition:
// 节名(两个)+ 签名
($upx0 and $upx1) or ($upx2 and any of ($upx3, $upx4))
}
rule C9_Packer_Themida_VMP {
meta:
risk_level = "medium"
category = "C9"
false_positive_rate = "low"
reference = "Themida / VMProtect"
description = "商业壳特征:Themida / VMProtect 产品标识字符串"
strings:
$themida1 = "Themida" ascii wide
$themida2 = "WinLicense" ascii wide
$themida3 = "Oreans" ascii wide
$vmp1 = "VMProtect" ascii wide
$vmp3 = "VMProtect SDK" ascii wide
condition:
any of ($themida*) or any of ($vmp*)
}
// =============================================================================
// C1-7 PE 高熵 + 大量网络 API(疑似加壳下载器)
// binary.py 的 HighEntropySection 已单独扫描,但 YARA 看"熵 + 网络"组合
// =============================================================================
rule C1_PE_EntropyHighNetwork {
meta:
risk_level = "medium"
category = "C1"
false_positive_rate = "medium"
reference = "binary.py HighEntropySection 联动"
description = "PE 同时出现:多个网络 API + 加壳特征(熵高) + 无签名"
strings:
$net1 = "InternetOpenUrl" ascii
$net2 = "WinHttpOpen" ascii
$net3 = "URLDownloadToFile" ascii
$net4 = "WSAConnect" ascii
// 壳特征
$upx = "UPX0" ascii
$themida = "Themida" ascii
condition:
// 网络 API + 壳特征 = 加壳下载器
any of ($net*) and ($upx or $themida)
}

210
rules/ransom.yar Normal file
View File

@@ -0,0 +1,210 @@
// =============================================================================
// MeshSafe L2B YARA 规则集 —— 勒索 / 挖矿专项(C8,剩余家族)
// =============================================================================
//
// 设计原则:
// - C8_Ransomware_Encryption 在 pe.yar 里已经覆盖了"加密 API + 卷影删除 + 勒索信"通用链
// - 本文件补充:具体家族特征(LockBit/BlackCat/Conti/Ryuk/Pseudo)+
// 文件扩展名黑名单变体 + 勒索信文件名模式
// - 必须满足"加密 API 组合 + 家族特征"才触发,单靠扩展名不触发
//
// 元数据规范:同 webshell.yar / pe.yar(risk_level, category, false_positive_rate)
// =============================================================================
// =============================================================================
// C8-1 LockBit 家族
// =============================================================================
rule C8_Ransomware_LockBit {
meta:
risk_level = "critical"
category = "C8"
false_positive_rate = "low"
reference = "LockBit / BitLocker 勒索家族"
description = "LockBit 家族特征:Mutex 名 + .lockbit3/.lockbit 扩展名 + CryptEncrypt"
strings:
$mutex1 = /Global\\[Ll]ock[Bb]it/ ascii
$mutex2 = /Local\\[Ll]ock[Bb]it/ ascii
$mutex3 = /LockBit[\d_]/ ascii nocase
$ext1 = /\.lockbit3?\b/ ascii nocase
$ext2 = /\.lckbt\b/ ascii nocase
$enc = /CryptEncrypt|BCryptEncrypt|CryptGenKey/ ascii
$ransomnote = /README[\d_-]*\.(html|txt|bmp|png|jpg|url)/ nocase
condition:
// Mutex + 加密 API(家族识别核心)
any of ($mutex*) and any of ($enc*)
or
// Mutex + 勒索扩展名
any of ($mutex*) and any of ($ext*)
or
// 加密 API + 家族扩展名 + 勒索信
any of ($enc*) and any of ($ext*) and $ransomnote
}
// =============================================================================
// C8-2 BlackCat / ALPHV 家族
// =============================================================================
rule C8_Ransomware_BlackCat {
meta:
risk_level = "critical"
category = "C8"
false_positive_rate = "low"
reference = "BlackCat (ALPHV) 勒索家族"
description = "BlackCat/ALPHV:Mutex + .blackcat/.bc1 扩展名 + Rust 字符串特征"
strings:
$mutex1 = /Global\\[Bb]lack[Cc]at/ ascii
$mutex2 = /[Aa][Ll][Pp][Hh][Vv]/ ascii
$ext1 = /\.blackcat\b/ ascii nocase
$ext2 = /\.bc1?\b/ ascii nocase
$rust1 = "rustc" ascii
$rust2 = "/rustc/" ascii
$enc = /CryptEncrypt|BCryptEncrypt/ ascii
$note = /BlackCat.*README|how_to_decrypt|restore_files/ ascii nocase
condition:
any of ($mutex1, $mutex2) and any of ($enc*, $ext*)
or
any of ($ext*) and any of ($rust*) and $note
}
// =============================================================================
// C8-3 Conti 家族
// =============================================================================
rule C8_Ransomware_Conti {
meta:
risk_level = "critical"
category = "C8"
false_positive_rate = "low"
reference = "Conti 勒索家族"
description = "Conti:Mutex + .conti 扩展名 + 加密 API"
strings:
$mutex1 = /Global\\[Cc]onti/ ascii
$mutex2 = /Local\\[Cc]onti/ ascii
$ext1 = /\.conti\b/ ascii nocase
$enc = /CryptEncrypt|BCryptEncrypt|CryptDeriveKey/ ascii
condition:
any of ($mutex*) and any of ($enc*, $ext*)
or
any of ($ext*) and any of ($enc*)
}
// =============================================================================
// C8-4 Ryuk / Pseudo / Dharma 家族
// =============================================================================
rule C8_Ransomware_Ryuk_Pseudo {
meta:
risk_level = "high"
category = "C8"
false_positive_rate = "medium"
reference = "Ryuk / Pseudo / Dharma 勒索家族"
description = "Ryuk/Pseudo: RyukTask Mutex + 加密 API + .ryk/.pseudo 扩展名"
strings:
$mutex_ryuk = /RyukTask[\d]/ ascii
$mutex_pseudo = /Global\\[Pp]seudo/ ascii
$mutex_dharma = /Global\\[Dd]harma/ ascii
$ext_ryk = /\.ryk\b/ ascii nocase
$ext_pseudo = /\.pseudo\b/ ascii nocase
$ext_dharma = /\.dharma\b/ ascii nocase
$enc = /CryptEncrypt|CryptDeriveKey/ ascii
condition:
(any of ($mutex_ryuk, $mutex_pseudo, $mutex_dharma))
and (any of ($enc*, $ext_ryk, $ext_pseudo, $ext_dharma))
}
// =============================================================================
// C8-5 勒索信文件名模式(独立规则,辅助 family 识别)
// =============================================================================
rule C8_Ransomware_Note_Filename {
meta:
risk_level = "medium"
category = "C8"
false_positive_rate = "medium"
reference = "勒索信文件名通用模式"
description = "勒索信典型文件名变体(匹配后触发需要配合加密 API 才升级高危)"
strings:
$n1 = /HOW_TO_RECOVER[\w.-]*\.(txt|html|png|bmp|jpg|url|vbs|js)/ nocase
$n2 = /RESTORE_FILES[\w.-]*\.(txt|html|png|bmp|jpg|url|vbs|js)/ nocase
$n3 = /DECRYPT_INSTRUCTIONS[\w.-]*\.(txt|html|png|bmp|jpg|url)/ nocase
$n4 = /README[_\s-]*[\d]*[_\s-]*[\w]*\.(txt|html|png|bmp|jpg|url)/ nocase
$n5 = /HELP_DECRYPT[\w.-]*\.(txt|html|png|bmp|jpg|url)/ nocase
$n6 = /_readme[\w.-]*\.(txt|html|png|bmp|jpg|url)/ nocase
$n7 = /_restore[\w.-]*\.(txt|html|png|bmp|jpg|url)/ nocase
$bitcoin = /bitcoin address|BTC\b|monero address|XMR\b|send money|ransom|payment/ nocase
$wallet = /1[A-Za-z0-9]{25,34}|bc1[A-Za-z0-9]{11,71}|4[0-9A-Za-z]{32}/ nocase
$encapi = /CryptEncrypt|BCryptEncrypt|CryptDeriveKey/ ascii
condition:
// 勒索信文件名 + 加密 API = 明确勒索
any of ($n*) and $encapi
or
// 勒索信文件名 + 比特币/XMR 地址 = 大概率勒索
any of ($n*) and any of ($bitcoin, $wallet)
}
// =============================================================================
// C8-6 加密文件扩展名黑名单(不单独触发,配合加密 API)
// =============================================================================
rule C8_Ransomware_Extension_Blacklist {
meta:
risk_level = "low"
category = "C8"
false_positive_rate = "medium"
reference = "勒索加密文件扩展名模式"
description = "常见勒索加密扩展名(.locky/.zepto/.cryptolocker/.encrypted/.virus/.tor/.crpt 等)+ 加密 API"
strings:
$ext1 = /\.locky\b/ nocase
$ext2 = /\.zepto\b/ nocase
$ext3 = /\.cryptolocker\b/ nocase
$ext4 = /\.cryptor\b/ nocase
$ext5 = /\.crypt\b/ nocase
$ext6 = /\.encrypted\b/ nocase
$ext7 = /\.virus\b/ nocase
$ext8 = /\.tor\b/ nocase
$ext9 = /\.crpt\b/ nocase
$ext10 = /\.wallet\b/ nocase
$ext11 = /\.pay2[\w.-]*\.?\w*\b/ nocase
$enc = /CryptEncrypt|BCryptEncrypt|CryptDeriveKey/ ascii
$note = /HOW_TO_RECOVER|RESTORE_FILES|DECRYPT_INSTRUCTIONS|README/ nocase
condition:
// 扩展名 + 加密 API + 勒索信 = 完整勒索链
any of ($ext*) and $enc and $note
or
// 扩展名 + 加密 API(至少 2 种扩展名变体)
(2 of ($ext*)) and $enc
}
// =============================================================================
// C8-7 卷影删除专项(辅助勒索前置)
// =============================================================================
rule C8_Ransomware_VolumeShadow {
meta:
risk_level = "high"
category = "C8"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1490 Inhibit System Recovery"
description = "删除卷影副本:vssadmin / wmic shadowcopy + 加密 API"
strings:
$vss1 = "vssadmin delete shadows" ascii
$vss2 = /vssadmin\s+delete\s+shadows\s+\/all\b/ ascii
$wmic1 = /wmic\s+shadowcopy\s+delete/ ascii
$wmic2 = /wmic\s+shadowcopy\s+where\s+\d+/ ascii
$vss3 = /ShadowCopy|VolumeShadowCopy|vss\b/i ascii // "i" flag = nocase in YARA
$enc = /CryptEncrypt|BCryptEncrypt|CryptDeriveKey/ ascii
condition:
// 卷影删除 + 加密 API = 完整勒索前置
(any of ($vss1, $vss2, $wmic*, $vss3)) and any of ($enc*)
or
// 连续多次 vssadmin delete = 正在清卷影
any of ($vss1, $vss2) and any of ($wmic*)
}

345
rules/webshell.yar Normal file
View File

@@ -0,0 +1,345 @@
// =============================================================================
// 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)
}