加密流量论文复现:《Detecting DNS over HTTPS based data exfiltration》(下)

  在上一篇文章当中,我们已经详细阅读了论文原文,并对其中的一些较难理解的地方加以解释。本篇文章,将对论文最终得到的结论进行简单的论证。

数据收集

  首先,由于重新搭建和论文描述的实验环境太过复杂,这里为了简化(实际是太懒了),可以寻找网上的相关数据集。可以查阅到,有关DoH隧道研究较为出名,并且能够搜索到的公开数据集是来着“北海道大学”公开的数据集,具体链接如下:https://eprints.lib.hokudai.ac.jp/dspace/handle/2115/88092

在这里插入图片描述

其中有两个数据集,我们下载第一个就ok。因为第二个单纯的都是DoH隧道流量,适用于研究不同软件发出的DoH隧道流量的探测。第一个数据集其实也是包含整理了第二个数据集,其中的l1-total-add.csv 有很多行数据,包含了多个特征值字段和最后的实际标签(DoH或NonDoH),这恰好是可以给我使用的。

  大家可以重新翻看之前的文章,其中讲到了研究者刚开始是使用了如下图的24个特征值进行训练模型:

在这里插入图片描述
但是,在最后的论证当中发现,由于可能会出现0填充的影响导致有关TLS记录长度的特征无效,所以研究者只用了有关时间的特征进行训练,发现效果依然不错,也是他们最后得到的结论之一。所以,我们可以借此使用l1-total-add.csv 当中的有关时间的特征进行模型训练。虽然,数据集中并没有记录,并且我们也无法根据现有的数据计算出和论文当中一模一样的12个时间特征,但是,我认为数据集当中的16个时间特征仍旧有效,能够保留论文当中12个时间特征的相关特性。

模型训练

  论文使用的是sklearn库中的现有模型进行训练,我们也可以同样进行使用。对于研究者使用的增强决策树模型,下面我将会使用GBDT(Gradient Boosting Decision Tree,梯度提升决策树) 进行替代。
  废话不多说,代码也不难,下面直接贴代码。

随机森林

  • 训练代码
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score, StratifiedKFold
from sklearn.metrics import make_scorer, accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
from sklearn.preprocessing import LabelEncoder
from sklearn.utils import shuffle
from joblib import dump  # 用于保存模型
from tqdm import tqdm

# 1. 加载数据
print("正在加载数据...")
data = pd.read_csv(r"CIRA-CIC-DoHBrw-2020-and-DoH-Tunnel-Traffic-HKD\l1-total-add.csv")
print(f"数据加载完成,总样本数: {
     
     len(data)}")

# 2. 清理数据
print("\n正在清理数据...")
data = data.dropna()
print(f"清理后剩余样本数: {
     
     len(data)}")

# 3. 分离特征和标签
X = data.iloc[:, 18:-1].values
y = data.iloc[:, -1].values  # 标签列是字符串( 'DoH'/'NonDoH')

# 4. 将字符串标签编码为数值(推荐)
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(y)
print("类别顺序:", label_encoder.classes_)

# 5. 打乱数据
print("\n正在打乱数据顺序...")
X, y = shuffle(X, y, random_state=42)

# 6. 初始化随机森林模型
print("\n初始化随机森林模型...")
rf_model = RandomForestClassifier(
    n_estimators=100,
    max_depth=None,
    min_samples_split=2,
    min_samples_leaf=1,
    random_state=42,
    verbose=1,
    n_jobs=-1
)

# 7. 定义评估指标
scoring = {
   
   
    'accuracy': make_scorer(accuracy_score),
    'precision': make_scorer(precision_score, pos_label=0),  # 根据实际编码调整
    'recall': make_scorer(recall_score, pos_label=0),
    'f1': make_scorer(f1_score, pos_label=0),
    'roc_auc': make_scorer(roc_auc_score, needs_proba=True)
}

# 8. 5折交叉验证
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# 9. 执行交叉验证(带进度条)
print("\n开始5折交叉验证...")
results = {
   
   }
for metric_name in tqdm(scoring, desc="交叉验证进度"):
    scores = cross_val_score(rf_model, X, y, cv=cv, scoring=scoring[metric_name])
    results[metric_name] = scores.mean()
    print(f"{
     
     metric_name}: {
     
     scores.mean():.4f}{
     
     scores.std():.4f})")

# 10. 输出结果
print("\n平均性能评估:")
for metric, score in results.items():
    print(f"{
     
     metric}: {
     
     score:.4f}")

# 11. 训练最终模型(在整个数据集上)
print("\n训练最终模型...")
rf_model.fit(X, y)
print("模型训练完成!")

# 12. 保存模型
dump(rf_model, 'random_forest_model.joblib')
print("模型已保存为 'random_forest_model.joblib'")
  • 验证代码
import numpy as np
import pandas as pd
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
from joblib import load
from sklearn.preprocessing import LabelEncoder

# 1. 加载数据
print("正在加载数据...")
data = pd.read_csv(r"CIRA-CIC-DoHBrw-2020-and-DoH-Tunnel-Traffic-HKD\l1-total-add.csv")
print(f"数据加载完成,总样本数: {
     
     len(data)}")

# 2. 清理数据
print("\n正在清理数据...")
data = data.dropna()
print(f"清理后剩余样本数: {
     
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值