0x01 XSS簡介
XSS是一個(gè)非常常見的Web漏洞,各大互聯(lián)網(wǎng)公司對XSS的重視程度差別很大,有的作為高危,有的最多當(dāng)中危甚至當(dāng)?shù)臀#驘o非是這兩方面:一方面是XSS雖然數(shù)量過多但是利用時(shí)需要很多前置條件,不容易成功利用;另一方面一但被成功利用危害又較大,會造成盜取帳號、控制數(shù)據(jù)、盜竊資料、網(wǎng)站掛馬等危害。
0x02 XSS漏洞檢測
絕大多數(shù)Web漏洞掃描器都可以檢測出某一網(wǎng)站是否存在XSS漏洞,網(wǎng)上也能找到很多專用的XSS檢測工具,具體的原理及檢測過程不再贅述。有興趣可查看極客學(xué)院的課程《XSS檢測與防御》
0x03 XSS自動化驗(yàn)證
驗(yàn)證的前提是已經(jīng)確認(rèn)某頁面存在XSS漏洞,并有成功觸發(fā)的POC(Web漏洞掃描器都會返回吧?)。
驗(yàn)證的思路如下:
- 判斷該P(yáng)OC的發(fā)送方式:GET和POST
- 若為GET,直接發(fā)送即可觸發(fā)
- 若為POST,拆分POC,本地構(gòu)造輸入框,提交POST請求
- 觸發(fā)后自動截圖
1、判斷發(fā)送方式
此處使用的是某廠商的Web漏掃,很人性化的提示當(dāng)前使用的POC是用那種方式提交,不用自己進(jìn)行判斷,其他情況后續(xù)再做補(bǔ)充。
GET:
POST:
2、瀏覽器操作
既然是漏洞驗(yàn)證,得提供充足的證據(jù)來證明該漏洞確實(shí)是存在的。對于XSS來講,截取瀏覽器界面,證明POC觸發(fā)成功是一個(gè)強(qiáng)有力的證據(jù),所謂“無圖無真相”嘛。此處就得操作瀏覽器了。
瀏覽器操作選用selenium + Firefox。
安裝selenium
代碼是用python寫的,所以基礎(chǔ)環(huán)境為 Windows 10 + python 2.7。
安裝selenium只需要一條命令:
pip install selenium
下載Firefox driver
selenium需要驅(qū)動程序與你所選的瀏覽器進(jìn)行連接。Firefox需要安裝geckodriver才能正常運(yùn)行,同時(shí),確保它在你的PATH環(huán)境中。
下載地址:geckodriver
其他受支持的瀏覽器也有自己的驅(qū)動程序可用。一些更受歡迎的瀏覽器的驅(qū)動程序下載鏈接如下:
Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads
Edge: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Safari: https://webkit.org/blog/6900/webdriver-support-in-safari-10/
selenium簡單操作
簡單說下selenium的操作,編寫代碼,讓瀏覽器依次執(zhí)行以下指令:
- 打開一個(gè)新的Firefox瀏覽器
- 加載百度主頁
- 等待一段時(shí)間
- 關(guān)閉瀏覽器
代碼如下:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('https://www.baidu.com')
driver.implicitly_wait(10)
driver.quit()
3、漏洞驗(yàn)證
如果漏洞POC觸發(fā)方式為GET
時(shí),在上面代碼的基礎(chǔ)上稍作修改,增加窗口最大化以及截圖功能即可實(shí)現(xiàn)。
關(guān)鍵代碼如下:
......
maxWidth = driver.execute_script("return window.screen.availWidth;")
maxHeight = driver.execute_script("return window.screen.availHeight;")
driver.set_window_size(maxWidth, maxHeight)
......
if driver.switch_to_alert():
printScreen.printScreen('crackme2.bmp')
......
有關(guān)自動截圖部分的內(nèi)容請看Python調(diào)用Win32 API實(shí)現(xiàn)截圖
因?yàn)閟elenium操作瀏覽器時(shí),不支持直接發(fā)送POST請求,如果觸發(fā)方式為POST
時(shí),則需要先構(gòu)造表單,用瀏覽器模擬點(diǎn)擊操作來發(fā)送POST請求。
表單構(gòu)造
從Web漏掃獲取到的風(fēng)險(xiǎn)點(diǎn)中,POST觸發(fā)方式的鏈接多為如下形式:
http://***.***.com:80/register/register.php?FirstName=135791&LastName=135791&Password=admin&DOB=135791&Address=135791&txtCity=135791&drpState=Alabama&TelephoneNo=13412312345&Email=admin@admin.com&UserId=admin>'><ScRiPt>window.a==1?1:prompt(a=1)</ScRiPt>
構(gòu)造表單的目的只是用來向服務(wù)器發(fā)送一個(gè)POST請求,所以,越簡單越好。
- 拆分獲取到的url
從Web漏掃獲取存在XSS漏洞的風(fēng)險(xiǎn)點(diǎn),首先拆分出使用的網(wǎng)絡(luò)協(xié)議、域名、路徑以及傳遞的參數(shù)。
import urlparse
url = "http://crackme.cenzic.com:80/kelev/register/register.php?FirstName=135791&LastName=135791&Password=admin&DOB=135791&Address=135791&txtCity=135791&drpState=Alabama&TelephoneNo=13412312345&Email=admin@admin.com&UserId=admin>'><ScRiPt>window.a==1?1:prompt(a=1)</ScRiPt>?qqdrsign=042c6"
res = urlparse.urlparse(url)
scheme = res[0]
host = res[1]
path = res[2]
data_string = res[4]
- 構(gòu)造表單內(nèi)容
將傳遞的參數(shù)進(jìn)一步拆分,還原成表單,生成html代碼。
form = ''
s = data_string.split('&')
for i in range(0, len(s)):
p = s[i].split('=', 1)
inputName = p[0]
inputValue = p[1]
tr = '<tr><td align=right><b>' + inputName + ':</b></td><td><input type=text name="' + inputName + '" value="' + inputValue + '" size=80></td></tr>'
form = form + tr
- 構(gòu)造頁面
添加html代碼,生成完整的.html
文件,方便瀏覽器使用。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>WebApi</title>
<style>
body{ font-size:14px; font-family:"Microsoft Yahei";background-color:#fff;}
td{table-layout: fixed; word-wrap:break-word;word-break:break-all;}
</style>
</head>
<body>
<table border=0 width='90%'>
<tr>
<td align=right style=width:120px;>
<b>url(Action):</b>
</td>
<td>
<a id=id_action target=_blank href="{{ url_base }}">{{ url_base }}</a>
</td>
</tr>
<form name=theForm action="{{ url }}" method=post>
{% csrf_token %}
{% autoescape off %}
{{ form }}
{% endautoescape %}
<tr>
<td></td>
<td>
<input onclick="theForm.action=document.getElementById('id_action').href;" id=id_input_action type=submit value=' 使用Action提交POST數(shù)據(jù) '>
</td>
</tr>
</form>
</table>
</body>
</html>
效果圖如下:
發(fā)送POST請求
XSS驗(yàn)證表單構(gòu)造完畢后,下一步即為發(fā)送POST請求。在前文“selenium簡單操作”部分的代碼基礎(chǔ)上,增加點(diǎn)擊過程即可。
首先,定位元素名為“id_input_action”的按鈕,然后執(zhí)行點(diǎn)擊操作,緊接著判斷是否有彈窗,最后截圖保存到當(dāng)前目錄。代碼如下:
driver.find_element_by_id("id_input_action").click()
time.sleep(3)
if driver.switch_to_alert():
printScreen.printScreen('crackme2.bmp')
0x04 生成報(bào)告
此處為了簡便,直接生成html報(bào)告,后期需要,也可轉(zhuǎn)換成pdf等格式。
構(gòu)造報(bào)告模板
此處為了簡便,可以直接生成html報(bào)告,后期需要,也可轉(zhuǎn)換成pdf等其他格式。
構(gòu)造方式可參考上文表單構(gòu)造部分內(nèi)容,只需要傳入存在漏洞的鏈接以及存放圖片的路徑即可,也可按自己想法或需求,增加漏洞產(chǎn)生的原因、解決方案等內(nèi)容。
0x05 效果展示
腳本運(yùn)行后,先從掃描器結(jié)果中獲取XSS漏洞的url(涉及到api請求與處理),分析當(dāng)前url觸發(fā)方式,選用不同的提交方式去觸發(fā),最后截圖保存(也可以直接寫入word文件中)。