0.前言
學習一下如何使用機器學習的方式去識別XSS Payload。
1.XSS介紹
其實xss説白了,就是通過向網頁中注入惡意的腳本代碼,一般來説都是 JavaScript,讓代碼在其他用户的瀏覽器中執行,從而達到竊取信息、冒充身份、傳播木馬等目的。
換句話説,網站本來應該只展示安全的內容的,但是攻擊者把一些惡意的腳本給塞入了網站中,讓瀏覽器錯誤地把其當成正常內容執行了。
大概有以下這幾種分類:
反射型:payload 在請求裏,也就是URL或者表單,服務器拼回頁面即觸發,通常需要誘導點擊。
存儲型:payload 被存入庫,比如説什麼網站的評論、暱稱、公告之類的,所有訪問者都會觸發。
DOM 型:前端腳本把不可信數據塞進危險 DOM SinkinnerHTML 之類的,不依賴服務器拼接。
盲 XSS:這個顧名思義是看不到彈窗,但 payload 會在後台或者運營端頁面執行。
自我 XSS:誘導用户在控制枱粘貼代碼。
變異 XSS:瀏覽器或框架在解析或者重排 DOM 時修補標籤,繞過原本的過濾器。
2.隱式馬爾科夫
馬爾科夫模型就是基於本次觀測的狀態來預測上一次的狀態 而不依賴前面的所有內容。
假設現在有三個時間點:1,2,3
在2這個時間點是a,到了3這個時間點就變成了A,而馬爾科夫模型在這裏就僅根據a來預測,而不是根據a前面的內容。
主要解決連續問題,比如説:
-
文本類中上一個字或者詞中下一個字詞的出現概率。
-
一個連續的字詞構成的句子判斷句子的情感等。
使用的時候需要在虛擬環境中下載一個第三方庫
pip install hmmlearn -i https://pypi.tuna.tsinghua.edu.cn/simple
3.使用隱式馬爾科夫識別XSS
注意:這裏只截取重要部分代碼,並沒有展示完全。
xss語法特徵
<src>
<script>
<alert>
http://
<img>
onerror
導入一個文本的數據,都是各種各樣的xss變體,github或者是kaggle上都能找到相關的xss數據集。

然後進行一個數據向量的處理。

這是個正則表達式,匹配雙引號裏面的字符串,比如説xss裏面會有這種<>括起來的符號。
還有把http開頭的,閉合的標籤,反斜杆,或者是隻有一個>,還有=符號,畢竟xss裏面有什麼onerror=xxx之類
還有函數調用,老生常談的alert。
然後使用nltk,一個自然語言的工具,用來做分詞處理。

那什麼是分詞處理?把一段連續的文本拆分成一個個有意義的“詞語”或“最小語言單位”的過程。
在英語中,單詞之間有空格,計算機很容易識別:
“I love natural language processing.”
可以直接得到:["I", "love", "natural", "language", "processing"]
但在中文中,句子是連續的,沒有空格:
“我愛自然語言處理。”
對計算機來説,這是一個連續的字符串,它不知道“我愛”、“自然語言處理”這些邊界。所以就需要中文分詞算法來判斷哪些字該組合在一起。
【----幫助網安學習,以下所有學習資料免費領!加vx:YJ-2021-1,備註 “博客園” 獲取!】
① 網安學習成長路徑思維導圖
② 60+網安經典常用工具包
③ 100+SRC漏洞分析報告
④ 150+網安攻防實戰技術電子書
⑤ 最權威CISSP 認證考試指南+題庫
⑥ 超1800頁CTF實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP客户端安全檢測指南(安卓+IOS)
接下來就是轉換列表,去重,添加等常規操作。

