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:
@@ -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]:
|
||||
|
||||
Reference in New Issue
Block a user