Files
MeshSate/rules/linux.yar

331 lines
13 KiB
Plaintext
Raw Normal View History

// =============================================================================
// 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 = "low"
reference = "多种语言反弹 Shell 通用特征"
description = "通用反弹 Shell 标记:/dev/udp 或 攻击工具名 + 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 会命中 "dehydrated"、crack 会命中 "cracklib",必须带参数或成组出现
$hydra = /\bhydra\s+(-l|-P|-p|-s|-m|-t)\b/ ascii nocase
$tool = /\b(crackmapexec|weevely|meterpreter|msfconsole|msfvenom)\b/ ascii nocase
$reverseshell = /reverse[_\s]?shell|shell[_\s]?shock/ ascii nocase
$netart = /(nc|ncat)\s+\S+\s+\d{2,5}\s+-[ec]\b|\/dev\/(tcp|udp)\/|socat\s+EXEC:|bash\s+-i\s*>&/ ascii
condition:
any of ($devudp, $bashc, $dash_e)
or $hydra
or ($tool and $netart)
or ($reverseshell and $netart)
}
// =============================================================================
// 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 = "low"
reference = "MITRE ATT&CK T1543.002 Systemd Service"
description = "恶意 systemd unit:ExecStart 指向临时目录隐藏文件 / 管道执行 / 反弹命令"
strings:
$unit = /\[Unit\]/ ascii
$service = /\[Service\]/ ascii
$install = /\[Install\]/ ascii
$execstart = /ExecStart=/ ascii
$multiuser = /multi-user\.target/ ascii
// 隐藏文件(点开头)落在可写临时目录——正常 unit 只会在 /usr/bin、/opt 等路径
$hiddenpath = /\/(tmp|var\/tmp|dev\/shm)\/\.[a-zA-Z0-9_-]{2,}/ ascii
$pipe = /(curl|wget)\s+\S+\s*\|\s*(ba)?sh/ ascii
$revshell = /((nc|ncat|socat)\s+.*(-e|--exec|EXEC:)\s*\/bin\/(ba)?sh|\/dev\/tcp\/\d{1,3}\.\d{1,3})/ ascii
condition:
($unit and $service and $execstart and any of ($hiddenpath, $pipe, $revshell))
or
($install and $multiuser and $execstart and any of ($hiddenpath, $pipe, $revshell))
}
rule C7_Linux_Persistence_LD_PRELOAD {
meta:
risk_level = "high"
category = "C7"
false_positive_rate = "low"
reference = "MITRE ATT&CK T1574.006 LD_PRELOAD"
description = "LD_PRELOAD 劫持:写 ld.so.preload 或预加载临时目录里的 .so"
strings:
$ldpreload = /LD_PRELOAD=/ ascii
$exportenv = /export\s+LD_PRELOAD/ ascii
$ldso = /ld\.so\.preload/ ascii
$tmpso = /\/(tmp|var\/tmp|dev\/shm|proc\/\d+\/root)\/[a-zA-Z0-9_.\/-]*\.so(\.[0-9]+)?/ ascii
condition:
// /etc/ld.so.preload 是内核级后门常用落点,单独出现即算证据
$ldso
or
// LD_PRELOAD 指向可写临时目录的 so;README 里 LD_PRELOAD=libasan.so 不算
(any of ($ldpreload, $exportenv) and $tmpso)
}
// =============================================================================
// 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 = "low"
reference = "多语言反弹 Shell"
description = "Ruby/Lua 反弹 Shell:Socket 对象 + 紧邻的 shell 执行调用"
strings:
$ruby = "TCPSocket" ascii
$ruby2 = "Socket.tcp" ascii
$lua = "loadstring" ascii
$lua2 = "luasocket" ascii
$exec = /(\bexec|\bsystem|IO\.popen|\bpopen|os\.execute|os\.runtime)\s*\(?\s*['"]((\/bin\/)?(ba)?sh|nc\s+-e|\/dev\/tcp)[^'"]{0,48}/ ascii
condition:
// 只要出现 TCPSocket/loadstring 就命中 = 任何内嵌 Lua 的程序(Redis、nginx-lua、
// Wireshark 插件)必中。语言标记与 shell 执行必须挨在一起(256B 内)。
$exec and (
for any i in (1..#exec): (
any of ($ruby, $ruby2, $lua, $lua2) in (@exec[i] - 256..@exec[i] + 256)
)
)
}
// =============================================================================
// C7-5 网络投毒 / MITM 工具(内网横向移动)
// 工具名必须整词匹配,且与攻击参数成组出现
// =============================================================================
rule C7_Network_Tools_Malicious {
meta:
risk_level = "medium"
category = "C7"
false_positive_rate = "low"
reference = "内网攻击工具"
description = "内网攻击工具:ettercap/responder/nmap + 投毒参数成组出现"
strings:
$tool1 = /\bettercap\b/ ascii nocase
$tool2 = /\bresponder(\.py)?\b/ ascii nocase
$tool3 = /\bnmap\b/ ascii nocase
// 攻击参数 / 漏洞编号(这些才是意图证据)
$art1 = /--smb/ ascii
$art2 = /\bms17-010\b/ ascii nocase
$art3 = /\bSMBGhost\b/ ascii nocase
$art4 = /\bdns[-_]spoof\b|\bdns[-_]mitm\b/ ascii nocase
$art5 = /\barp[-_]poison\b|\barp[-_]spoof\b/ ascii nocase
$art6 = /--Mitm|-T\s+text|\bec_sleep\b|\bntlm_relay\b|\bRunFinger\.py\b/ ascii nocase
condition:
// 投毒手法名本身就是明确证据
any of ($art4, $art5)
or
// 工具名 + 攻击参数
($tool1 and any of ($art1, $art2, $art3, $art6))
or ($tool2 and any of ($art1, $art2, $art3, $art6))
or ($tool3 and any of ($art1, $art2, $art3))
}