基于机器学习和深度学习的恶意WebURL检测系统实战详解

#源码获取:https://mbd.pub/o/bread/YZWclppsag==

一、项目概述与背景

1.1 网络安全现状分析

在当今数字化时代,互联网已经深入到人们生活的方方面面。然而,随着网络技术的飞速发展,网络安全威胁也日益严峻。恶意URL(Uniform Resource Locator)作为网络攻击的主要载体之一,被广泛用于传播恶意软件、实施钓鱼攻击、进行SQL注入和跨站脚本攻击(XSS)等。据统计,全球每天新增数百万个恶意URL,传统的基于黑名单的防护方式已经难以应对这种快速变化的威胁态势。

恶意URL的危害主要体现在以下几个方面:

  1. 钓鱼攻击:攻击者通过伪造与合法网站极为相似的URL,诱导用户输入敏感信息,如账号密码、银行卡信息等。

  2. 恶意软件传播:恶意URL常常指向包含病毒、木马、勒索软件等恶意程序的文件下载地址。

  3. Web应用攻击:包括SQL注入、XSS攻击、CSRF攻击等,通过构造特殊的URL参数来攻击Web应用程序。

  4. 重定向攻击:将用户重定向到恶意网站,实施进一步的攻击行为。

1.2 传统检测方法的局限性

传统的恶意URL检测方法主要包括:

  • 黑名单机制:维护一个已知的恶意URL列表,对访问的URL进行匹配。这种方法的缺点是滞后性强,无法检测新出现的恶意URL。

  • 基于规则的检测:通过预定义的规则(如正则表达式)来识别恶意URL模式。这种方法容易被攻击者通过编码、混淆等技术绕过。

  • 启发式分析:基于URL的特征(如域名年龄、URL长度、特殊字符数量等)进行判断。这种方法准确率有限,容易产生误报。

1.3 机器学习和深度学习的优势

与传统方法相比,基于机器学习和深度学习的恶意URL检测具有以下优势:

  1. 自学习能力:能够从大量样本中自动学习恶意URL的特征,无需人工编写复杂的规则。

  2. 泛化能力强:对于未见过的新型恶意URL具有良好的检测能力。

  3. 特征提取自动化:深度学习模型可以自动从原始URL中提取高层次的抽象特征。

  4. 持续优化:可以通过不断添加新样本进行模型更新,适应威胁的演变。

1.4 项目目标

本项目旨在构建一个完整的恶意URL检测系统,实现以下目标:

  1. 实现多种机器学习算法(逻辑回归、XGBoost)和深度学习模型(全连接网络、VGG风格网络、残差网络)的恶意URL检测。

  2. 对比分析不同算法的性能表现,选择最优方案。

  3. 基于Flask框架构建Web服务,提供实时的URL检测API接口。

  4. 开发友好的Web界面,方便用户进行URL检测和模型训练管理。


二、技术架构与核心算法

2.1 整体架构设计

本项目的整体技术架构如下图所示:

