[toc]
# 備注
會(huì)不定時(shí)擴(kuò)充與完善文章內(nèi)容
更新日期:2020年12月13日
# 知識(shí)儲(chǔ)備
## JavaScript
JavaScript 是屬于 HTML 和 Web 的編程語言。
JavaScript 能夠改變 HTML 內(nèi)容。
**案例:**
JavaScript 能夠改變 HTML 屬性
本例通過改變 <img> 標(biāo)簽的 src 屬性(source)來改變一張 HTML 圖像:
```
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript 能做什么?</h2>
<p>JavaScript 能夠改變 HTML 屬性值。</p>
<p>在本例中,JavaScript 改變了圖像的 src 屬性值。</p>
<button onclick="document.getElementById('myImage').src='/i/eg_bulbon.gif'">開燈</button>
<img id="myImage" border="0" src="/i/eg_bulboff.gif" style="text-align:center;">
<button onclick="document.getElementById('myImage').src='/i/eg_bulboff.gif'">關(guān)燈</button>
</body>
</html>
```
![](/upload/attach/202012/202012131753_KJX44TVG79UGY3K.gif)
## JavaScript HTML DOM
通過 HTML DOM,JavaScript 能夠訪問和改變 HTML 文檔的所有元素。
**HTML DOM(文檔對(duì)象模型)**
當(dāng)網(wǎng)頁被加載時(shí),瀏覽器會(huì)創(chuàng)建頁面的文檔對(duì)象模型(Document Object Model)。
HTML DOM 模型被結(jié)構(gòu)化為對(duì)象樹:
對(duì)象的 HTML DOM 樹
![圖片描述](/upload/attach/202012/202012131802_9JWZ3PYH6D839Z5.png)
通過這個(gè)對(duì)象模型,JavaScript 獲得創(chuàng)建動(dòng)態(tài) HTML 的所有力量:
* JavaScript 能改變頁面中的所有 HTML 元素
* JavaScript 能改變頁面中的所有 HTML 屬性
* JavaScript 能改變頁面中的所有 CSS 樣式
* JavaScript 能刪除已有的 HTML 元素和屬性
* JavaScript 能添加新的 HTML 元素和屬性
* JavaScript 能對(duì)頁面中所有已有的 HTML 事件作出反應(yīng)
* JavaScript 能在頁面中創(chuàng)建新的 HTML 事件
HTML DOM 是 HTML 的標(biāo)準(zhǔn)對(duì)象模型和編程接口,它定義了:
* 作為對(duì)象的 HTML 元素
* 所有 HTML 元素的屬性
* 訪問所有 HTML 元素的方法
* 所有 HTML 元素的事件
換言之:HTML DOM 是關(guān)于如何獲取、更改、添加或刪除 HTML 元素的標(biāo)準(zhǔn)。
## HTML DOM Event 對(duì)象
**HTML DOM Document 對(duì)象**
```
每個(gè)載入瀏覽器的 HTML 文檔都會(huì)成為 Document 對(duì)象。
Document 對(duì)象使我們可以從腳本中對(duì) HTML 頁面中的所有元素進(jìn)行訪問。
```
**HTML DOM Element 對(duì)象**
```
在 HTML DOM 中,Element 對(duì)象表示 HTML 元素。
Element 對(duì)象可以擁有類型為元素節(jié)點(diǎn)、文本節(jié)點(diǎn)、注釋節(jié)點(diǎn)的子節(jié)點(diǎn)。
NodeList 對(duì)象表示節(jié)點(diǎn)列表,比如 HTML 元素的子節(jié)點(diǎn)集合。
```
**HTML DOM Attribute 對(duì)象**
```
在 HTML DOM 中,Attr 對(duì)象表示 HTML 屬性。
HTML 屬性始終屬于 HTML 元素。
```
**HTML DOM Event 對(duì)象**
```
Event 對(duì)象代表事件的狀態(tài),比如事件在其中發(fā)生的元素、鍵盤按鍵的狀態(tài)、鼠標(biāo)的位置、鼠標(biāo)按鈕的狀態(tài)。
事件通常與函數(shù)結(jié)合使用,函數(shù)不會(huì)在事件發(fā)生前被執(zhí)行!
```
## 其它前端知識(shí)
學(xué)無止境
# xss漏洞簡介
* 跨站腳本(Cross-Site Scripting,XSS)是一種經(jīng)常出現(xiàn)在Web應(yīng)用程序中的計(jì)算機(jī)安全漏洞,是由于Web應(yīng)用程序?qū)τ脩舻妮斎脒^濾不足而產(chǎn)生的。
* 攻擊者利用網(wǎng)站漏洞把惡意的腳本代碼(通常包括HTML代碼和客戶端Javascript腳本)注入到網(wǎng)頁之中,當(dāng)其他用戶瀏覽這些網(wǎng)頁時(shí),就會(huì)執(zhí)行其中的惡意代碼,對(duì)受害用戶可能采取Cookie資料竊取、會(huì)話劫持、釣魚欺騙等各種攻擊。
* 由于和另一種網(wǎng)頁技術(shù)——層疊樣式表(Cascading Style Sheets,CSS)的縮寫一樣,為了防止混淆,故把原本的CSS簡稱為XSS。通常情況下,我們既可以把跨站腳本理解成一種Web安全漏洞,也可以理解成一種攻擊手段。
* XSS跨站腳本攻擊本身對(duì)Web服務(wù)器沒有直接危害,它借助網(wǎng)站進(jìn)行傳播,使網(wǎng)站的大量用戶受到攻擊。攻擊者一般通過留言、電子郵件或其他途徑向受害者發(fā)送一個(gè)精心構(gòu)造的惡意URL,當(dāng)受害者在Web瀏覽器中打開該URL的時(shí)侯,惡意腳本會(huì)在受害者的計(jì)算機(jī)上悄悄執(zhí)行,其流程如圖所示:
![圖片描述](/upload/attach/202012/202012131820_E66JSHNVFW7D848.png)
**未便于理解進(jìn)行了分類歸納:**
* 反射型XSS(也叫非持久型XSS)
```
發(fā)出請(qǐng)求時(shí),XSS代碼出現(xiàn)在URL中,作為輸入提交到服務(wù)端,服務(wù)端解析后響應(yīng),在響應(yīng)內(nèi)容中出現(xiàn)這段XSS代碼,最后瀏覽器解析執(zhí)行。這個(gè)過程就像一次反射,故稱為反射型XSS。
```
* 存儲(chǔ)型XSS(也叫持久型XSS)
```
存儲(chǔ)型XSS和反射型XSS的差別僅在于:提交的XSS代碼會(huì)存儲(chǔ)在服務(wù)端(不管是數(shù)據(jù)庫、內(nèi)存還是文件系統(tǒng)等),下次請(qǐng)求目標(biāo)頁面時(shí)不用再提交XSS代碼。
```
* DOM XSS
```
DOM XSS的XSS代碼并不需要服務(wù)器解析響應(yīng)的直接參與,觸發(fā)XSS靠的就是瀏覽器端的DOM解析,可以認(rèn)為完全是客戶端的事情。
```
**常見危害例舉**
掛馬
* 盜取用戶Cookie
* DoS(拒絕服務(wù))客戶端瀏覽器
* 釣魚攻擊,高級(jí)釣魚技巧
* 編寫針對(duì)性的XSS病毒
* 刪除目標(biāo)文章
* 惡意篡改數(shù)據(jù)、嫁禍、“借刀殺人”
* 劫持用戶Web行為,甚至進(jìn)一步滲透內(nèi)網(wǎng)
* 蠕蟲攻擊
* 蠕蟲式掛馬攻擊、刷廣告、刷流量、破壞網(wǎng)上數(shù)據(jù)......
# 實(shí)戰(zhàn)
通過案例進(jìn)行講解
## 利用本地存儲(chǔ)功能
在使用搜索功能時(shí)發(fā)現(xiàn)信息存在"駐留"現(xiàn)象
![圖片描述](/upload/attach/202012/202012131813_6G5SPBS3Y4ZTCJQ.png)
* 打開瀏覽器調(diào)試工具分析
**元素**
![圖片描述](/upload/attach/202012/202012131814_5HY2Q5ZM3R25PVZ.png)
**查看js代碼**
![圖片描述](/upload/attach/202012/202012131814_HSC5CQSC86V5VZ4.png)
```
$('.search-ipt').on('input',function () {
let val=localStorage.getItem('record')||''
if (val!=''){
$('.history').css('display','block')
$('.history').html('<a href="/?search='+val+'">'+val+'</a>')
}else{
$('.history').css('display','none')
}
})
$('.search-btn').click(function () {
let val = $('.search-ipt').val()
localStorage.setItem('record',val)
}
)
發(fā)現(xiàn)將數(shù)據(jù)存儲(chǔ)在localStorage
```
![圖片描述](/upload/attach/202012/202012131815_FN2C83HPFFQWQBR.png)
* 輸入js語句進(jìn)行xss測試
```
<script>alert("xss測試")</script>
```
![圖片描述](/upload/attach/202012/202012131816_8MNDV5YU2ZT6UGD.png)
* 搜索執(zhí)行查看
再次搜索成功調(diào)用并按js執(zhí)行了所輸入內(nèi)容
![圖片描述](/upload/attach/202012/202012131817_FGT25EMMAFFW264.png)
## 簡單閉合標(biāo)簽逃逸
![圖片描述](/upload/attach/202012/202012131828_XY7ZFWQRV7VGTGT.png)
發(fā)現(xiàn)輸入的數(shù)據(jù)有駐留但在標(biāo)簽內(nèi)
* 查看js
![圖片描述](/upload/attach/202012/202012131828_DDRSN3RP9GG6R3H.png)
```
$('.search-ipt').on('input',function () {
if ($('.search-ipt').val()==''){
$('.history').css('display','none')
}
else {
$('.history').css('display','block')
}
let val = $('.search-ipt').val()
$('.history').html('<a href="/?search='+val+'">暫無搜索結(jié)果</a>')
})
發(fā)現(xiàn)取內(nèi)容放在<a標(biāo)簽內(nèi)
```
* 輸入測試
![圖片描述](/upload/attach/202012/202012131829_BHRMPW2DNTCWUSB.png)
* 輸入特殊字符閉合標(biāo)簽
閉合成功,輸入內(nèi)容以js代碼形式執(zhí)行
![圖片描述](/upload/attach/202012/202012131829_6387AY7QQYCJ9GZ.png)
**分析:**
輸入"> 閉合了標(biāo)簽<a 并使之后的數(shù)據(jù)可不在標(biāo)簽內(nèi)顯示
![圖片描述](/upload/attach/202012/202012131830_T8R84KCD77TT989.png)
## 添加事件進(jìn)行逃逸
正常測試,查看元素
![圖片描述](/upload/attach/202012/202012131831_2D4JDJQFUDF7R57.png)
* 查看js
![圖片描述](/upload/attach/202012/202012131831_DNWZ6BM7Q3XN3RH.png)
```
$('.url-btn').click(function () {
let val = $('.search-ipt').val()
if (val == '') {
$('.url-box').css('display', 'none')
} else {
val = val.toLocaleLowerCase().replace(/script/g,'').replace(/</g,'').replace(/>/g,'')
$('.url-box').css('display', 'block')
$('.url-box').html('<span style="padding-left: 2px">生成的鏈接為:<a class="url" href="'+val+'">'+val+'</a></span>')
}
}
)
發(fā)現(xiàn)將數(shù)據(jù)存儲(chǔ)在<a標(biāo)簽href屬性內(nèi)
```
* 閉合并添加事件
![圖片描述](/upload/attach/202012/202012131832_ZNX2KE9EGQDWNJR.png)
分析:
需閉合標(biāo)簽并逃逸herf屬性
```
<a> 標(biāo)簽的 href 屬性用于指定超鏈接目標(biāo)的 URL。
href 屬性的值可以是任何有效文檔的相對(duì)或絕對(duì) URL,包括片段標(biāo)識(shí)符和 JavaScript 代碼段。如果用戶選擇了 <a> 標(biāo)簽中的內(nèi)容,那么瀏覽器會(huì)嘗試檢索并顯示 href 屬性指定的 URL 所表示的文檔,或者執(zhí)行 JavaScript 表達(dá)式、方法和函數(shù)的列表。
```
HTML DOM Event 對(duì)象
```
Event 對(duì)象代表事件的狀態(tài),比如事件在其中發(fā)生的元素、鍵盤按鍵的狀態(tài)、鼠標(biāo)的位置、鼠標(biāo)按鈕的狀態(tài)。
```
事件句柄 (Event Handlers)
```
HTML 4.0 的新特性之一是能夠使 HTML 事件觸發(fā)瀏覽器中的行為,比如當(dāng)用戶點(diǎn)擊某個(gè) HTML 元素時(shí)啟動(dòng)一段 JavaScript。下面是一個(gè)屬性列表,可將之插入 HTML 標(biāo)簽以定義事件的行為。
```
![圖片描述](/upload/attach/202012/202012131838_JV66U94KH5DEDFZ.png)
事件通常與函數(shù)結(jié)合使用,函數(shù)不會(huì)在事件發(fā)生前被執(zhí)行!
onmouseover 事件會(huì)在鼠標(biāo)指針移動(dòng)到指定的對(duì)象上時(shí)發(fā)生
```
支持該事件的 HTML 標(biāo)簽:
<a>, <address>, <area>, <b>, <bdo>, <big>, <blockquote>, <body>, <button>,
<caption>, <cite>, <code>, <dd>, <dfn>, <div>, <dl>, <dt>, <em>, <fieldset>,
<form>, <h1> to <h6>, <hr>, <i>, <img>, <input>, <kbd>, <label>, <legend>,
<li>, <map>, <ol>, <p>, <pre>, <samp>, <select>, <small>, <span>, <strong>,
<sub>, <sup>, <table>, <tbody>, <td>, <textarea>, <tfoot>, <th>, <thead>,
<tr>, <tt>, <ul>, <var>
```
![](/upload/attach/202012/202012131836_63ECKC2PCKHQ9EW.gif)
## 打破長度
* 輸入測試
```
"><script>alert(1)</script>
```
![圖片描述](/upload/attach/202012/202012241342_E3YQUTWG8UKGKCY.png)
測試發(fā)現(xiàn)輸入內(nèi)容被過濾
換測試代碼
```
" onclick="alert(1)
```
![圖片描述](/upload/attach/202012/202012241343_ZYARKUD7HF4HU49.png)
未過濾但未成功閉合
* 查看代碼
![圖片描述](/upload/attach/202012/202012241344_7KAFAZ7TUH98S38.png)
事件沒有完全閉合后面(多了:content)
*"閉合測試
![圖片描述](/upload/attach/202012/202012241344_UDYPNMB7SQ6PAVT.png)
* 深入測試
![圖片描述](/upload/attach/202012/202012241345_KCXECGFDKVEWJ2U.png)
發(fā)現(xiàn)對(duì)代碼輸入的長度進(jìn)行了限制
* 分析前端代碼
![圖片描述](/upload/attach/202012/202012241345_M57KX32Z59MCXRM.png)
```
let query = getParam('query')||''
if (query){
query=query.replace(/<|>|script/g,'').substring(0, 33)
看到使用了query參數(shù),其值為getParam('query')
```
* getparam()函數(shù)分析
![圖片描述](/upload/attach/202012/202012241346_FU8Z52JM2U8YWF2.png)
```
function getParam(name) {
if (location.search!=''){
let param = new URLSearchParams(location.search)
return decodeURI(param.get(name))
}
若鏈接中存在參數(shù),則創(chuàng)建一個(gè)對(duì)象,值為所有參數(shù),name對(duì)應(yīng)參數(shù)名
```
* 測試
```
"%20onclick="eval(getParam(Test))"&Test=其它代碼
```
![圖片描述](/upload/attach/202012/202012241347_7K6FYSWGQPUZS7S.png)
成功引用。已打破輸入長度限制
## 拼接繞過
* 測試
```
"" onclonclickick="alert(1)"
```
![圖片描述](/upload/attach/202012/202012241347_X5GKDYY4F8SNRYF.png)
被過濾,發(fā)現(xiàn)onclick被過濾成立空字符
* 拼接
```
"" onclonclickick="alert(1)"
```
過濾一個(gè)在加一個(gè)
![圖片描述](/upload/attach/202012/202012241348_VNRH2BG9XWAC8UE.png)
測試成功
# 參考資料
* 《JavaScript 教程》
* 《Web前端黑客技術(shù)揭秘》
* 《XSS跨站腳本攻擊剖析與防御》