返回首页

微信公众号

3.1.1 前端漏洞-xss

[toc]

備注

會不定時擴充與完善文章內(nèi)容
更新日期:2020年12月13日

知識儲備

JavaScript

JavaScript 是屬于 HTML 和 Web 的編程語言。
JavaScript 能夠改變 HTML 內(nèi)容。
案例:
JavaScript 能夠改變 HTML 屬性
本例通過改變 <img> 標(biāo)簽的 src 屬性(source)來改變一張 HTML 圖像:

1
2
3
4
5
6
7
8
9
10
11
<!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>

JavaScript HTML DOM

通過 HTML DOM,JavaScript 能夠訪問和改變 HTML 文檔的所有元素。
HTML DOM(文檔對象模型)
當(dāng)網(wǎng)頁被加載時,瀏覽器會創(chuàng)建頁面的文檔對象模型(Document Object Model)。
HTML DOM 模型被結(jié)構(gòu)化為對象樹:
對象的 HTML DOM 樹
圖片描述
通過這個對象模型,JavaScript 獲得創(chuàng)建動態(tài) HTML 的所有力量:

  • JavaScript 能改變頁面中的所有 HTML 元素
  • JavaScript 能改變頁面中的所有 HTML 屬性
  • JavaScript 能改變頁面中的所有 CSS 樣式
  • JavaScript 能刪除已有的 HTML 元素和屬性
  • JavaScript 能添加新的 HTML 元素和屬性
  • JavaScript 能對頁面中所有已有的 HTML 事件作出反應(yīng)
  • JavaScript 能在頁面中創(chuàng)建新的 HTML 事件

HTML DOM 是 HTML 的標(biāo)準(zhǔn)對象模型和編程接口,它定義了:

  • 作為對象的 HTML 元素
  • 所有 HTML 元素的屬性
  • 訪問所有 HTML 元素的方法
  • 所有 HTML 元素的事件

換言之:HTML DOM 是關(guān)于如何獲取、更改、添加或刪除 HTML 元素的標(biāo)準(zhǔn)。

HTML DOM Event 對象

HTML DOM Document 對象

1
2
每個載入瀏覽器的 HTML 文檔都會成為 Document 對象。
Document 對象使我們可以從腳本中對 HTML 頁面中的所有元素進行訪問。

HTML DOM Element 對象

1
2
3
在 HTML DOM 中,Element 對象表示 HTML 元素。
Element 對象可以擁有類型為元素節(jié)點、文本節(jié)點、注釋節(jié)點的子節(jié)點。
NodeList 對象表示節(jié)點列表,比如 HTML 元素的子節(jié)點集合。

HTML DOM Attribute 對象

1
2
在 HTML DOM 中,Attr 對象表示 HTML 屬性。
HTML 屬性始終屬于 HTML 元素。

HTML DOM Event 對象

1
2
Event 對象代表事件的狀態(tài),比如事件在其中發(fā)生的元素、鍵盤按鍵的狀態(tài)、鼠標(biāo)的位置、鼠標(biāo)按鈕的狀態(tài)。
事件通常與函數(shù)結(jié)合使用,函數(shù)不會在事件發(fā)生前被執(zhí)行!

其它前端知識

學(xué)無止境

xss漏洞簡介

  • 跨站腳本(Cross-Site Scripting,XSS)是一種經(jīng)常出現(xiàn)在Web應(yīng)用程序中的計算機安全漏洞,是由于Web應(yīng)用程序?qū)τ脩舻妮斎脒^濾不足而產(chǎn)生的。
  • 攻擊者利用網(wǎng)站漏洞把惡意的腳本代碼(通常包括HTML代碼和客戶端Javascript腳本)注入到網(wǎng)頁之中,當(dāng)其他用戶瀏覽這些網(wǎng)頁時,就會執(zhí)行其中的惡意代碼,對受害用戶可能采取Cookie資料竊取、會話劫持、釣魚欺騙等各種攻擊。
  • 由于和另一種網(wǎng)頁技術(shù)——層疊樣式表(Cascading Style Sheets,CSS)的縮寫一樣,為了防止混淆,故把原本的CSS簡稱為XSS。通常情況下,我們既可以把跨站腳本理解成一種Web安全漏洞,也可以理解成一種攻擊手段。
  • XSS跨站腳本攻擊本身對Web服務(wù)器沒有直接危害,它借助網(wǎng)站進行傳播,使網(wǎng)站的大量用戶受到攻擊。攻擊者一般通過留言、電子郵件或其他途徑向受害者發(fā)送一個精心構(gòu)造的惡意URL,當(dāng)受害者在Web瀏覽器中打開該URL的時侯,惡意腳本會在受害者的計算機上悄悄執(zhí)行,其流程如圖所示:
    圖片描述

未便于理解進行了分類歸納:

  • 反射型XSS(也叫非持久型XSS)
1
發(fā)出請求時,XSS代碼出現(xiàn)在URL中,作為輸入提交到服務(wù)端,服務(wù)端解析后響應(yīng),在響應(yīng)內(nèi)容中出現(xiàn)這段XSS代碼,最后瀏覽器解析執(zhí)行。這個過程就像一次反射,故稱為反射型XSS。
  • 存儲型XSS(也叫持久型XSS)
1
存儲型XSS和反射型XSS的差別僅在于:提交的XSS代碼會存儲在服務(wù)端(不管是數(shù)據(jù)庫、內(nèi)存還是文件系統(tǒng)等),下次請求目標(biāo)頁面時不用再提交XSS代碼。
  • DOM XSS
