#用于學習web安全自動化工具#
我能收獲什么?
1.XSS漏洞檢測機制
- 學習如何構造和發送XSS payload
- 如何識別響應中的回顯,WAF,過濾規則等
- 如何使用詞典,編碼策略,上下文探測等繞過過濾器
2.Python安全工具開發技巧
- 使用requests,urllib等模塊構造請求
- 多線程異步掃描
- 數據結構組織方式
- 命令行界面交互的設計思路
3.源碼工程結構與模塊劃分
- 如何將工具拆分為功能模塊
- 如何設計配置文件,命令參數,插件式架構
4.反WAF與XSS繞過技巧
- 內置的繞過payload和算法
- DOM與反射型XSS的區分探測方式
學習步驟
- 快速了解工具的功能和使用方式(閱讀README文檔,運行XSSstrike,觀察常見命令行參數,輸出內容,執行流程)
- 通過項目結構,理解各個模塊的職責(梳理模塊用途,建立模塊依賴關系圖)
- 選擇一個典型流程深入分析
- 學習其中用到的關鍵技術
項目概述
理解XSSstrike運作原理,學習其中的技術
模塊 | 功能說明 | 是否有獨立文件/目錄 |
---|---|---|
智能 Payload 生成器 | 根據上下文動態構造有效 Payload,而非使用固定詞典 | core/payloads.py |
HTML/JS 解析器 | 手工編寫的解析器,能理解上下文 | core/parsers/ 下可能包含 |
Fuzzing 引擎 | 自動注入參數 + 分析響應 + 變異構造 | core/fuzzer.py |
爬蟲引擎 | 多線程爬蟲(基于 Photon) | core/crawler.py |
參數發現工具 | 自動挖掘 URL 參數(可能集成 Arjun) | core/parameter.py |
WAF 探測與繞過 | 檢測是否被 WAF 攔截并嘗試繞過 | core/waf.py |
DOM XSS 掃描 | 分析 JavaScript 中觸發的 XSS(可能用到 headless 瀏覽器) | core/dom_scanner.py |
盲 XSS 支持 | 支持回顯不可見的注入測試 | 可能集成 external webhook |
Payload 編碼器 | 支持 URL、Unicode、HTML 編碼等 | utils/encoder.py |
配置模塊 | 支持高度定制,可能有配置文件或命令參數 | config.py 或 core/config.py |
學習流程
一.運行XSSstrike+跟蹤主入口
進行調試:我使用的是vscode,launch.json是其中的調試配置文件,用于告訴vscode要調試哪個程序(program),使用什么語言(python),傳入哪些命令參數(args),是否使用終端,是否附加已有進程等等
添加斷點,進行調試,觀察運行過程
二.分析主程序入口(xsstrike.py)
功能概述:這是主程序入口,所有的功能模塊都是從這里開始被調用
內容:
1.基礎引入和環境檢測
2.參數解析:argparse
參數 | 長參數形式 | 說明 |
---|---|---|
-h | --help | 顯示幫助信息并退出 |
-u | --url TARGET | 目標 URL |
--data | PARAMDATA | POST 數據 |
-e | --encode ENCODE | 對 payload 進行編碼 |
— | --fuzzer | 啟動 fuzz 模式 |
— | --update | 檢查并安裝更新 |
— | --timeout TIMEOUT | 設置請求超時時間 |
— | --proxy | 使用代理 |
— | --crawl | 啟用爬蟲功能 |
— | --json | 將 POST 數據作為 JSON 格式處理 |
— | --path | 在 URL 路徑中注入 payload |
— | --seeds ARGS_SEEDS | 從文件加載爬蟲種子 URL |
-f | --file ARGS_FILE | 從文件加載 payload 列表 |
-l | --level LEVEL | 設置爬蟲的深度級別 |
— | --headers [ADD_HEADERS] | 添加自定義請求頭 |
-t | --threads THREADCOUNT | 設置線程數量 |
-d | --delay DELAY | 請求之間的延遲時間 |
— | --skip | 不詢問是否繼續 |
— | --skip-dom | 跳過 DOM XSS 檢測 |
— | --blind | 爬蟲過程中注入 Blind XSS payload |
— | --console-log-level {DEBUG,INFO,RUN,GOOD,WARNING,ERROR,CRITICAL,VULN} | 設置控制臺日志級別 |
— | --file-log-level {DEBUG,INFO,RUN,GOOD,WARNING,ERROR,CRITICAL,VULN} | 設置日志文件的日志級別 |
— | --log-file LOG_FILE | 指定日志文件名稱 |
3.配置與全局變量初始化:將命令行參數作為全局配置傳入globalVariables,方便各模塊共享使用,處理headers和初始化關鍵模塊
if type(args.add_headers) == bool:headers = extractHeaders(prompt()) # 手動輸入
elif type(args.add_headers) == str:headers = extractHeaders(args.add_headers) # 解析命令行輸入
from core.config import blindPayload
from core.encoders import base64
from core.photon import photon
from core.prompt import prompt
from core.utils import extractHeaders, reader, converter
#這些是 XSStrike 自研的模塊,用于數據處理、payload 編碼、用戶輸入交互、爬蟲等。
4.程序執行主邏輯(主控制流)
1)單次fuzz模式
if fuzz:singleFuzz(target, paramData, encoding, headers, delay, timeout)
2)非遞歸掃描模式
elif not recursive and not args_seeds:if args_file:bruteforcer(target, paramData, payloadList, encoding, headers, delay, timeout)else:scan(target, paramData, encoding, headers, delay, timeout, skipDOM, skip)
解釋:scan()是常規XSS掃描的主函數,bruteforcer是自定義的payload掃描
3)爬蟲+全站掃描模式
else:if target:seedList.append(target)for target in seedList:logger.run('Crawling the target')scheme = urlparse(target).schemelogger.debug('Target scheme: {}'.format(scheme))host = urlparse(target).netlocmain_url = scheme + '://' + hostcrawlingResult = photon(target, headers, level,threadCount, delay, timeout, skipDOM)forms = crawlingResult[0]domURLs = list(crawlingResult[1])difference = abs(len(domURLs) - len(forms))if len(domURLs) > len(forms):for i in range(difference):forms.append(0)elif len(forms) > len(domURLs):for i in range(difference):domURLs.append(0)threadpool = concurrent.futures.ThreadPoolExecutor(max_workers=threadCount)futures = (threadpool.submit(crawl, scheme, host, main_url, form,blindXSS, blindPayload, headers, delay, timeout, encoding) for form, domURL in zip(forms, domURLs))for i, _ in enumerate(concurrent.futures.as_completed(futures)):if i + 1 == len(forms) or (i + 1) % threadCount == 0:logger.info('Progress: %i/%i\r' % (i + 1, len(forms)))logger.no_format('')
解釋:基于Phonton進行自動爬蟲,并結合HTML/JS解析器對表單/鏈接發起掃描和fuzz
總模塊結構圖:
xsstrike.py
├── argparse 命令行處理
├── 核心配置加載 core/config
├── 日志模塊初始化 core/log
├── 請求頭處理 extractHeaders/prompt
├── 調用模式模塊:
│ ├── modes/scan.py
│ ├── modes/singleFuzz.py
│ ├── modes/bruteforcer.py
│ └── core/photon.py + crawl.py (爬蟲+分析)
└── payload/參數/headers/encoder 等輔助模塊調用
三.modes/scan.py
功能概述:這個函數是XSStrike的核心掃描邏輯,其主要職責是對目標URL參數進行反射檢查,判斷是否存在XSS,分析過濾器繞過策略,并生成有效payload進行驗證
內容:
1.URL構造和初始請求
GET, POST = (False, True) if paramData else (True, False)
解釋:如果指定了 paramData
(POST 數據),則使用 POST,否則默認 GET。
if not target.startswith('http'):try:response = requester('https://' + target, {},headers, GET, delay, timeout)target = 'https://' + targetexcept:target = 'http://' + target
解釋:自動補全協議頭(如 example.com
→ https://example.com
)
2.DOM XSS檢測
if not skipDOM:logger.run('Checking for DOM vulnerabilities')highlighted = dom(response)if highlighted:logger.good('Potentially vulnerable objects found')logger.red_line(level='good')for line in highlighted:logger.no_format(line, level='good')logger.red_line(level='good')
解釋:使用core/dom.py模塊進行靜態DOM XSS檢查,如果HTML中出現可能被動態執行的eval()或innerHTML拼接位置,會被標記
3.參數提取和WAF檢測
params = getParams(target, paramData, GET)
解釋:從URL或POST data中提取參數
WAF = wafDetector(url, {list(params.keys())[0]: xsschecker}, headers, GET, delay, timeout)
解釋:使用core/wafDetector.py模塊,向目標發送特征性payload并分析相應內容,檢測是否存在WAF檢測
4.反射檢測+payload構造主循環
對每一個參數逐一進行 fuzz 和檢測:
for paramName in params.keys():paramsCopy = copy.deepcopy(params)...
1)參數注入和反射檢測
if encoding:paramsCopy[paramName] = encoding(xsschecker)else:paramsCopy[paramName] = xsscheckerresponse = requester(url, paramsCopy, headers, GET, delay, timeout)occurences = htmlParser(response, encoding)
解釋:注入payload,并分析響應中是否出現該值,htmlParser()
返回值如 {<位置>: <標簽上下文>}
。
2)分析過濾器
efficiencies = filterChecker(url, paramsCopy, headers, GET, delay, occurences, timeout, encoding)
解釋:使用多個輕量payload模擬不同類型的XSS注入,檢測哪些被過濾,返回每種payload的注入效率指標。
3)生成繞過payload
vectors = generator(occurences, response.text)
解釋:根據參數反射位置生成上下文對應的payload列表,含逃逸策略和雙引號,尖括號編碼等變體。
5.Payload驗證循環
for confidence, vects in vectors.items():for vect in vects:...efficiencies = checker(...)
1)判斷有效性
bestEfficiency = max(efficiencies)
解釋:如果payload達到效率100或>=95且以\開頭,則認為是高危
2)是否繼續掃描
if not skip:choice = input('...Continue?').lower()if choice != 'y':quit()
模塊間調用邏輯圖:
scan.py
├── requester() → 發起請求
├── dom() → DOM XSS 靜態檢測
├── getParams() → 參數提取
├── wafDetector() → 檢測是否有 WAF
├── htmlParser() → 判斷反射點(xsschecker 是否出現在響應中)
├── filterChecker() → 判斷輸入被過濾的規則
├── generator() → 根據反射點生成合適上下文 payload
└── checker() → 逐個 payload 驗證其注入效率
四.modes/singleFuzz.py(--fuzzer)
功能概述:這是XSStrike中一個用于快速fuzz單個參數的簡化掃描模塊,適用于手動分析或快速檢測用途。相比主掃描邏輯scan.py,它不執行DOM分析,paylaod構造或效率計算,僅將一個標準payload插入目標參數并fuzz相應內容
(注釋:什么是fuzzing?fuzzing指的是自動的或半自動的向程序輸入大量隨機,異常或畸形的數據,以觀察程序是否會出現異常行為,比如崩潰,處理失敗或產生漏洞等。)
內容:
1.函數定義
def singleFuzz(target, paramData, encoding, headers, delay, timeout):
參數名 | 含義 |
---|---|
target | 目標 URL |
paramData | POST 數據(若為 None 則默認 GET 請求) |
encoding | 可選,對 payload 進行編碼 |
headers | 自定義請求頭 |
delay | 每個請求之間的延遲(防止 WAF) |
timeout | 請求超時時間 |
2.請求方法和URL預處理
GET, POST = (False, True) if paramData else (True, False)# If the user hasn't supplied the root url with http(s), we will handle itif not target.startswith('http'):try:response = requester('https://' + target, {},headers, GET, delay, timeout)target = 'https://' + targetexcept:target = 'http://' + target
3.日志輸出和參數準備
host = urlparse(target).netloc
url = getUrl(target, GET)
params = getParams(target, paramData, GET)
解釋:解析出主機名,最終構造的URL和參數鍵值對,使用core/utils.py中的工具函數
4.WAF檢測
WAF = wafDetector(url, {list(params.keys())[0]: xsschecker}, headers, GET, delay, timeout)
5.Fuzz主題邏輯
for paramName in params.keys():logger.info('Fuzzing parameter: %s' % paramName)paramsCopy = copy.deepcopy(params)paramsCopy[paramName] = xsscheckerfuzzer(url, paramsCopy, headers, GET, delay, timeout, WAF, encoding)
解釋:逐個參數插入標準payload,調用core/fuzzer.py中的fuzzer()進行fuzz
與scan.py的區別:
功能 | scan.py | singlefuzz.py |
---|---|---|
DOM 檢測 | ? | ? |
Payload 構造 | ? | ? |
自動反射分析 | ? | ? |
多參數掃描 | ? | ? |
標準 payload fuzz | ? | ?(核心功能) |
用途 | 自動掃描 + 精度分析 | 快速測試某個目標是否有反射型 XSS |
五.modes/bruteforcer.py(-f ARGS_FILE)
功能概述:實現了一個基于payload列表的暴力測試器,用于向指定參數逐個注入Payload,并檢測是否存在響應中,從而判斷是否反射
內容:
1.主函數
def bruteforcer(target, paramData, payloadList, encoding, headers, delay, timeout):
-
target
:目標 URL。 -
paramData
:POST 參數,如果為空則默認使用 GET。 -
payloadList
:需要測試的 Payload 字符串列表。 -
encoding
:是否使用編碼函數處理 Payload(如 HTML 實體編碼等)。 -
headers
:請求頭字典。 -
delay
:請求間隔延遲。 -
timeout
:請求超時時間。
2.請求方法和URL預處理
GET, POST = (False, True) if paramData else (True, False)host = urlparse(target).netloc # Extracts host out of the urllogger.debug('Parsed host to bruteforce: {}'.format(host))url = getUrl(target, GET)logger.debug('Parsed url to bruteforce: {}'.format(url))params = getParams(target, paramData, GET)logger.debug_json('Bruteforcer params:', params)if not params:logger.error('No parameters to test.')quit()
3.外層循環:遍歷參數名,內層循環:遍歷payload列表
for paramName in params.keys():progress = 1paramsCopy = copy.deepcopy(params)for payload in payloadList:logger.run('Bruteforcing %s[%s%s%s]%s: %i/%i\r' %(green, end, paramName, green, end, progress, len(payloadList)))if encoding:payload = encoding(unquote(payload))paramsCopy[paramName] = payloadresponse = requester(url, paramsCopy, headers,GET, delay, timeout).textif encoding:payload = encoding(payload)if payload in response:logger.info('%s %s' % (good, payload))progress += 1
六.modes/craw.py(--craw)
功能概述:負責處理表單爬取,漏洞檢測,Blind XSS注入
函數:
def crawl(scheme, host, main_url, form, blindXSS, blindPayload, headers, delay, timeout, encoding):
-
scheme
: 協議名,如"http"
或"https"
-
host
: 主機名,如"example.com"
-
main_url
: 起始頁面的 URL,用于校驗表單來源 -
form
: 從頁面中提取到的所有表單數據(是一個字典,通常由htmlParser
提供) -
blindXSS
: 布爾值,是否啟用 Blind XSS 模式 -
blindPayload
: 如果啟用 Blind XSS,這是注入的 payload -
headers
: 請求頭 -
delay
: 每次請求之間的延遲(秒) -
timeout
: 請求超時時間 -
encoding
: payload 的編碼方式(可選)
內容:
if form:for each in form.values():url = each['action']
解釋:遍歷頁面中提取到的所有的form,每個表單是一個dict,含有action,method,inputs等信息,從中獲取<form action="...">中的URL
1)構造完整的表單提交URL
if url:if url.startswith(main_url):passelif url.startswith('//') and url[2:].startswith(host):url = scheme + '://' + url[2:]elif url.startswith('/'):url = scheme + '://' + host + urlelif re.match(r'\w', url[0]):url = scheme + '://' + host + '/' + url
2)初始化記錄,避免重復檢測
if url not in core.config.globalVariables['checkedForms']:core.config.globalVariables['checkedForms'][url] = []
解釋:全局變量 checkedForms
用來記錄已經檢測過的表單和參數,避免重復。
3)提交表單參數+構造參數
method = each['method']
GET = True if method == 'get' else False
inputs = each['inputs']
paramData = {}
for one in inputs:paramData[one['name']] = one['value']
解釋:獲取表單的提交方式(GET/POST),提取所有輸入框的嗎name/value作為參數字典paramData。
4)遍歷每一個參數并開始測試
for paramName in paramData.keys():if paramName not in core.config.globalVariables['checkedForms'][url]:core.config.globalVariables['checkedForms'][url].append(paramName)
解釋:只測試沒有檢測過的參數
5)注入XSS測試載荷,然后發送請求
paramsCopy = copy.deepcopy(paramData)
paramsCopy[paramName] = xsschecker
response = requester(url, paramsCopy, headers, GET, delay, timeout)
解釋:拷貝參數,向當前參數注入默認XSS檢測payload,并發送請求
6)相應解析和位置提取
occurences = htmlParser(response, encoding)
positions = occurences.keys()
解釋:使用htmlParser查找payload是否出現在響應中,并提取位置
7)進一步過濾+生成payload
occurences = filterChecker(url, paramsCopy, headers, GET, delay, occurences, timeout, encoding)
vectors = generator(occurences, response.text)
解釋:filterChecker用于檢查是否有字符被過濾,generator根據上下文和過濾情況生成最適合的XSS payload
8)如果找到可利用的payload,輸出結果
if vectors:for confidence, vects in vectors.items():try:payload = list(vects)[0]logger.vuln('Vulnerable webpage: %s%s%s' % (green, url, end))logger.vuln('Vector for %s%s%s: %s' % (green, paramName, end, payload))breakexcept IndexError:pass
解釋:成功生成 payload 則輸出漏洞信息(URL + payload),break 表示只輸出一個 payload 即可。
9)注入Blind XSS(如果啟用)
if blindXSS and blindPayload:paramsCopy[paramName] = blindPayloadrequester(url, paramsCopy, headers, GET, delay, timeout)
解釋:如果開啟了Blind XSS模式,則用blindPayload再次注入,這種payload不在當前頁面回顯,但可能在后臺系統觸發。
七.core/dom.py
功能概述:在響應的<script>標簽中尋找潛在的XSS"source→sink"流,從而判斷是否存在DOM XSS漏洞。
關鍵術語:
概念 | 解釋 |
---|---|
DOM XSS | 通過 JavaScript 在客戶端執行中,攻擊者控制的輸入流向危險的函數(如 innerHTML , eval ),造成 XSS |
Source | 攻擊者可控的輸入點(如 document.location , window.name ) |
Sink | 可能執行惡意代碼的危險函數(如 eval , innerHTML , document.write ) |
變量追蹤 | 判斷 source 內容是否被賦值給某個變量,再被傳入 sink |
內容:
1)識別source和sink正則
sources = r'''\b(?:document\.(URL|documentURI|...|referrer)|location\.(...))\b'''
sinks = r'''\b(?:eval|assign|innerHTML|...|document\.(write|writeln)|...)'''
2)用正則匹配<script>標簽內容
scripts = re.findall(r'(?i)(?s)<script[^>]*>(.*?)</script>', response)
3)主循環分析邏輯
sinkFound, sourceFound = False, False
for script in scripts:script = script.split('\n')num = 1allControlledVariables = set()
-
sinkFound
、sourceFound
:用于標記是否發現漏洞路徑。 -
將每段
<script>
的內容按行分割,便于逐行分析與高亮。 -
allControlledVariables
:記錄由用戶輸入派生出的變量名。
4)逐行掃描JS內容
for newLine in script:line = newLineparts = line.split('var ')controlledVariables = set()
解釋:每行JS代碼存在于newline中,用split('var ') 試圖提取變量定義
5)檢查source派生變量
for part in parts:for controlledVariable in allControlledVariables:if controlledVariable in part:controlledVariables.add(re.search(r'[a-zA-Z$_][a-zA-Z0-9$_]+', part).group().replace('$', '\\$'))
解釋:如果在某一行中,已有受控變量出現在某段變量定義中,就認為新的變量也被污染。(污點傳播)
6)匹配source并高亮
pattern = re.finditer(sources, newLine)
for grp in pattern:source = newLine[grp.start():grp.end()].replace(' ', '')if len(parts) > 1:for part in parts:if source in part:controlledVariables.add(re.search(r'[a-zA-Z$_][a-zA-Z0-9$_]+', part).group().replace('$', '\\$'))line = line.replace(source, yellow + source + end)
解釋:使用正則在該行中查找source,將發現的source替換為黃色高亮,如果source出現在變量定義中,也將該變量添加為受控變量。
7)受控變量使用點檢查
for controlledVariable in allControlledVariables:matches = list(filter(None, re.findall(r'\b%s\b' % controlledVariable, line)))if matches:sourceFound = Trueline = re.sub(r'\b%s\b' % controlledVariable, yellow + controlledVariable + end, line)
解釋:如果本行中使用了受控變量,也高亮顯示,并標記sourceFound,說明受控輸入正在傳播
8)檢測sink并高亮
pattern = re.finditer(sinks, newLine)
for grp in pattern:sink = newLine[grp.start():grp.end()].replace(' ', '')if sink:line = line.replace(sink, red + sink + end)sinkFound = True
解釋:匹配sink函數入innerHTML,eval,將其紅色高亮,只要存在sink就標記sinkFound
9)保存高亮結果
if line != newLine:highlighted.append('%-3s %s' % (str(num), line.lstrip(' ')))
num += 1
-
如果當前行已被高亮處理(說明可能存在危險 source → sink 流),就保存。
-
添加行號便于后續定位漏洞代碼位置。
10)最終返回結果
if sinkFound or sourceFound:return highlighted
else:return []
解釋:如果整個<script>中發現了sink或source,就返回高亮行,狗則返回空列表。
小結:
HTML Response↓
提取 <script> 腳本↓
逐行查找用戶可控的 source(黃色高亮)↓
變量污染分析:追蹤 source → var a → var b↓
查找危險 sink 函數(紅色高亮)↓
匹配成功 → 返回高亮源碼(標記潛在 DOM XSS)
八.core/fuzzer.py
功能概述:
九.core/generator.py
功能概述:
十.core/photon.py
功能概述:
十一.core/utils.py
功能概述:
十二.core/wafDetector.py
功能概述: