diff --git a/app/engines/keywords.py b/app/engines/keywords.py index 0c0f34d..bfd8028 100644 --- a/app/engines/keywords.py +++ b/app/engines/keywords.py @@ -13,6 +13,7 @@ from __future__ import annotations import logging +import os import re from typing import Any, Dict, List @@ -24,6 +25,26 @@ logger = logging.getLogger(__name__) class KeywordEngine(Engine): """内网特征词表匹配引擎。""" + # ---- 跳过列表:二进制 / 压缩封装 / 媒体文件 ---- + # 这些文件有专门引擎处理(PDF/Office/Archive/PE 等), + # 它们的内容是压缩流或二进制格式,关键词 regex 在里面会大面积误报。 + # 短关键词 (nc/wce/curl/...) 在压缩流里等于伪随机字节必然碰撞。 + BINARY_SKIP_EXTS = frozenset({ + # PDF / Office + ".pdf", ".docx", ".docm", ".doc", ".xlsx", ".xlsm", ".xls", + ".pptx", ".pptm", ".ppt", ".ppsx", ".pps", ".potx", + # 压缩包 + ".rar", ".zip", ".7z", ".tar", ".gz", ".bz2", ".xz", ".tgz", + ".iso", ".img", ".dmg", + # 图片 + ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".tif", ".webp", + ".ico", ".svg", + # 视频 + ".mp4", ".avi", ".mkv", ".mov", ".flv", ".wmv", ".webm", + # 音频 + ".mp3", ".wav", ".flac", ".ogg", ".aac", ".wma", ".m4a", + }) + name = "keywords" layer = "L2B" version = "1.0" @@ -57,6 +78,14 @@ class KeywordEngine(Engine): findings: List[Finding] = [] + # ---- 跳过二进制/压缩封装文件 ---- + # 这些文件内容是压缩流或纯二进制,短关键词 regex 在里面必然误报 + ext = (target.declared_ext or "").lower() + if not ext and target.path: + ext = os.path.splitext(target.path)[1].lower() + if ext in self.BINARY_SKIP_EXTS: + return result + try: text = self._extract_text(target.path, target.declared_ext) except Exception: # noqa: BLE001 diff --git a/config/policy.yaml b/config/policy.yaml index 0d8fbeb..a0caf8f 100644 --- a/config/policy.yaml +++ b/config/policy.yaml @@ -357,7 +357,8 @@ keyword_rules: # ---- 反弹 Shell ---- - name: ReverseShellNetcat match: regex - pattern: "(\\bnc\\b|\\bncat\\b|\\bnetcat\\b|/dev/tcp/|bash\\s+-i\\s+>&|sh\\s+-i\\s+>&)" + # nc/ncat 后必须跟参数 (如 -e/-l/-p/-v/-s),单独 nc 在二进制里必然误报 + pattern: "(\\bnc\\s+-[elpvs]\\w*|\\bncat\\s+-\\w+|\\bnetcat\\b|/dev/tcp/|bash\\s+-i\\s+>&|sh\\s+-i\\s+>&)" ignore_case: true weight: 40 severity: critical @@ -372,7 +373,8 @@ keyword_rules: # ---- 凭据窃取工具 ---- - name: CredentialStealer match: regex - pattern: "(mimikatz|sekurlsa|wce|gsecdump|fgdump|lsadump|dcsync|dcsyncer|rubeus)" + # 全部加 \b 词边界, wce 要求后跟 .exe / 空格 / / (二进制随机字节里的 WCE 不会触发) + pattern: "(\\bmimikatz\\b|\\bsekurlsa\\b|\\bwce(\\.exe\\b|\\s|\\/)|\\bgsecdump\\b|\\bfgdump\\b|\\blsadump\\b|\\bdcsync\\b|\\bdcsyncer\\b|\\brubeus\\b)" ignore_case: true weight: 45 severity: critical