【CCF2022】Web攻击检测与分类识别 baseline

2022-09-26 16:00:46 浏览数 (1)

线下cv acc:0.97 线上 应该0.6

1 赛题介绍

赛题名称: Web攻击检测与分类识别

赛程规划: 参赛报名:2022年8月20日(10点)-10月10日(24点) 线上参赛:2022年8月27日(10点)-10月16日(24点) 复现提交:2022年10月17日-10月23日(16点前) 代码审核:2022年10月24日-2022年11月2日 公布晋级:2022年11月3日-2022年11月6日 决赛答辩:2022年11月18日(暂定)

赛题背景: 某业务平台平均每月捕获到Web攻击数量超过2亿,涉及常见注入攻击,代码执行等类型。传统威胁检测手段通过分析已知攻击特征进行规则匹配,无法检测未知漏洞或攻击手法。如何快速准确地识别未知威胁攻击并且将不同攻击正确分类,对提升Web攻击检测能力至关重要。利用机器学习和深度学习技术对攻击报文进行识别和分类已经成为解决该问题的创新思路,有利于推动AI技术在威胁检测分析场景的研究与应用。

赛题任务: 参赛团队需要对前期提供的训练集进行分析,通过特征工程、机器学习和深度学习等方法构建AI模型,实现对每一条样本正确且快速分类,不断提高模型精确率和召回率。待模型优化稳定后,通过无标签测试集评估各参赛团队模型分类效果,以正确率评估各参赛团队模型质量。

2 数据简介

数据简介 赛题训练集分为6种不同标签,共计约3.5万条数据。训练数据集字段内容主要包括: ● lable:攻击类型编号 ● 其他:HTTP协议内容

LGM基线

导入包

代码语言:javascript复制
import lightgbm as lgb
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from lightgbm import early_stopping
from lightgbm import log_evaluation
from sklearn.decomposition import TruncatedSVD
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import accuracy_score
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
from tqdm import tqdm
from user_agents import parse

数据加载

代码语言:javascript复制
train=pd.concat([
    pd.read_csv('data/train/SQL注入.csv'),
    pd.read_csv('data/train/XSS跨站脚本.csv'),
    pd.read_csv('data/train/命令执行.csv'),
    pd.read_csv('data/train/白.csv'),
    pd.read_csv('data/train/目录遍历.csv'),
    pd.read_csv('data/train/远程代码执行.csv'),
],axis=0).reset_index(drop=True)


test=pd.read_csv('data/test.csv')

标签分布

代码语言:javascript复制
train['label'].value_counts()
代码语言:javascript复制
1,14038
2,9939
0,6489
3,1397
4,697
5,659

基础特征

  • 文本特征
代码语言:javascript复制
texts=data['user_agent'].values.tolist()
n_components = 16
tf = TfidfVectorizer(min_df= 3, max_df=0.5,analyzer = 'char_wb', ngram_range = (2,5))
X = tf.fit_transform(texts)
svd = TruncatedSVD(n_components=n_components,
                   random_state=42)
X_svd = svd.fit_transform(X)
df_tfidf = pd.DataFrame(X_svd)
df_tfidf.columns = [f'user_agent_name_tfidf_{i}' for i in range(n_components)]
  • 类别编码
代码语言:javascript复制
for col in tqdm(cate_cols):
    lbl = LabelEncoder()
    lbl.fit(data[col])
    data[col] = lbl.transform(data[col])

五折交叉验证

代码语言:javascript复制
def lgb_model(train, target, test, k):
    feats = [f for f in train.columns if f not in ['label',  'url', 'url_count']]
    #     feats=import_cols
    print('Current num of features:', len(feats))

    oof_probs = np.zeros((train.shape[0],6))
    output_preds = 0
    offline_score = []
    feature_importance_df = pd.DataFrame()
    parameters = {
        'learning_rate': 0.03,
        'boosting_type': 'gbdt',
        'objective': 'multiclass',
        'metric': 'multi_error',
        'num_class': 6,
        'num_leaves': 31,
        'feature_fraction': 0.6,
        'bagging_fraction': 0.8,
        'min_data_in_leaf': 15,
        'verbose': -1,
        'nthread': 4,
        'max_depth': 7
    }

    seeds = [2020]
    for seed in seeds:
        folds = StratifiedKFold(n_splits=k, shuffle=True, random_state=seed)
        for i, (train_index, test_index) in enumerate(folds.split(train, target)):
            train_y, test_y = target.iloc[train_index], target.iloc[test_index]
            train_X, test_X = train[feats].iloc[train_index, :], train[feats].iloc[test_index, :]

            dtrain = lgb.Dataset(train_X,
                                 label=train_y)
            dval = lgb.Dataset(test_X,
                               label=test_y)
            lgb_model = lgb.train(
                parameters,
                dtrain,
                num_boost_round=8000,
                valid_sets=[dval],
                callbacks=[early_stopping(100), log_evaluation(100)],
            )
            oof_probs[test_index] = lgb_model.predict(test_X[feats], num_iteration=lgb_model.best_iteration) / len(
                seeds)
            offline_score.append(lgb_model.best_score['valid_0']['multi_error'])
            output_preds  = lgb_model.predict(test[feats],
                                              num_iteration=lgb_model.best_iteration) / folds.n_splits / len(seeds)
            print(offline_score)
            # feature importance
            fold_importance_df = pd.DataFrame()
            fold_importance_df["feature"] = feats
            fold_importance_df["importance"] = lgb_model.feature_importance(importance_type='gain')
            fold_importance_df["fold"] = i   1
            feature_importance_df = pd.concat([feature_importance_df, fold_importance_df], axis=0)
    print('OOF-MEAN-AUC:%.6f, OOF-STD-AUC:%.6f' % (np.mean(offline_score), np.std(offline_score)))
    print('feature importance:')
    print(feature_importance_df.groupby(['feature'])['importance'].mean().sort_values(ascending=False).head(50))

    return output_preds, oof_probs, np.mean(offline_score), feature_importance_df
代码语言:javascript复制
print('开始模型训练train')
lgb_preds, lgb_oof, lgb_score, feature_importance_df = lgb_model(train=train[feature_names],
                                                                 target=train['label'],
                                                                 test=test[feature_names], k=5)

优化方向

  • web请求信息解析,比如user_agent/body/url,然后做统计特征
  • 文本特征挖掘,比如tfidf可以对char、toekn级别去做embedding,ngram参数调整下应该有分数变化

欢迎大家关注公众号“ChallengeHub”,获取更多开源方案

0 人点赞