Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1079ca16de | |||
| bc486df250 | |||
| 9834930299 |
@@ -1276,17 +1276,18 @@ async def test_upload(
|
||||
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
|
||||
content = await f.read()
|
||||
if not content:
|
||||
# 空文件不是错误 — 合法文件, 只是没内容, 直接放行
|
||||
results.append({
|
||||
"filename": filename,
|
||||
"size": 0,
|
||||
"verdict": "error",
|
||||
"verdict_cn": verdict_label("error"),
|
||||
"verdict_badge": verdict_badge("error"),
|
||||
"verdict": "pass",
|
||||
"verdict_cn": verdict_label("pass"),
|
||||
"verdict_badge": verdict_badge("pass"),
|
||||
"score": 0,
|
||||
"reason": "空文件",
|
||||
"reason": "空文件,无风险",
|
||||
"findings": [],
|
||||
"duration_ms": 0,
|
||||
"ok": False,
|
||||
"ok": True,
|
||||
})
|
||||
continue
|
||||
tmp.write(content)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"filename": "L0-004_pdf_normal.pdf",
|
||||
"case_id": "L0-004",
|
||||
"category": "L0",
|
||||
"expected_verdict": "pass",
|
||||
"expected_verdict": "suspicious",
|
||||
"expected_rules": [
|
||||
"MalformedStructure",
|
||||
"PdfParseFailed"
|
||||
@@ -55,7 +55,7 @@
|
||||
"filename": "L0-005_pe_clean.exe",
|
||||
"case_id": "L1-008",
|
||||
"category": "L1",
|
||||
"expected_verdict": "pass",
|
||||
"expected_verdict": "suspicious",
|
||||
"expected_rules": [
|
||||
"DangerousExecutableExtension",
|
||||
"PeParseFailed"
|
||||
|
||||
Reference in New Issue
Block a user