francesco-univr/malware-visual-analysis

GitHub: francesco-univr/malware-visual-analysis

该项目将恶意软件二进制转为灰度图像,利用 ResNet 和 ViT 进行家族分类,并使用 VAE 重构异常检测实现 Zero-Day 检测。

Stars: 0 | Forks: 0

# 恶意软件可视化分析 在 Malimg 数据集上的家族分类与 Zero-Day 检测 计算机视觉与深度学习 — 维罗纳大学,人工智能硕士。 作者:Francesco Simbola (VR545665) Nataraj 等人 (2011) 将恶意软件二进制文件读取为一维字节流,并将其重塑 为灰度图像。本项目在该想法的基础上构建了两个 pipeline,均在 Malimg 数据集上运行: - 任务 1 — 家族分类(闭集):将恶意软件图像分配到 25 个家族中的一个。 - 任务 2 — Zero-Day 检测(开集):使用基于重构的异常检测,标记训练期间从未见过的家族的样本。 ## 结果 ### 任务 1 — 家族分类(测试集,1,267 个样本) | 模型 | Accuracy | Macro F1 | F1 Autorun.K | F1 Yuner.A | |-------|----------|----------|--------------|------------| | ResNet-18 (scratch) | 97.63% | ~0.926 | 0.000 | 0.741 | | ResNet-18 (ImageNet-1K) | 98.50% | ~0.941 | 0.000 | 0.741 | | ViT-B/16 (SWAG) | 98.18% | 0.961 | 1.000 | 1.000 | 在总体准确率方面,这三个模型处于彼此的抽样误差范围内(精确的 McNemar 检验,预训练的 ResNet vs ViT:*p* = 0.62)。整个 macro-F1 的差距仅来自一对 样本:**Autorun.K / Yuner.A**:ResNet 变体无法区分它们,而 ViT 将其区分开来。结果 表明这对样本在像素级别上具有 100% 的训练/测试重叠(参见*已知局限性*),因此 ViT 在这里的分数反映的是对已见像素的记忆,而不是对未见像素的泛化能力。 ### 任务 2 — Zero-Day 检测(149 个 zero-day vs 1,118 个已知) | 模型 | AUROC | AUPRC | F1 (calibrated) | |-------|-------|-------|-----------------| | ConvAutoencoder (AE) | 0.648 | 0.253 | 0.097 | | ConvVAE | **0.732** | **0.502** | **0.550** | Monte Carlo 样本计数消融实验(N ∈ {1, 2, 5, 10},AUROC 波动为 0.0031)表明,VAE 相对于 AE 的提升 来自于变分公式,而不是 MC 平均。 每个家族的 AUROC 分为两种情况。VAE 能够清晰地区分 **Fakerean** (0.952) 和 **VB.AT** (0.928),但在 **Rbot!gen** (0.438)、**Yuner.A** (0.402) 和 **Autorun.K** (0.388) 上表现极差,全部低于 0.5 的随机基线。原因是表征 本身:它将这三个家族映射到了已知家族所占据的相同区域,因此没有任何 重构分数能将它们区分开来。 ## 项目结构 ``` . ├── configs/ │ └── config.yaml # Hyperparameters and paths ├── src/ │ ├── dataset.py # Dataloaders, transforms, weighted sampling │ ├── models/ │ │ ├── resnet_classifier.py # ResNet-18 head for 25 classes │ │ ├── vit_classifier.py # ViT-B/16 SWAG head │ │ ├── autoencoder.py # Convolutional AE + shared encoder/decoder │ │ └── vae.py # Convolutional VAE + ELBO loss │ ├── prepare_dataset.py # MD5 deduplication + stratified split │ ├── train_classifier.py # Task 1 training │ ├── train_vae.py # Task 2 training (AE / VAE) │ ├── evaluate_classifier.py # Task 1 evaluation + confusion matrices │ ├── evaluate_zeroday.py # Task 2 evaluation (AUROC, AUPRC, thresholds) │ ├── analyze_zeroday_per_family.py # Per-family AUROC decomposition │ ├── ablate_mc_samples.py # Monte Carlo sample-count ablation │ ├── significance_test.py # Exact McNemar test between classifiers │ ├── visualize.py # Grad-CAM, t-SNE, VAE reconstructions │ └── utils.py # Seeding, checkpointing, optimizer, early stopping ├── tests/ │ ├── smoke_test.py # Structural validation of all models │ ├── check_duplicates.py # Byte-level (MD5) duplicate analysis │ └── check_pixel_duplicates.py # Pixel-level leakage analysis ├── main.pdf # Full project report └── requirements.txt ``` ## 安装说明 需要 Python 3.10+ 以及支持 CUDA 的 GPU 来进行训练(CPU 可用于推理)。 ``` pip install -r requirements.txt ``` ## 数据集 由于体积(约 1.2 GB)和许可协议的限制,Malimg 数据集(Nataraj 等人,2011)未包含在此 仓库中。它可以在 Kaggle 上公开获取: 这个镜像文件已经整理成了 `train/`、`val/` 和 `test/` 子文件夹,这正是 `prepare_dataset.py` 期望的输入布局。下载后,请复现本工作中使用的精确的去重后的 70/15/15 划分: ``` python src/prepare_dataset.py --data_root --output_dir clean_dataset ``` 这会通过 MD5 对每个样本的原始 PNG 字节进行哈希处理,移除了 895 个完全相同的字节 重复项(9,339 → 8,444 个样本),并将全新的、无泄漏的分层划分写入 `clean_dataset/`(去重和重新划分是在合并原始文件夹*之后*运行的, 因此没有文件会出现在多个划分中)。五个 zero-day 家族(VB.AT、Fakerean、 Rbot!gen、Autorun.K、Yuner.A)被排除在 autoencoder 的训练集之外,并且配置在 `configs/config.yaml` 中。 ## 复现结果 训练会将 checkpoint 写入 `checkpoints/`,并将图表/指标写入 `outputs/`。 ### 任务 1 — 分类器 ``` python src/train_classifier.py --model resnet18 # from scratch python src/train_classifier.py --model resnet18 --pretrained # ImageNet-1K python src/train_classifier.py --model vit --pretrained # ViT-B/16 SWAG (384x384) python src/evaluate_classifier.py --model resnet18 --checkpoint checkpoints/resnet18_best.pth python src/evaluate_classifier.py --model resnet18 --pretrained --checkpoint checkpoints/resnet18_pretrained_best.pth python src/evaluate_classifier.py --model vit --pretrained --checkpoint checkpoints/vit_pretrained_best.pth --image_size 384 ``` ### 任务 2 — autoencoder ``` python src/train_vae.py --model ae python src/train_vae.py --model vae python src/evaluate_zeroday.py --model ae --checkpoint checkpoints/ae_latent128_best.pth python src/evaluate_zeroday.py --model vae --checkpoint checkpoints/vae_latent128_beta1.0_best.pth python src/analyze_zeroday_per_family.py --model vae --checkpoint checkpoints/vae_latent128_beta1.0_best.pth ``` ### 分析与图表 ``` python src/ablate_mc_samples.py # Monte Carlo ablation python src/significance_test.py # McNemar ResNet vs ViT python src/visualize.py --task gradcam --model resnet18 --checkpoint checkpoints/resnet18_pretrained_best.pth python src/visualize.py --task tsne --model vit --checkpoint checkpoints/vit_pretrained_best.pth --image_size 384 python src/visualize.py --task reconstructions --vae_model vae --vae_checkpoint checkpoints/vae_latent128_beta1.0_best.pth ``` ### 快速验证(无需训练,无需 checkpoint;需要 `clean_dataset/`) ``` python tests/smoke_test.py # builds every model, checks shapes and losses python tests/check_pixel_duplicates.py # reproduces the 425 / 47 / 71 leakage figures ``` ## 关键设计选择 - **类别不平衡**(高达 37:1)由 `WeightedRandomSampler` 处理,而不是通过 加权损失,从而避免了双重补偿。 - **不使用几何增强**:翻转会反转字节顺序,而旋转会破坏 定义每个家族视觉特征的内存线性结构。 - **AE/VAE pipeline 不使用 padding**:常量 padding 像素很容易被 重构,从而稀释异常分数。 - **AdamW**,权重衰减仅应用于 conv/linear 权重(bias 和 norm 参数 不进行衰减)。 - **VAE β-warmup**:β 在前 10 个 epoch 中从 0 逐渐增加到 1,以防止后验坍缩。 - **Monte Carlo 异常分数**(N = 10),遵循 An & Cho (2015)。 所有随机种子(Python、NumPy、PyTorch、CUDA)均固定为 42。 ## 已知局限性 MD5 去重在文件字节级别进行,而不是像素级别。事后 像素级别分析(`tests/check_pixel_duplicates.py`)发现了 425 个像素重复副本 以及 71 个测试样本(5.6%)在训练集中存在像素级孪生样本,这些集中在四个 家族上(Autorun.K 和 Yuner.A 为 100%,Fakerean 为 97%,Adialer.C 为 57%)。因此,任务 1 中关于 Autorun.K/Yuner.A 这一对样本的核心结果应被解读为对 近乎退化的碰撞的鲁棒性,而不是对未见样本的泛化能力。自然的下一步工作应当是进行像素级别的重新去重,随后进行重新训练。 ## 参考文献 - L. Nataraj 等人,*Malware Images: Visualization and Automatic Classification*,VizSec,2011。 - D. P. Kingma, M. Welling,*Auto-Encoding Variational Bayes*,ICLR,2014。 - J. An, S. Cho,*Variational Autoencoder based Anomaly Detection using Reconstruction Probability*,2015。 - A. Dosovitskiy 等人,*An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale*,ICLR,2021。 - M. Singh 等人,*Revisiting Weakly Supervised Pre-Training of Visual Perception Models* (SWAG),CVPR,2022。 完整的讨论和方法论请见 [`main.pdf`](main.pdf)。
标签:DAST, ResNet, Vectored Exception Handling, ViT, 凭据扫描, 图像分类, 异常检测, 恶意软件分析, 深度学习, 计算机视觉, 逆向工具