動態

詳情 返回 返回

用隱式馬爾科夫模型檢測XSS攻擊Payload - 動態 詳情

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 的語法序列特徵,但對於經過多層編碼、混淆的攻擊樣本效果有限。

此外,模型需要大量帶標籤的數據進行訓練,否則容易過擬合。

更多網安技能的在線實操練習,請點擊這裏>>

 

user avatar TheFutureIsNow 頭像
點贊 1 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.