這樣就大致完成了數據向量的處理。
模型的結構
import model_param
from hmmlearn import hmm
remodel = hmm.GaussianHMM(n_components=model_param.N, covariance_type="full", n_iter=model_param.n_iter)
model_param.N是模型的狀態,就是樣本到底有幾個類型,比如3個不同類型的骰子之類的。
covariance_type="full" 這個表示所有的樣本都是有數據的,都是不為0的。
#狀態個數
N=5
#迭代次數
n_iter=100
這裏就把狀態數和迭代數設置為5和100,這裏100次看個人電腦配置吧,我100次都跑得挺慢的。
模型的訓練
import model_struct
import joblib
import vec_data
index_wordbag=1 #詞袋索引
wordbag={} #詞袋
wordbag = vec_data.load_wordbag("E:\\my_hmm\\data\\xss-200000.txt",2000)
X,X_lens = vec_data.vec("E:\\my_hmm\\data\\xss-200000.txt",wordbag)
remodel = model_struct.remodel.fit(X,X_lens)
joblib.dump(remodel, "xss-train.pkl")
把用到的數據都加入到詞袋中去,第一次詞袋是空的,第一次就是去填滿這個內容,也就是詞的特徵,第二次是做匹配,也就是根據上面的特徵去做匹配才能返回X這個結果。
有了X和X_lens之後就可以做訓練,然後把xss-train.pkl這個模型保存到本地。
模型測試
可以設置一個判斷的閾值,或者理解為一個評分。
都是負數,評分越靠近0就説明越不像xss,評分越遠離0就説明很像xss。

比如説我們在test數據中放入這麼幾條數據
/0_1/?%22onmouseover='prompt(42873)'bad=%22%3E
/0_1/api.php?op=map&maptype=1&city=test%3Cscript%3Ealert%28/42873/%29%3C/script%3E
/0_1/api.php?op=map&maptype=1&defaultcity=%e5%22;alert%28/42873/%29;//
/0_1/api.php?op=map&maptype=1&defaultcity=%E5%8C%97%E4%BA%AC&api_key=%22%3E%3C/script%3E%3Cscript%3Ealert%28/42873/%29;%3C/script%3E
/0_1/api.php?op=map&maptype=1&defaultcity=%E5%8C%97%E4%BA%AC&field=%29%3C/script%3E%3Cscript%3Ealert%2842873%29%3C/script%3E//
/0_1/api.php?op=video_api&pc_hash=1&uid=1&snid=%3C/script%3E%3Cscript%3Ealert(/42873/)%3C/script%3E//&do_complete=1%20
/0_1/api.php?op=video_api&uid=1&snid=1&pc_hash=%3C/script%3E%3Cscript%3Ealert(/360/)%3C/script%3E//&do_complete=1
/0_1/?callback=%3Cscript%3Eprompt(42873)%3C/script%3E
讓訓練好的模型去檢測這些是不是xss攻擊。

可以看到評分越小,説明它越像xss攻擊。
接下來,可以把訓練好的模型做成一個可視化界面。
可以使用django或者flask框架,這裏就使用flask框架。
...
#最大似然概率閾值
T=-13
def process_text(input_text):
# 這裏可以添加處理邏輯
remodel = joblib.load("E:\\my_hmm\\model\\xss-train.pkl")
f = open("test.txt", "w")
f.write(input_text)
f.close()
pro,line = test(remodel,"test.txt")
print(pro)
if pro == -1000:
return "請輸入長度為10以上的payload"
elif pro > T:
return "沒有檢測到xss代碼"
else:
return f"檢測的結果是: {line},評分為:{pro}"
@app.route('/', methods=['GET', 'POST'])
def index():
result = ""
if request.method == 'POST':
input_text = request.form['input_text']
result = process_text(input_text)
return render_template('index.html', result=result)
if __name__ == '__main__':
app.run(debug=True)
先把訓練好的模型加載進來,然後把input_txt保存成一個本地文件test.txt,然後使用寫好的判斷分數函數去做一個分數判斷。
因為最簡單的xss攻擊payload也會超過10個長度,所以可以先把長度小於10的排除了。
如果分數大於-13,就説明模型認為不是xss攻擊。
實際效果就如下圖:


使用樣本里面沒有的xss payload 模型也能檢測出來。
但是並非百分之百正確,卻可以解決一些看起來像的問題。
有一點要注意,雖然 HMM 可以捕捉 XSS Payload 的語法序列特徵,但對於經過多層編碼、混淆的攻擊樣本效果有限。
此外,模型需要大量帶標籤的數據進行訓練,否則容易過擬合。
更多網安技能的在線實操練習,請點擊這裏>>