┌─────────────────────────────────────────────────────────────────┐
│                        应用层 (Web Interface)                    │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │  URL检测界面  │  │ 训练管理界面  │  │ 结果展示界面  │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      服务层 (Flask API)                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ /predict     │  │ /training/*  │  │ / (首页)     │          │
│  │ URL预测接口   │  │ 训练管理接口  │  │ Web界面      │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      模型层 (Model Layer)                        │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐          │
│  │    LR    │ │  XGBoost │ │   FCNet  │ │VGG+ResNet│          │
│  │ 逻辑回归  │ │梯度提升树│ │ 全连接网络│ │残差网络  │          │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    特征工程层 (Feature Engineering)              │
│              TF-IDF + N-grams (3-gram特征提取)                  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      数据层 (Data Layer)                         │
│           正常URL数据集 (goodqueries.txt)                        │
│           恶意URL数据集 (badqueries.txt)                         │
└─────────────────────────────────────────────────────────────────┘

2.2 特征工程:TF-IDF与N-grams

2.2.1 N-grams原理

N-grams是一种常用的文本特征提取方法,它将文本分割成连续的N个字符的序列。在本项目中,我们使用3-grams(tri-grams)来提取URL的特征。

例如,对于URL www.foo.com/1,其3-grams特征为:

['www', 'ww.', 'w.f', '.fo', 'foo', 'oo.', 'o.c', '.co', 'com', 'om/', 'm/1']

N-grams的优势在于:

  • 能够捕捉URL中的局部模式和结构信息
  • 对URL编码和微小变化具有一定的鲁棒性
  • 无需复杂的分词处理,实现简单高效

核心代码实现:

def get_ngrams(query):
    """
    将URL转换为3-grams特征
    例如: www.foo.com/1 转换为 ['www','ww.','w.f','.fo','foo',...]
    """
    tempQuery = str(query)
    ngrams = []
    for i in range(0, len(tempQuery) - 3):
        ngrams.append(tempQuery[i:i + 3])
    return ngrams
2.2.2 TF-IDF向量化

TF-IDF(Term Frequency-Inverse Document Frequency)是一种常用的文本特征权重计算方法,它综合考虑了词频(TF)和逆文档频率(IDF)。

  • TF(词频):表示某个N-gram在当前URL中出现的频率
  • IDF(逆文档频率):表示某个N-gram在整个数据集中的重要程度,出现越少的N-gram权重越高

使用scikit-learn的TfidfVectorizer进行特征提取:

from sklearn.feature_extraction.text import TfidfVectorizer

# 定义矢量化器
vectorizer = TfidfVectorizer(tokenizer=get_ngrams, max_features=800)

# 将URL列表转换为TF-IDF特征矩阵
X = vectorizer.fit_transform(queries)

2.3 机器学习算法

2.3.1 逻辑回归(Logistic Regression)

逻辑回归是一种经典的二分类算法,虽然名为"回归",但实际上是一种分类方法。它通过Sigmoid函数将线性回归的输出映射到(0,1)区间,表示样本属于正类的概率。

算法原理

P(y=1|x) = 1 / (1 + exp(-(w^T * x + b)))

其中:

  • w 是权重向量
  • b 是偏置项
  • x 是输入特征(TF-IDF向量)

实现代码

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

# 数据分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=20, random_state=42
)

# 定义逻辑回归模型
LR = LogisticRegression()

# 训练模型
LR.fit(X_train, y_train)

# 评估模型
print('模型的准确度:{}'.format(LR.score(X_test, y_test)))

# 预测新样本
X_predict = vectorizer.transform(new_queries)
res = LR.predict(X_predict)

优缺点分析

  • 优点:训练速度快,可解释性强,不容易过拟合
  • 缺点:对于复杂的非线性关系拟合能力有限
2.3.2 XGBoost(eXtreme Gradient Boosting)

XGBoost是一种基于梯度提升决策树(Gradient Boosting Decision Tree, GBDT)的集成学习算法,在各类数据竞赛中表现优异。

核心思想
XGBoost通过串行训练多棵决策树,每棵树学习前面所有树的残差(预测误差),最终将多棵树的预测结果相加得到最终预测。

算法特点

  1. 正则化:在目标函数中加入L1和L2正则化项,防止过拟合
  2. 二阶泰勒展开:使用损失函数的一阶和二阶导数,收敛更快
  3. 列采样:借鉴随机森林的思想,对特征进行采样
  4. 缺失值处理:自动学习缺失值的分裂方向

实现代码

import xgboost as xgb

# 定义XGBoost分类器
XGB = xgb.XGBClassifier()

# 训练模型
XGB.fit(X_train, y_train)

# 评估模型
print('模型的准确度:{}'.format(XGB.score(X_test, y_test)))

# 预测新样本
X_predict = vectorizer.transform(new_queries)
res = XGB.predict(X_predict)

超参数说明

  • n_estimators:树的数量
  • max_depth:树的最大深度
  • learning_rate:学习率
  • subsample:样本采样比例
  • colsample_bytree:特征采样比例

2.4 深度学习模型

2.4.1 全连接神经网络(FCNet)

全连接神经网络(Fully Connected Neural Network)是最基础的深度学习模型,每一层的神经元与下一层的所有神经元相连。

网络结构

输入层 (input_size) 
    ↓
全连接层1 (128个神经元) + ReLU激活
    ↓
全连接层2 (256个神经元) + ReLU激活
    ↓
全连接层3 (512个神经元) + ReLU激活
    ↓
输出层 (1个神经元) + Sigmoid激活

PyTorch实现

import torch
import torch.nn as nn

class Net(nn.Module):
    def __init__(self, input_size, output_size):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_size, 128)
        self.fc2 = nn.Linear(128, 256)
        self.fc3 = nn.Linear(256, 512)
        self.fc = nn.Linear(512, output_size)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = torch.relu(self.fc3(x))
        x = self.fc(x)
        return x

训练流程

# 定义损失函数和优化器
criterion = nn.BCEWithLogitsLoss()  # 二分类交叉熵损失
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 训练循环
for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels.unsqueeze(1))
        loss.backward()
        optimizer.step()
        running_loss += loss.item() * inputs.size(0)
    
    epoch_loss = running_loss / len(train_loader.dataset)
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}')
2.4.2 VGG风格全连接网络

VGG(Visual Geometry Group)网络是2014年ImageNet竞赛的亚军模型,其核心思想是使用多个小卷积核(3×3)堆叠代替大卷积核,增加网络深度。

在本项目中,我们将VGG的思想应用到全连接网络中,设计了VGGF(VGG-style Fully connected)网络:

网络结构

class VGGF(nn.Module):
    def __init__(self, input_size, output_size):
        super(VGGF, self).__init__()
        self.conv1 = nn.Linear(input_size, 256)
        self.bn1 = nn.BatchNorm1d(256)
        self.conv2 = nn.Linear(256, 512)
        self.conv3 = nn.Linear(512, 512)
        self.bn3 = nn.BatchNorm1d(512)
        self.fc1 = nn.Linear(512, 512)
        self.fc2 = nn.Linear(512, output_size)

    def forward(self, x):
        out = F.relu(self.conv1(x))
        out = self.bn1(out)
        out = F.relu(self.conv2(out))
        out = F.relu(self.conv3(out))
        out = self.bn3(out)
        out = F.relu(self.fc1(out))
        out = self.fc2(out)
        return out

关键技术点

  1. 批归一化(Batch Normalization):加速训练收敛,提高模型稳定性
  2. 深度堆叠:通过多个全连接层增加网络表达能力
  3. ReLU激活函数:缓解梯度消失问题,加速训练
2.4.3 残差网络(ResNet)

残差网络(Residual Network)是2015年ImageNet竞赛的冠军模型,其核心贡献是引入了残差学习(Residual Learning)机制,有效解决了深层网络的梯度消失问题。

残差学习原理
传统的神经网络学习的是输入到输出的直接映射 H(x),而残差网络学习的是残差映射 F(x) = H(x) - x,最终输出为 F(x) + x

残差块结构

输入 x
    ↓
┌─────────────────────────────────────┐
│  全连接层1 → 批归一化 → ReLU激活    │
│              ↓                      │
│  Dropout(0.3)                       │
│              ↓                      │
│  全连接层2 → 批归一化               │
│              ↓                      │
│  + 残差连接 (x)                     │
│              ↓                      │
│  ReLU激活                           │
└─────────────────────────────────────┘
    ↓
输出

实现代码

class ResidualBlockF(nn.Module):
    """全连接残差块"""
    def __init__(self, in_channels, out_channels):
        super(ResidualBlockF, self).__init__()
        self.fc1 = nn.Linear(in_channels, out_channels)
        self.fc2 = nn.Linear(out_channels, out_channels)
        self.bn = nn.BatchNorm1d(out_channels)
        self.dropout = nn.Dropout(0.3)

    def forward(self, x):
        residual = x  # 保存输入作为残差
        out = torch.relu(self.bn(self.fc1(x)))
        out = self.dropout(out)
        out = self.bn(self.fc2(out))
        out += residual  # 残差连接
        out = torch.relu(out)
        return out

class VGGFWithResidualF(nn.Module):
    """VGG风格 + 残差连接网络"""
    def __init__(self, input_size, output_size):
        super(VGGFWithResidualF, self).__init__()
        self.cfc1 = nn.Linear(input_size, 64)
        self.bn0 = nn.BatchNorm1d(64)
        self.residual1 = ResidualBlockF(64, 64)
        self.cfc2 = nn.Linear(64, 128)
        self.residual2 = ResidualBlockF(128, 128)
        self.fc0 = nn.Linear(128, 128)
        self.bn1 = nn.BatchNorm1d(128)
        self.fc1 = nn.Linear(128, 128)
        self.fc2 = nn.Linear(128, output_size)

    def forward(self, x):
        out = F.relu(self.cfc1(x))
        out = self.bn0(out)
        out = self.residual1(out)
        out = F.relu(self.cfc2(out))
        out = self.residual2(out)
        out = F.relu(self.fc0(out))
        out = self.bn1(out)
        out = F.relu(self.fc1(out))
        out = self.fc2(out)
        return out

残差网络的优势

  1. 解决梯度消失:通过跳跃连接,梯度可以直接反向传播到浅层
  2. 训练更深网络:可以训练上百层甚至上千层的网络
  3. 恒等映射:如果某层无用,可以通过残差连接学习恒等映射
2.4.4 改进版VGG+残差网络

在实际部署中,我们进一步优化了网络结构,设计了改进版模型:

class ImprovedVGGFWithResidualF(nn.Module):
    """改进版VGG+残差网络"""
    def __init__(self, input_size, output_size):
        super(ImprovedVGGFWithResidualF, self).__init__()
        self.cfc1 = nn.Linear(input_size, 128)
        self.bn0 = nn.BatchNorm1d(128)
        self.residual1 = ResidualBlockF(128, 128)
        self.cfc2 = nn.Linear(128, 256)
        self.residual2 = ResidualBlockF(256, 256)
        self.fc0 = nn.Linear(256, 128)
        self.bn1 = nn.BatchNorm1d(128)
        self.fc1 = nn.Linear(128, 64)
        self.fc2 = nn.Linear(64, output_size)
        self.dropout = nn.Dropout(0.5)

    def forward(self, x):
        out = torch.relu(self.cfc1(x))
        out = self.bn0(out)
        out = self.dropout(out)
        out = self.residual1(out)
        out = torch.relu(self.cfc2(out))
        out = self.residual2(out)
        out = torch.relu(self.fc0(out))
        out = self.bn1(out)
        out = torch.relu(self.fc1(out))
        out = self.fc2(out)
        return out

改进点

  1. 增加了Dropout层(0.5),防止过拟合
  2. 调整了网络宽度,从64→128→256→128→64的渐进结构
  3. 使用更激进的批归一化策略

三、数据集与预处理

3.1 数据集介绍

本项目使用了两类URL数据集:

  1. 正常URL数据集(goodqueries.txt):包含正常的Web请求URL
  2. 恶意URL数据集(badqueries.txt):包含各类恶意Web请求URL

数据集格式为纯文本文件,每行一个URL。

3.2 数据加载与预处理

import os
import urllib

def get_query_list(filename, max_samples=None):
    """
    从文件中加载URL列表
    
    Args:
        filename: 数据文件路径
        max_samples: 最大采样数量(用于限制训练数据规模)
    
    Returns:
        去重后的URL列表
    """
    directory = str(os.getcwd())
    filepath = os.path.join(directory, filename)
    
    with open(filepath, 'r', encoding='UTF-8') as f:
        data = f.readlines()
    
    query_list = []
    for d in data[:max_samples] if max_samples else data:
        # URL解码:将URL编码的数据转换为普通字符串
        d = str(urllib.parse.unquote(d))
        query_list.append(d)
    
    # 去重处理
    return list(set(query_list))

3.3 数据平衡处理

在实际场景中,正常URL通常远多于恶意URL,这会导致数据不平衡问题。我们采用以下策略:

# 平衡数据集 - 使用较少类别的数量
min_samples = min(len(good_query_list), len(bad_query_list))
balanced_good = good_query_list[:min_samples]
balanced_bad = bad_query_list[:min_samples]

# 标记数据:0表示正常,1表示恶意
good_y = [0 for _ in range(len(balanced_good))]
bad_y = [1 for _ in range(len(balanced_bad))]

# 合并数据
queries = balanced_good + balanced_bad
y = good_y + bad_y

3.4 加权采样

在深度学习中,我们使用PyTorch的WeightedRandomSampler来处理数据不平衡:

from torch.utils.data import WeightedRandomSampler

# 计算类别权重
class_counts = torch.bincount(y_train.long())
class_weights = 1. / class_counts
sample_weights = class_weights[y_train.long()]

# 创建加权采样器
sampler = WeightedRandomSampler(
    weights=sample_weights,
    num_samples=len(sample_weights),
    replacement=True
)

# 在DataLoader中使用采样器
train_loader = DataLoader(train_dataset, batch_size=64, sampler=sampler)

四、模型训练与优化

4.1 训练流程

完整的训练流程包括以下步骤:

def train_model():
    # 1. 数据准备
    good_query_list = get_query_list('dataset/goodqueries.txt', 20000)
    bad_query_list = get_query_list('dataset/badqueries.txt', 20000)
    
    # 2. 特征提取
    vectorizer = TfidfVectorizer(tokenizer=get_ngrams, max_features=800)
    X = vectorizer.fit_transform(queries)
    
    # 3. 数据分割
    X_train, X_test, y_train, y_test = train_test_split(
        X_tensor, y_tensor, test_size=0.2, random_state=42, stratify=y
    )
    
    # 4. 模型定义
    model = ImprovedVGGFWithResidualF(input_size, output_size)
    
    # 5. 损失函数和优化器
    pos_weight = torch.tensor([len(good_y) / len(bad_y)])
    criterion = nn.BCEWithLogitsLoss(pos_weight=pos_weight)
    optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)
    scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.5)
    
    # 6. 训练循环
    for epoch in range(num_epochs):
        model.train()
        for batch_idx, (data, target) in enumerate(train_loader):
            optimizer.zero_grad()
            output = model(data).squeeze()
            loss = criterion(output, target)
            loss.backward()
            optimizer.step()
        
        # 学习率调整
        scheduler.step()
        
        # 验证
        model.eval()
        # ... 验证代码 ...
    
    # 7. 保存模型
    torch.save(model.state_dict(), 'medium_model.pth')

4.2 超参数设置

超参数 设置值 说明
max_features 800 TF-IDF最大特征数
batch_size 64 训练批次大小
learning_rate 0.001 初始学习率
num_epochs 30 训练轮数
weight_decay 1e-4 L2正则化系数
dropout 0.5 Dropout比率

4.3 学习率调度

使用StepLR学习率调度器,每10个epoch将学习率减半:

scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.5)

这种策略可以在训练初期使用较大的学习率快速收敛,后期使用较小的学习率精细调整。

4.4 模型评估

我们使用多种指标来评估模型性能:

from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score

# 模型评估
model.eval()
all_predictions = []
all_targets = []
all_probabilities = []

with torch.no_grad():
    for data, target in test_loader:
        output = model(data).squeeze()
        probabilities = torch.sigmoid(output)
        predictions = (probabilities > 0.5).float()
        
        all_predictions.extend(predictions.cpu().numpy())
        all_targets.extend(target.cpu().numpy())
        all_probabilities.extend(probabilities.cpu().numpy())

# 分类报告
print(classification_report(all_targets, all_predictions, 
                           target_names=['正常请求', '恶意请求']))

# AUC分数
auc_score = roc_auc_score(all_targets, all_probabilities)
print(f"AUC Score: {auc_score:.4f}")

4.5 混淆矩阵可视化

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix

# 计算混淆矩阵
cm = confusion_matrix(all_targets, all_predictions)

# 绘制热力图
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', 
            xticklabels=['正常请求', '恶意请求'], 
            yticklabels=['正常请求', '恶意请求'])
plt.title('混淆矩阵')
plt.ylabel('真实标签')
plt.xlabel('预测标签')
plt.savefig('confusion_matrix.png')
plt.show()

五、Web服务部署

5.1 Flask框架简介

Flask是一个轻量级的Python Web框架,具有简单易用、扩展性强的特点。我们选择Flask来构建恶意URL检测的Web服务。

5.2 API接口设计

接口路径 方法 功能描述
/ GET 返回Web界面
/predict GET/POST URL预测接口
/training/start POST 开始模型训练
/training/stop POST 停止模型训练
/training/status GET 获取训练状态

5.3 核心API实现

5.3.1 URL预测接口
from flask import Flask, request, jsonify, render_template
import torch
import pickle

app = Flask(__name__)

# 加载预训练模型和矢量化器
model = ImprovedVGGFWithResidualF(input_size=800, output_size=1)
model.load_state_dict(torch.load('medium_model.pth'))
model.eval()

with open('medium_vectorizer.pkl', 'rb') as f:
    vectorizer = pickle.load(f)

@app.route('/predict', methods=['GET', 'POST'])
def predict():
    """URL预测接口"""
    # 解析请求参数
    if request.method == 'POST':
        data = request.get_json(force=True)
        queries = data['queries']
    else:
        queries = request.args.get('queries', '').split(',')
    
    if not queries:
        return jsonify({'error': 'No queries provided'}), 400
    
    # 特征提取
    new_X = vectorizer.transform(queries).toarray()
    new_X_tensor = torch.tensor(new_X, dtype=torch.float32)
    
    # 模型预测
    with torch.no_grad():
        outputs = model(new_X_tensor)
        probabilities = torch.sigmoid(outputs).squeeze().cpu().numpy()
        predictions = (probabilities > 0.5).astype(int)
    
    # 返回结果
    results = [
        {'url': q, 'res': '正常请求' if pred == 0 else '恶意请求'} 
        for q, pred in zip(queries, predictions)
    ]
    return jsonify(results)
5.3.2 训练状态管理
import threading
from datetime import datetime

# 训练状态全局变量
training_status = {
    'is_training': False,
    'progress': 0,
    'current_epoch': 0,
    'total_epochs': 0,
    'training_loss': 0.0,
    'validation_loss': 0.0,
    'training_accuracy': 0.0,
    'validation_accuracy': 0.0,
    'start_time': None,
    'end_time': None,
    'message': '未开始训练'
}

@app.route('/training/start', methods=['POST'])
def start_training():
    """开始训练"""
    if training_status['is_training']:
        return jsonify({'error': '训练正在进行中'}), 400
    
    # 重置训练状态
    training_status.update({
        'is_training': True,
        'progress': 0,
        'current_epoch': 0,
        'total_epochs': 30,
        'start_time': datetime.now().isoformat(),
        'message': '训练开始'
    })
    
    # 在后台线程中运行训练
    training_thread = threading.Thread(target=train_model)
    training_thread.daemon = True
    training_thread.start()
    
    return jsonify({'message': '训练已开始'})

@app.route('/training/status', methods=['GET'])
def get_training_status():
    """获取训练状态"""
    return jsonify(training_status)

@app.route('/training/stop', methods=['POST'])
def stop_training():
    """停止训练"""
    training_status['is_training'] = False
    training_status['message'] = '训练已停止'
    return jsonify({'message': '训练已停止'})

5.4 Web界面开发

我们开发了一个美观实用的Web界面,包含以下功能:

  1. URL检测功能:用户可以输入多个URL进行检测,系统实时返回检测结果
  2. 模型训练管理:支持在线重新训练模型,实时显示训练进度和指标
  3. 可视化展示:使用进度条、指标卡片等组件直观展示训练状态

界面预览:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>恶意URL检测系统</title>
    <style>
        /* 样式代码 */
        .safe { background-color: #dff0d8; color: #3c763d; }
        .malicious { background-color: #f2dede; color: #a94442; }
        .progress-bar { /* 进度条样式 */ }
    </style>
</head>
<body>
    <h1>恶意URL检测系统</h1>
    
    <!-- 模型训练管理 -->
    <div class="section">
        <div class="section-title">模型训练管理</div>
        <button id="train-btn">开始训练模型</button>
        <button id="stop-btn" disabled>停止训练</button>
        <div class="training-status" id="training-status">
            <!-- 训练状态显示 -->
        </div>
    </div>
    
    <!-- URL检测 -->
    <div class="section">
        <div class="section-title">URL安全检测</div>
        <textarea id="urls" placeholder="请输入要检测的URL"></textarea>
        <button id="detect-btn">检测URL</button>
        <div class="results" id="results"></div>
    </div>
    
    <script>
        // JavaScript交互逻辑
    </script>
</body>
</html>

5.5 服务启动

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

启动后,可以通过以下方式访问:

  • Web界面:http://localhost:5000/
  • API接口:http://localhost:5000/predict?queries=url1,url2

六、模型导出与部署

6.1 ONNX格式导出

ONNX(Open Neural Network Exchange)是一种开放的神经网络交换格式,可以实现不同深度学习框架之间的模型互操作。

# 导出为ONNX格式
dummy_input = torch.randn(batch_size, input_size)
torch.onnx.export(
    model, 
    dummy_input, 
    'model.onnx',
    input_names=['input'],
    output_names=['output'],
    dynamic_axes={'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}}
)

6.2 模型序列化

使用PyTorch的save和load功能保存和加载模型:

# 保存模型
torch.save(model.state_dict(), 'model.pth')

# 加载模型
model = ImprovedVGGFWithResidualF(input_size, output_size)
model.load_state_dict(torch.load('model.pth'))
model.eval()

6.3 矢量化器保存

使用pickle保存TF-IDF矢量化器:

import pickle

# 保存矢量化器
with open('vectorizer.pkl', 'wb') as f:
    pickle.dump(vectorizer, f)

# 加载矢量化器
with open('vectorizer.pkl', 'rb') as f:
    vectorizer = pickle.load(f)

七、实验结果与分析

7.1 各模型性能对比

模型 准确率 AUC 训练时间 模型大小
逻辑回归 (LR) ~92% ~0.95
XGBoost ~95% ~0.98 中等 中等
全连接网络 (FCNet) ~94% ~0.97 中等 中等
VGGF ~96% ~0.99 较慢 较大
VGGF+ResNet (改进版) 97% 0.9932 较慢 较大

7.2 混淆矩阵分析

改进版VGG+残差网络的混淆矩阵:

预测正常 预测恶意
实际正常 3850 150
实际恶意 120 3880

从混淆矩阵可以看出:

  • 真正例(TP):3880
  • 假正例(FP):150
  • 真负例(TN):3850
  • 假负例(FN):120

7.3 性能指标计算

精确率 (Precision) = TP / (TP + FP) = 3880 / (3880 + 150) = 96.28%
召回率 (Recall) = TP / (TP + FN) = 3880 / (3880 + 120) = 97.00%
F1分数 = 2 * (Precision * Recall) / (Precision + Recall) = 96.64%

7.4 训练曲线分析

训练过程中记录的损失和准确率曲线可以帮助我们分析模型的学习情况:

  1. 损失曲线:训练损失和验证损失都呈下降趋势,且两者差距不大,说明模型没有过拟合
  2. 准确率曲线:训练准确率和验证准确率都呈上升趋势,最终趋于稳定

7.5 实际检测案例

以下是一些实际检测案例:

URL 检测结果 攻击类型
www.foo.com/id=1<script>alert(1)</script> 恶意请求 XSS攻击
www.foo.com/name=admin' or 1=1 恶意请求 SQL注入
abc.com/admin.php 正常请求 -
q=../etc/passwd 恶意请求 路径遍历
/stylesheet.php?version=1331749579 正常请求 -

八、项目优化与改进

8.1 数据增强策略

  1. URL编码变体:对恶意URL进行URL编码、双重编码等变换,扩充训练数据
  2. 字符替换:使用相似字符替换(如0替换O,1替换l)生成变体
  3. 参数扰动:对URL参数进行随机增删改

8.2 模型优化方向

  1. 注意力机制:引入Self-Attention机制,让模型关注URL中的关键部分
  2. 字符级CNN:使用字符级卷积神经网络直接处理原始URL字符串
  3. 预训练语言模型:使用BERT等预训练模型进行URL语义理解
  4. 集成学习:结合多个模型的预测结果,提高整体性能

8.3 系统架构优化

  1. 异步处理:使用Celery等任务队列处理耗时的训练任务
  2. 模型缓存:使用Redis等缓存热点预测结果
  3. 负载均衡:部署多个预测服务实例,提高并发处理能力
  4. 模型热更新:支持不停机更新模型

8.4 安全加固

  1. 输入验证:对输入URL进行格式验证和长度限制
  2. 速率限制:防止API被恶意调用
  3. 日志审计:记录所有预测请求,便于事后分析
  4. HTTPS加密:使用HTTPS协议保护数据传输安全

九、完整代码实现

9.1 项目结构

Identifying-Malicious-WebURLs-Based-on-Machine-Learning-and-Deep-Learning/
├── dataset/
│   ├── goodqueries.txt          # 正常URL数据集
│   ├── badqueries.txt           # 恶意URL数据集
│   └── readme                   # 数据集说明
├── templates/
│   └── index.html               # Web界面模板
├── venv/                        # Python虚拟环境
├── Weburl_test_app.py           # Flask Web服务主程序
├── LRforWeb.py                  # 逻辑回归实现
├── XboostforWeb.py              # XGBoost实现
├── DeeplearingforWeb.py         # 基础深度学习实现
├── Deeplearing_FCnet_Web.py     # 全连接网络实现
├── Deeplearing_VGGFnet_Web.py   # VGG网络实现
├── Deeplearing_VGGFWithResidualFnet_Web.py  # VGG+残差网络实现
├── medium_training.py           # 中等规模训练脚本
├── README.md                    # 项目说明
└── *.png, *.pth, *.pkl, *.onnx  # 模型文件和可视化结果

9.2 环境依赖

Python >= 3.8
PyTorch >= 1.9.0
scikit-learn >= 0.24.0
xgboost >= 1.4.0
Flask >= 2.0.0
numpy >= 1.19.0
matplotlib >= 3.3.0
seaborn >= 0.11.0

安装命令:

pip install torch torchvision scikit-learn xgboost flask numpy matplotlib seaborn

9.3 快速开始

  1. 克隆项目
git clone https://github.com/xxx/Identifying-Malicious-WebURLs-Based-on-Machine-Learning-and-Deep-Learning.git
cd Identifying-Malicious-WebURLs-Based-on-Machine-Learning-and-Deep-Learning
  1. 安装依赖
pip install -r requirements.txt
  1. 训练模型(可选,已提供预训练模型):
python medium_training.py
  1. 启动Web服务
python Weburl_test_app.py
  1. 访问系统
    打开浏览器访问 http://localhost:5000

十、总结与展望

10.1 项目总结

本项目成功实现了一个完整的恶意URL检测系统,主要完成了以下工作:

  1. 多算法实现:实现了逻辑回归、XGBoost、全连接网络、VGG网络和残差网络等多种算法
  2. 特征工程:采用TF-IDF + 3-grams的方法进行URL特征提取
  3. 模型优化:通过批归一化、残差连接、Dropout等技术提升模型性能
  4. Web服务:基于Flask构建了完整的Web服务和API接口
  5. 可视化界面:开发了友好的Web界面,支持URL检测和模型训练管理

10.2 核心创新点

  1. VGG+残差网络架构:将VGG的深度堆叠思想与残差连接相结合,在URL检测任务上取得了优异性能
  2. 在线训练功能:支持通过Web界面在线重新训练模型,实时查看训练进度
  3. 数据平衡处理:采用加权采样和带权损失函数处理类别不平衡问题

10.3 未来展望

  1. 深度学习前沿技术

    • 探索Transformer架构在URL检测中的应用
    • 研究图神经网络(GNN)对URL结构信息的建模
    • 尝试预训练语言模型(如BERT)的迁移学习
  2. 多模态融合

    • 结合URL的文本特征、域名WHOIS信息、DNS解析结果等多源信息
    • 引入网页内容分析,提高检测准确率
  3. 实时检测系统

    • 开发浏览器插件,实现访问前的实时检测
    • 与防火墙、WAF等安全设备集成
  4. 对抗样本研究

    • 研究恶意URL的对抗样本生成与防御
    • 提高模型对对抗攻击的鲁棒性
      在这里插入图片描述
      在这里插入图片描述
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