上週將W13Scan目錄結構整理了一番,以爲要深刻研究還得從代碼層,因而嘗試編寫一下插件;框架自己已經集成了XSS掃描插件;php
本篇文章的XSS插件的編寫單純是爲了學習這個框架,因此只支持GET型,瞭解插件的編寫方法和原理便可。html
W13scan 是基於Python3的一款開源的Web漏洞發現工具,它支持主動掃描模式和被動掃描模式,能運行在Windows、Linux、Mac上。
在編寫插件以前,咱們須要對框架自己的目錄結構有必定了解,因爲W13Scan自己的文檔不是太詳細,我本身整理了一下,目錄結構圖下所示python
├── api 經過API調用啓動掃描 ├── certs HTTPS證書存放目錄 ├── data html輸出模板存放目錄 ├── fingprints 指紋數據 │ ├── framework 框架 │ ├── os 操做系統 │ ├── programing │ └── webserver web服務 ├── lib 框架核心目錄 │ ├── api │ ├── controller │ ├── core │ ├── helper │ ├── parse │ ├── proxy │ └── reverse ├── output 掃描結果輸出目錄 ├── scanners 掃描器插件 │ ├── PerFile 針對每一個文件,包括參數啥的 │ ├── PerFolder 針對url的目錄,會分隔目錄分別訪問 │ ├── PerServer 對每一個domain的 ├── thirdpart │ ├── requests └── w13scan.py 啓動入口
在上方目錄結構中,咱們看到插件都放在scanners
目錄中,入口文件則爲w13scan.py
文件,所以這兩個位置就是咱們須要重點所關注的;如今咱們須要去分析框架的運行流程。git
使用pycharm
編輯器打開文件 w13scan.py
,能夠看到入口文件中的以下代碼web
def main(): # 檢查版本信息 version_check() # 獲取絕對路徑 root = modulePath() # 解析命令行參數 cmdline = cmd_line_parser() # 初始化執行 init(root, cmdline)
在上方代碼中能夠看到運行了初始化init(root,cmdline)
方法,按住ctrl
而後用鼠標點擊跳轉到方法詳情,編輯器自動打開了文件 lib/core/option.py
,能夠看到初始化的具體流程後端
def init(root, cmdline): cinit(autoreset=True) setPaths(root) # 指紋信息 banner() # 從config.py讀取配置信息 _init_conf() # 從cmdline讀取配置 _merge_options(cmdline) # 設置端口信息 _set_conf() initKb() # 加載插件 initPlugins() # 輸出配置信息 _init_stdout() patch_all()
在上方代碼中能夠看到,裏面有一個initPlugins()
方法,一樣按住ctrl
而後點擊方法名字,編輯器會自動打開文件 lib/core/option.py
,能夠看到插件初始化的整個過程api
def initPlugins(): # 加載檢測插件 for root, dirs, files in os.walk(path.scanners): # 獲取插件下的文件列表 files = filter(lambda x: not x.startswith("__") and x.endswith(".py"), files) # 對每個文件進行處理 for _ in files: # 獲取文件名 q = os.path.splitext(_)[0] # 判斷插件白名單 if conf.able and q not in conf.able and q != 'loader': continue # 判斷插件黑名單 if conf.disable and q in conf.disable: continue # 文件絕對路徑 filename = os.path.join(root, _) # 加載該文件 mod = load_file_to_module(filename)
在上方代碼中能夠看到初始化插件,其實就是掃描了插件目錄的文件列表,而後挨個加載文件。瀏覽器
爲了證明這個猜測,我在遍歷的位置進行了代碼調試,加了print()
方法,來驗證個人猜測,代碼以下所示cookie
# 獲取文件名 q = os.path.splitext(_)[0] print(q) print("\n") # 判斷插件白名單 if conf.able and q not in conf.able and q != 'loader': continue
找了一個靶場系統,而後使用w13scan的掃描命令運行,執行命令以下所示框架
python w13scan.py -u "http://192.168.152.135:8888/home/index.php?m=tiezi&a=index&bk=6"
命令執行,在控制檯看到以下信息
(w13scan) D:\mycode\tools\w13scan\W13SCAN>python w13scan.py -u "http://192.168.152.135:8888/home/index.php?m=tiezi&a=index&bk=6" ________________ < w13scan v2.1.0 > ---------------- \ \ ,__, | | (oo)\| |___ (__)\| | )\_ | |_w | \ | | || * Cower.... loader analyze_parameter backup_file ....插件列表,省略.... net_xss swf_files [11:23:49] [INFO] Load scanner plugins:29
在上方的信息中,看到scanners
目錄下的文件列表,因此驗證了個人猜測;
接下來我就能夠正式編寫插件了,爲了防止編寫過程當中對插件目錄形成損壞,我將scanners
目錄複製了一份,以下圖所示
在上圖中,我將scannsers
目錄複製到當前目錄的scannsers
目錄,若是編寫過程當中須要參考或者還原直接拷貝過來便可
接着我回到scanners
目錄,在目錄裏面有29個插件,調試的時候不是太方便,我先將其餘插件都刪除,爲了參考插件怎麼編寫的,我留下一個,以下圖所示
在上圖中,我只留下了一個backup_file.py
插件,用於編寫本身的插件參考;同時我將這個插件改爲本身插件的名字,以下圖所示
在上圖中,我將插件文件名子改成了xss_test.py
,再次運行,看看是否能正確運行,運行結果以下圖所示
在上圖中能夠看到依然是能夠運行的,同時插件名字也發生了變化,變成了xss_test
文件
如今咱們就開始編輯xss_test.py
插件,使用pycharm打開後,看到的代碼以下圖所示
在上圖中能夠看到插件代碼裏面有兩個方法audit
和_check
,我作了下分析,audit
纔是對外的方法,_check
方法是插件內部的方法,咱們不須要,直接刪除便可;
接着咱們新建一個audit
方法,同時備份以前的audit
方法爲audit_bak
做爲參考,以下圖所示
在上圖中,我新建了一個audit
方法,並接收了請求頭信息和要請求的URL地址,並給出了要實現XSS漏洞檢測的三個步驟:
接着我就開始實現這三個步驟,首先去準備poc代碼,以下代碼所示
# 接收頭信息 headers = self.requests.headers # 咱們不要URL地址中的參數部分 url = self.requests.netloc # 從這裏單獨接收參數,字典類型 params = self.requests.params # 這裏備份一下字典,不要使用同一個內存地址 paramsBak = params.copy() # 1. 準備poc payloads = [ "1'\"()&%<acx><ScRiPt >prompt(915149)</ScRiPt>", "<svg/onload=alert(1)>", "\"><script>alert(document.cookie)</script>" ]
接着我須要將poc代碼和URL地址結合,生成一個帶有攻擊參數的連接地址,代碼以下所示
# 每個payloads都測試一遍 for payload in payloads: # 每個參數都須要測試 for key, val in params.items(): # 每次只測試一個參數,因此須要將以前的字典覆蓋 params = paramsBak.copy() # 將字典裏的值改變,而後放到另一個函數生成一個URL地址 params[key] = payload nUrl = self.createUrl(url, params)
生成以下URL地址:
http://192.168.152.135:8888/home/index.php?m=<svg/onload=alert(1)>&a=index&bk=6
或者以下:
http://192.168.152.135:8888/home/index.php?m=tiezi&a=<svg/onload=alert(1)>&bk=6
依次將poc代碼替換到原有請求參數當中,接下來就是使用python去請求這個地址,並查看返回結果是否包含了poc代碼,若是包含了poc代碼說明後端沒有作過濾處理,代碼以下所示
# 2. 發送請求 r = requests.get(nUrl, headers=headers, allow_redirects=False) # 若是返回值是200,說明頁面能夠訪問 if r.status_code == 200: # 3.判斷返回數據裏面是否包含了poc,包含了說明存在XSS if payload in r.text: # 將結果返回給框架,統一存儲 result = self.new_result() result.init_info(nUrl, "XSS檢測", VulType.BRUTE_FORCE) # 存儲掃描結果 result.add_detail("payload請求", r.reqinfo, "請求返回結果", "插件備註信息", nUrl, "", PLACE.GET) self.success(result)
代碼的含義在上面的備註信息中已經有說明,就再也不過多贅述了,接下來咱們再次運行W13Scan
,運行命令以下所示
python w13scan.py -u "http://192.168.152.135:8888/home/index.php?m=tiezi&a=index&bk=6"
命令運行以後,控制檯輸出的信息以下所示
在上圖中能夠看到咱們的插件已經成功運行,並檢測到了XSS漏洞
接下來我複製其中一個帶有poc的URL地址,放到瀏覽器去運行,以下圖所示
在上圖中能夠看到瀏覽器觸發了XSS代碼,彈出了cookie值,至此編寫XSS檢測插件就完成了,固然這個插件還不夠完善,有興趣的能夠本身再深刻研究~
完整的poc代碼能夠參考:
https://gitee.com/songboy/codes/kodyj714izqbpgv8cu2n390
做者:湯青松
日期:2020-12-08