系列目录
《Web安全之机器学习入门》笔记:第九章 9.2 支持向量机SVM hello world
《Web安全之机器学习入门》笔记:第九章 9.3 支持向量机算法SVM 检测XSS攻击
目录
本系列是《Web安全之机器学习入门》的笔记集合,包含书中第五章-第十七章的内容。本文这一小节主要内容是讲解第8章使用SVM算法的基本用法,本小节使用svm检测XSS攻击,数据集是通过网上搜集的php脚本数据集合。
一、SVM算法
支持向量机SVM(support vector machines)是一种二分类模型,它的目的是寻找一个超平面来对样本进行分割,分割的原则是间隔最大化,最终转化为一个凸二次规划问题来求解。
支持向量机(SVM)是一种聪明的分类方法,它就像是在一堆混杂的弹珠中画出一条最合理的分界线。这个方法特别擅长处理那些"既像这个又像那个"的模糊情况。其核心思想是通过核函数将数据映射到高维空间,并在此空间中构造最优分离超平面,使得两类数据间隔最大化。算法通过寻找支持向量(距离超平面最近的样本点)来确定决策边界,具有结构风险最小化的理论优势。
SVM 基础信息如下表所示
分类 | 描述 |
---|---|
算法类型 | 监督学习(分类/回归) |
核心思想 | 寻找最优超平面,最大化分类间隔 |
关键组件 | 支持向量、分离超平面、间隔边界 |
数学基础 | 凸优化、核方法、结构风险最小化 |
本关卡的处理流程如下图所示。
二、代码实现
1、加载数据集
构造黑白样本,黑样本20w,白样本20w
etl('../data/xss-200000.txt',x,1)
etl('../data/good-xss-200000.txt',x,0)
2、向量特征化
对于数据集文件,每项提取出四个特征,分别是:url长度、url中包含的第三方域名的个数、敏感字符的个数、敏感关键字的个数。
如下为源码,注意相对于书里配套代码,增加了encoding='utf-8',否则会报错。代码为XSS 攻击检测提取 URL 特征:含计算 URL 长度、检测 HTTP 协议标识、统计危险字符(如 <>)及 XSS 关键词(如 alert)出现次数的函数,通过 ETL 函数加载文件,提取上述 4 个特征并按样本类型(XSS / 正常)标记标签,构建特征数据集用于后续模型训练。
- URL 长度:计算并返回 URL 字符串的总字符数
- 协议检测:判断 URL 是否含 http:// 或 https://,返回 1 或 0
- 危险字符:统计 URL 中 <>、,'"/ 等危险字符的出现次数
- 攻击关键词:统计 alert、script = 等 XSS 相关关键词出现次数
- 数据加载:读取文件内容,为每条 URL 提取 4 个特征
- 标签标记:根据样本类型(XSS / 正常)为特征数据标记标签(1/0)
- 特征整合:将提取的特征和标签整合为数据集,供模型使用
# 功能:URL特征提取工具集(用于XSS攻击检测)
def get_len(url):
"""计算URL长度特征"""
return len(url) # 返回URL字符串的总字符数
def get_url_count(url):
"""检测URL中是否包含HTTP协议标识"""
if re.search('(http://)|(https://)', url, re.IGNORECASE): # 忽略大小写匹配http://或https://
return 1 # 存在协议头返回1
else:
return 0 # 不存在返回0
def get_evil_char(url):
"""统计危险字符出现次数"""
# 匹配<>,'"/等特殊字符(常用于XSS攻击)
return len(re.findall("[<>,\'\"/]", url, re.IGNORECASE)) # 返回匹配到的危险字符总数
def get_evil_word(url):
"""统计XSS攻击关键词出现次数"""
# 匹配常见XSS攻击关键词(不区分大小写):
# alert, script=, %3c(<), %3e(>), %20(空格),
# onerror, onload, eval, src=, prompt
return len(re.findall(
"(alert)|(script=)(%3c)|(%3e)|(%20)|(onerror)|(onload)|(eval)|(src=)|(prompt)",
url, re.IGNORECASE
))
def etl(filename, data, isxss):
"""
数据抽取转换加载(ETL)主函数
:param filename: 数据文件路径
:param data: 存储特征数据的列表
:param isxss: 是否为XSS样本的标记
:return: 更新后的特征数据集
"""
with open(filename, encoding='utf-8') as f:
for line in f:
# 提取四个特征:
f1 = get_len(line) # 特征1:URL长度
f2 = get_url_count(line) # 特征2:是否含HTTP协议
f3 = get_evil_char(line) # 特征3:危险字符数
f4 = get_evil_word(line) # 特征4:攻击关键词数
# 将特征向量加入数据集
data.append([f1, f2, f3, f4])
# 根据isxss参数设置标签(1表示XSS攻击,0表示正常)
if isxss:
y.append(1) # 全局变量需在函数外定义
else:
y.append(0)
return data
"""
使用示例:
# 初始化全局变量
data = []
y = []
# 处理XSS样本
data = etl("xss_samples.txt", data, isxss=True)
# 处理正常样本
data = etl("normal_urls.txt", data, isxss=False)
打印数据集X的前四个数据,结果如下所示。
[23, 0, 2, 0]
[106, 0, 7, 5]
[16, 0, 2, 0]
[24, 0, 2, 0]
3、SVM训练
如下所示,将数据集拆分:用 train_test_split 按 4:6 比例划分测试集(40%)和训练集(60%),固定随机种子确保结果可复现;初始化线性核支持向量机(SVM),以 C=1 控制正则化强度,用训练集拟合模型;最后用训练好的模型预测测试集标签,为后续模型评估(如准确率计算)提供预测结果,完成分类模型的训练与预测流程。
x_train, x_test, y_train, y_test = model_selection.train_test_split(x,y, test_size=0.4, random_state=0)
clf = svm.SVC(kernel='linear', C=1).fit(x_train, y_train)
y_pred = clf.predict(x_test)
4、完整源码
本文构建 SVM 模型检测 XSS 攻击。提取 URL 的 4 个特征(长度、协议标识、危险字符数、攻击关键词数),加载 XSS 和正常 URL 数据生成特征集与标签;按 6:4 拆分训练 / 测试集,训练线性核 SVM(C=1),预测测试集并计算准确率、混淆矩阵等指标,最后保存模型,完成 XSS 检测模型的训练、评估与持久化。
- 特征提取:计算 URL 长度、协议标识、危险字符及 XSS 关键词数量
- 数据加载:读取 XSS 和正常 URL 文件,提取特征并标记标签(1/0)
- 数据集拆分:按 4:6 划分测试集(40%)和训练集(60%),固定随机种子
- 模型训练:初始化线性核 SVM,用训练集拟合模型(C=1 控制正则化)
- 模型预测:用训练好的模型预测测试集标签
- 模型评估:计算并输出准确率、混淆矩阵等评估指标
- 模型保存:将训练好的 SVM 模型持久化存储为文件
import re
import joblib
from sklearn import model_selection
from sklearn import svm
from sklearn import metrics
x = []
y = []
def get_len(url):
return len(url)
def get_url_count(url):
if re.search('(http://)|(https://)', url, re.IGNORECASE) :
return 1
else:
return 0
def get_evil_char(url):
return len(re.findall("[<>,\'\"/]", url, re.IGNORECASE))
def get_evil_word(url):
return len(re.findall("(alert)|(script=)(%3c)|(%3e)|(%20)|(onerror)|(onload)|(eval)|(src=)|(prompt)",url,re.IGNORECASE))
def do_metrics(y_test,y_pred):
print("metrics.accuracy_score:")
print(metrics.accuracy_score(y_test, y_pred))
print("metrics.confusion_matrix:")
print(metrics.confusion_matrix(y_test, y_pred))
print("metrics.precision_score:")
print(metrics.precision_score(y_test, y_pred))
print("metrics.recall_score:")
print(metrics.recall_score(y_test, y_pred))
print("metrics.f1_score:")
print(metrics.f1_score(y_test, y_pred))
def etl(filename,data,isxss):
with open(filename, encoding='utf-8') as f:
for line in f:
f1=get_len(line)
f2=get_url_count(line)
f3=get_evil_char(line)
f4=get_evil_word(line)
data.append([f1,f2,f3,f4])
if isxss:
y.append(1)
else:
y.append(0)
return data
etl('../data/xss-200000.txt',x,1)
etl('../data/good-xss-200000.txt',x,0)
x_train, x_test, y_train, y_test = model_selection.train_test_split(x,y, test_size=0.4, random_state=0)
clf = svm.SVC(kernel='linear', C=1).fit(x_train, y_train)
y_pred = clf.predict(x_test)
do_metrics(y_test, y_pred)
joblib.dump(clf,"xss-svm-200000-module.m")
5、运行结果
运行结果如下所示,该 SVM 模型检测 XSS 攻击的性能优异:准确率达 99.79%,说明整体分类正确性极高;混淆矩阵显示正常 URL 误判为攻击 73 条,攻击 URL 漏判 53 条,错误率极低;精确率 98.88%、召回率 99.18%、F1 分数 99.03%,表明模型对攻击样本的识别能力强(漏检少)且误判少,综合性能接近完美,适用于实际 XSS 攻击检测场景。
metrics.accuracy_score:
0.9979229856257418
metrics.confusion_matrix:
[[54092 73]
[ 53 6446]]
metrics.precision_score:
0.988801963491333
metrics.recall_score:
0.9918448992152639
metrics.f1_score:
0.9903210938700261
6、模型验证
clf1 = joblib.load("xss-svm-200000-module.m")
y_test1 = []
y_test1 = clf1.predict(x)
print(metrics.accuracy_score(y_test1, y))
运行结果如下所示。
0.9979493333685002