<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/web/13124

            0x00 背景


            憑借烏云漏洞報告平臺的公開案例數據,我們足以管中窺豹,跨站腳本漏洞(Cross-site Script)仍是不少企業在業務安全風險排查和修復過程中需要對抗的“大敵”。

            XSS可以粗分為反射型XSS和存儲型XSS,當然再往下細分還有DOM XSS, mXSS(突變XSS), UXSS(瀏覽器內的通用跨站腳本)。其中一部分解決方法較為簡便,使用htmlspecialchars()對HTML特殊符號做轉義過濾,經過轉義的輸入內容在輸出時便無法再形成瀏覽器可以解析的HTML標簽,也就不會形成XSS漏洞。

            p1 (圖:htmlspecialchars函數的轉義規則)

            但網站做大了,總有一些業務,比如郵件內容編輯、日志帖子類編輯發布等功能時,需要授權給用戶自定義鏈接、改變字體顏色,插入視頻圖片,這時就不得不需要需要引入HTML富文本實現相應功能。之前提到,htmlspecialchars()這樣把所有特殊符號做轉義處理的過濾辦法,這是就英雄無用武之地,因為HTML標簽全部被過濾了,那之前提到的這些用戶可以自定義功能又該如何實現?

            一個問題總有它的解決辦法,所以基于白/黑名單防御思想的富文本內容過濾器應運而生,并很快被應用到了對抗富文本存儲型XSS的前沿。它的任務就是根據內置的正則表達式和一系列規則,自動分析過濾用戶提交的內容,從中分離出合法和被允許的HTML,然后經過層層刪除過濾和解析最終展示到網頁前端用戶界面來。這樣既不影響網站的安全性,也不會妨礙到用戶自定義富文本內容功能的實現。

            道高一尺魔高一丈,經過一些前期的手工測試和側面從烏云公開的漏洞報告中了解,大多數網站的富文本過濾器采用“黑名單”的設計思想。這也為我們使用模糊測試來自動化挖掘富文本存儲型XSS提供了可能性。

            p2 (圖:某國內知名郵箱的富文本過濾器基于“黑名單”設計邏輯)

            與此同時,本文的主角,“強制發掘漏洞的利器”-- 模糊測試(Fuzzing Test),相信各位一定不會陌生。無論是在二進制還是在WEB端的黑盒測試中都有它立功的身影,從客戶端軟件漏洞的挖掘到WEB端弱口令的爆破,本質上都可以認為是一種模糊測試。

            結合富文本過濾器“黑名單”的實現邏輯,接下來,本文將主要探討這類富文本存儲型跨站腳本的模糊測試之道。將模糊測試這一強大的漏洞挖掘武器通過精細的打磨,挖掘出大量的潛在缺陷。

            0x01 找準目標,事半功倍


            要進行模糊測試,首先要找準目標。知道目標有哪些地方有富文本編輯器,又有哪些種類,進一步推測其是否基于“黑名單”思想,是否可以進行自動化的模糊測試。才可以讓我們接下來要進行的模糊測試,發揮出事半功倍的效果

            并不是所有允許用戶提交自定義內容的地方,都允許用戶自定義富文本,如果網站已經在后端對所有提交的內容做了htmlspecialchars()的過濾,就意味著所有提交的內容都會被轉義,也就不存在模糊測試的必要了。比如:

            p3

            烏云漏洞報告平臺的評論回復區域,后端的實現邏輯就是不允許用戶傳入富文本內容,對所有用戶輸入的內容做了htmlspecialchars()的過濾。也就是說,如果你傳入類似:

            #!js
            <script>alert(1);</script>    =>  &lt;script&gt;alert(1);&lt;/script&gt;&nbsp;
            

            這時無論你使用何種高大上的XSS Vector,都無濟于事,被轉義以后的內容,無法對構成XSS跨站腳本。

            富文本編輯器也分很多種,比如基于HTML標簽形式的富文本編輯器(Ueditor、Fckeditor),自定義富文本標簽形式(Markdown, UBB),在國內外各大網站都有使用。模糊測試萬變不離其宗,你有了一把鋒利的斧頭,你無論用什么方式砍柴,本質相同。只是有時候是類似Ueditor的編輯器,在進行模糊測試的時候,可能會更加方便容易。

            p4 (圖:百度Ueditor)

            0x02 模糊測試框架


            就好像寫字之前你必須有一只筆,砍柴前必須有一把斧子一樣,在開始針對富文本過濾器展開模糊測試之前,你必須得有一個可以自動生成Payload的模糊測試框架。無論使用JavaScript、PHP、Python還是更加小眾亦或是高級的語言,模糊測試框架的中心思想就是,通過拼接思想動態生成大量的供模糊測試使用的Payload。對網站富文本編輯器的模糊測試,稍不同于對瀏覽器XSS Filter或者是對DOM特性的模糊測試,不過我們還是可以參考一些已經在互聯網上公開的XSS Filter Fuzzer的現成代碼,加以修改,為我所用,這里就不再贅述。

            所以,在開始更深一步的模糊測試方案設計之前,請選擇自己得心應手的一種程序設計語言,參考現成的XSS Filter Fuzzer,編寫出一個或簡單或復雜的模糊測試框架。

            p5 (圖:基于拼接思想動態生成XSS Fuzzing Test Payload的框架代碼)

            0x03 模糊測試模板


            有了框架,就好比有了手槍,現在我們需要給它裝上“子彈”-- 模糊測試模板。一個模糊測試模板的好壞,很大程度上決定了,之后我們是否能夠高效的測試出富文本編輯器中潛在的缺陷,從而發掘出大量的存儲型XSS構造姿勢。而在設計自己的模糊測試模板時,主要需要考慮三點:邊界、進制編碼和字符集。

            先來說說邊界問題。以下面簡單的HTML代碼為例:

            #!html
            <span class=”yyy onmouseover=11111” style="width:expression(alert(9));"></span>
            

            上述HTML標記語言文本傳給后端富文本編輯器的時候,程序會如何過濾和解析?也許是這樣的:首先匹配到<span,進入其屬性值過濾的邏輯,首先是否含有高危的on開頭的事件屬性,發現存在onmouseover但被”,”包裹,作為class屬性的屬性值,所以并不存在危險,于是放行;接著分析style屬性,其中有高危關鍵詞”expression()”,又有括弧特殊符號,所以直接清除過濾。

            上述過濾流程的實現,很大程度依賴于后端通過正則匹配進行的HTML標簽中的邊界分析。通過對“邊界”的判定,類似class=”yyyy onmouserover=11111” 的屬性及其值才會被放行,因為雖然onmouserover=11111雖然是高危的事件屬性,但存在于=””中,沒有獨立成一個HTML屬性,也就不存在風險。所以在上面的例子中,=””就是邊界,<span中的尖括號也是邊界,空格也可以說成一種邊界。所以,形象一點說,一段HTML代碼的邊界位置很有可能是下面這樣的:

            #!html
            [邊界]<span[邊界]class=[邊界]yyy[邊界]>[邊界]</span[邊界]>
            

            所以如果是類似style="width:expr/*”*/esion(alert(9));"屬性和屬性值呢?程序又該如何確定邊界?是style="a:expr/*”還是style="a:expr/*”*/ession(alert(9));"?

            當后端富文本過濾程序遇到這樣,略微復雜的選擇題時,如果其后端規則設計的過于簡單,就很有可能導致把不該過濾的過濾掉,而把非法的內容放行,從而我們可以構造出存儲型XSS。打亂HTML邊界,讓后端富文本過濾器陷入選擇窘境,這是我們設計模糊測試模板的原則之一。有哪些內容可能會導致富文本內容過濾器出現邊界判斷問題?

            (1)特殊HTML符號,通過這類明顯的符號,過濾器就可以到HTML標簽及其屬性,但這些符號錯誤的時候出現在了錯誤的地點,往往會釀成大禍,如:

            =, ”, ’, :, ;, >, <, 空格, /,
            

            (2)過濾器會過濾刪除的內容,我們在邊界填充下面這些元素,過濾器盲目刪除,很有可能導致原本無害的屬性值,掙脫牢籠,成為惡意的屬性和屬性值,如:

            expression, alert, confirm, prompt, <script>,<iframe>
            

            (3)不可打印字符,如:

            \t、\r、\n、\0等不可打印字符
            

            綜上,現在我們已經可以用Fuzzer生成一個下面這樣的Payload。幸運的話,或許已經可以繞過一些后端邏輯簡單的富文本過濾器了,示例如下:

            #!html
            <<<span/class=/yyyy onmouseover=11111/style="a:exp/*”>*/resion(1);"></span>
            

            當然,除了邊界區分問題,富文本過濾器面對著另外兩個勁敵,特殊的進制字符編碼和千奇百怪的字符集。

            我們先來說說字符編碼,類似\x22,\40,&#x22;等一系列進制編碼,直接當作文本內容傳遞給后端富文本過濾器,如果處理的辦法?解密后過濾?直接輸出?經驗告訴我們,不少過濾器在處理類似特殊的進制編碼時,往往會在進制編碼的特殊HTML符號面前摔個人仰馬翻。于是,像下面這樣一段看似無害化的Payload,在富文本過濾器自作聰明的解密過后,變成了一段跨站腳本:

            #!html
            前:<span class=”yyy &#x22;onmouseover=alert(1);//”></span>
             =>
            后:<span class=”yyy“ onmouseover=alert(1);//”></span>
            

            接下來,我們再來說說千奇百怪的字符集,不少富文本編輯器在處理類似“祝”的unicode字符時,會將字符轉化成<img>標簽,所以在mramydnei報告的一個騰訊郵箱存儲型XSS中,一段無害的Payload逆襲成了有害的跨站腳本:

            #!html
            前:<style x="祝" y="Fuzzitup {}*{xss:expression(alert(document.domain))}">
             =>
            后:<style x="<IMG src=" https:="" res.mail.qq.com="" zh_cn="" htmledition="" images="" emoji32="" 3297.png"="">" y="Fuzzitup {}*{xss:expression(alert(document.domain))}"></style>
            

            0x04 模糊測試實戰


            正所謂“磨刀不誤砍柴工”,在進行模糊測試實戰之前,我建議,對富文本過濾器的大改過濾規則和實現原理手動測試一番,了解哪些HTML標簽允許被使用,有哪些關鍵詞出現就會被刪除,又有哪些Payload會觸發網站存在的WAF,在之后的測試中,針對目標網站“個性化”的修改模糊測試模板。

            講到這里,相信你已經大概了解富文本跨站腳本模糊測試了,不過模糊測試的威力究竟如何呢?我們用實例來做論證:

            0x05 寫在最后


            模糊測試只是自動化強制發現漏洞的一個重要手段,就像自動化漏洞掃描器一樣。我們并不能完全依靠它,在測試過程中,對過濾器結果進行適時的分析,對模糊測試模板做出合理的改進,不僅能提高模糊測試的效率,還能夠幫助我們挖掘到更多潛在的設計缺陷。畢竟,機器終究是“死板”的,而人是“靈活”的。

            富文本跨站腳本測試之道,就是細致的模糊測試結果分析,加上對模糊測試模板的不斷打磨,人與機器的結合,才會打造出一把真正的“神器”。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线