1
DOM XSS的XSS代碼并不需要服務(wù)器解析響應(yīng)的直接參與,觸發(fā)XSS靠的就是瀏覽器端的DOM解析,可以認為完全是客戶端的事情。

常見危害例舉
掛馬

  • 盜取用戶Cookie
  • DoS(拒絕服務(wù))客戶端瀏覽器
  • 釣魚攻擊,高級釣魚技巧
  • 編寫針對性的XSS病毒
  • 刪除目標(biāo)文章
  • 惡意篡改數(shù)據(jù)、嫁禍、“借刀殺人”
  • 劫持用戶Web行為,甚至進一步滲透內(nèi)網(wǎng)
  • 蠕蟲攻擊
  • 蠕蟲式掛馬攻擊、刷廣告、刷流量、破壞網(wǎng)上數(shù)據(jù)......

實戰(zhàn)

通過案例進行講解

利用本地存儲功能

在使用搜索功能時發(fā)現(xiàn)信息存在"駐留"現(xiàn)象
圖片描述

  • 打開瀏覽器調(diào)試工具分析
    元素
    圖片描述
    查看js代碼
    圖片描述
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$('.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ù)存儲在localStorage

圖片描述

  • 輸入js語句進行xss測試
1
<script>alert("xss測試")</script>

圖片描述

  • 搜索執(zhí)行查看
    再次搜索成功調(diào)用并按js執(zhí)行了所輸入內(nèi)容
    圖片描述

簡單閉合標(biāo)簽逃逸

圖片描述
發(fā)現(xiàn)輸入的數(shù)據(jù)有駐留但在標(biāo)簽內(nèi)

  • 查看js
    圖片描述
1
2
3
4
5
6
7
8
9
10
11
$('.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)
  • 輸入測試
    圖片描述
  • 輸入特殊字符閉合標(biāo)簽
    閉合成功,輸入內(nèi)容以js代碼形式執(zhí)行
    圖片描述
    分析:
    輸入"> 閉合了標(biāo)簽<a 并使之后的數(shù)據(jù)可不在標(biāo)簽內(nèi)顯示
    圖片描述

添加事件進行逃逸

正常測試,查看元素
圖片描述

  • 查看js
    圖片描述
1
2
3
4
5
6
7
8
9
10
11
12
$('.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ù)存儲在<a標(biāo)簽href屬性內(nèi)
  • 閉合并添加事件
    圖片描述
    分析:
    需閉合標(biāo)簽并逃逸herf屬性
1
2
<a> 標(biāo)簽的 href 屬性用于指定超鏈接目標(biāo)的 URL。
href 屬性的值可以是任何有效文檔的相對或絕對 URL,包括片段標(biāo)識符和 JavaScript 代碼段。如果用戶選擇了 <a> 標(biāo)簽中的內(nèi)容,那么瀏覽器會嘗試檢索并顯示 href 屬性指定的 URL 所表示的文檔,或者執(zhí)行 JavaScript 表達式、方法和函數(shù)的列表。

HTML DOM Event 對象

1
Event 對象代表事件的狀態(tài),比如事件在其中發(fā)生的元素、鍵盤按鍵的狀態(tài)、鼠標(biāo)的位置、鼠標(biāo)按鈕的狀態(tài)。

事件句柄 (Event Handlers)

1
HTML 4.0 的新特性之一是能夠使 HTML 事件觸發(fā)瀏覽器中的行為,比如當(dāng)用戶點擊某個 HTML 元素時啟動一段 JavaScript。下面是一個屬性列表,可將之插入 HTML 標(biāo)簽以定義事件的行為。

圖片描述
事件通常與函數(shù)結(jié)合使用,函數(shù)不會在事件發(fā)生前被執(zhí)行!
onmouseover 事件會在鼠標(biāo)指針移動到指定的對象上時發(fā)生

1
2
3
4
5
6
7
支持該事件的 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>

打破長度

  • 輸入測試
1
"><script>alert(1)</script>

圖片描述
測試發(fā)現(xiàn)輸入內(nèi)容被過濾
換測試代碼

1
" onclick="alert(1)

圖片描述
未過濾但未成功閉合

  • 查看代碼
    圖片描述
    事件沒有完全閉合后面(多了:content)
    *"閉合測試
    圖片描述
  • 深入測試
    圖片描述
    發(fā)現(xiàn)對代碼輸入的長度進行了限制
  • 分析前端代碼
    圖片描述
1
2
3
4
let query = getParam('query')||''
if (query){
query=query.replace(/<|>|script/g,'').substring(0, 33)
看到使用了query參數(shù),其值為getParam('query')
  • getparam()函數(shù)分析
    圖片描述
1
2
3
4
5
6
function getParam(name) {
if (location.search!=''){
let param = new URLSearchParams(location.search)
return decodeURI(param.get(name))
}
若鏈接中存在參數(shù),則創(chuàng)建一個對象,值為所有參數(shù),name對應(yīng)參數(shù)名
  • 測試
1
"%20onclick="eval(getParam(Test))"&Test=其它代碼

圖片描述
成功引用。已打破輸入長度限制

拼接繞過

  • 測試
1
"" onclonclickick="alert(1)"

圖片描述
被過濾,發(fā)現(xiàn)onclick被過濾成立空字符

  • 拼接
1
"" onclonclickick="alert(1)"

過濾一個在加一個
圖片描述
測試成功

參考資料

  • 《JavaScript 教程》
  • 《Web前端黑客技術(shù)揭秘》
  • 《XSS跨站腳本攻擊剖析與防御》
?

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册