轉自:Baidu Security Lab Xteam http://xteam.baidu.com/?p=177
漏洞概述
本次漏洞出現兩個使用不同方式截斷來實現的存儲型xss,一種為特殊字符截斷,一種為數據庫字段長度截斷,該漏洞導致攻擊者可獲取用戶 cookie以及模擬浏覽器正常操作,並且當管理員訪問到注入的payload時,結合wordpress後台功能甚至可以getshell。
漏洞分析
1.字符截斷 通過官網介紹“The character set named utf8 uses a maximum of three bytes per character and contains only BMP characters. ”,mysql在使用utf8的時候,一個字符的大小的上限為3字節,而當出現四個字節的字符時,是需要用使用utf8mb4編碼,不使用的話,會將不識 別的四字節的字符連同後面的字符串一同捨棄。示例如下,使用特殊字符UPDATE `wp_comments` SET `comment_content` = 'stefanie特殊字符555555555555555 ' WHERE `wp_comments`.`comment_ID` =12;執行結果,可以看出,後面的55555555已經被截斷,並未插入數據庫。 UTF-8編碼在對於不同的字符區域,編碼所占用的字節數各不相同,當然我們重點關注占用4字節的范圍 通過剛剛對於官網的說明的理解,mysql utf-8編碼對於占用四個字節的字符無法識別,那麼這一部分占用字節編碼的區域,插入數據庫時可以與符號產生同樣的效果,在該范圍中隨機進行測試發現,均產生截斷效果,如,,等,如需完整驗證猜想,可對針對圖中范圍進行FUZZ。 當mysql數據庫的編碼為utf-8mb4或者latin1時,是不存在該問題的,因為這兩種字符集對該類字符可以進行正常識別,不會產生截 斷效果,另外,當mysql開啟strict mode時候,會更加嚴格地處理,確保在數據有效存儲之前進行阻止,也就不會產生該問題。 2 超過長度截斷 mysql type=TEXT時,TEXT的最大長度為64kb,當發生數據庫的插入操作時,則會將大於64KB的部分拋棄,只插入前64KB,此時也造成了一種截斷。 而wordpress保存評論的字段的type正是TEXT 3 漏洞利用 wordpress中,對於匿名評論內容中的標簽以及屬性,會按照白名單進行過濾,如下所示。 \wp411\wp-includes\kses.php 419行
$allowedtags = array( 'a' => array( 'href' => true, 'title' => true, ), 'abbr' => array( 'title' => true, ), 'acronym' => array( 'title' => true, ), 'b' => array(), 'blockquote' => array( 'cite' => true, ), 'cite' => array(), 'code' => array(), 'del' => array( 'datetime' => true, ), 'em' => array(), 'i' => array(), 'q' => array( 'cite' => true, ), 'strike' => array(), 'strong' => array(), );wordpress只會允許白名單中的標簽出現,而在每個以標簽名作為數組名的數組中,保存的是該標簽下所允許出現的屬性。 正常情況是不允許類似於onmouseover之類的屬性出現的,我們使用poc進行測試
<abbr title=”123 onmouseover=alert(1) 特殊字符”>
在IE下面提交評論後可以發現,成功彈窗,代碼如下圖 可以看出,在poc中,onmouseover是在雙引號內作為title屬性的值出現的,而當特殊字符起到了截斷的作用之後,該條評論的內容在數據庫中保存如下 其中左邊的雙引號在輸出的時候,會被替換,而另外一個包裹onmouseover的雙引號被截斷未存入數據庫,此時的onmouseover成功變成了一個未在白名單允許范圍之內的事件,並且被成功解析。 而用超過固定長度來構造截斷與此同理。
<abbr title=”123 onmouseover=alert(1) 此處增加無用字符至64KB “>
此時則成功將右邊的雙引號和尖括號截斷,導致其並未進入數據庫,如下圖所示
漏洞利用
Klikki Oy團隊給出了兼容多種浏覽器的POC,chrome,IE,firefox測試成功 sssss<a title=’x onmouseover=alert(unescape(/hello%20world/.source))style=position:absolute;left:0;top:0;width:5000px;height:5000px 此處用特殊字符或者長度截斷均可’></a>
結合此poc,引用外部js,利用wordpress管理員在後台編輯模板的功能,可進行自動化的getshell,之前爆出wordpress xss時已有人發出,此處不再贅述
漏洞影響范圍
特殊字符截斷影響版本:WordPress < 4.1.2 (需要mysql使用utf8字符集且strict mode關閉) 超過長度截斷影響版本:WordPress < =4.2 此次漏洞利用的為mysql的特性,其他使用mysql的cms可能也會出現類似問題。
攔截建議
waf對兩種xss攔截,建議如下: 1 字符截斷:針對評論請求中帶有圖中范圍內的字符,予以攔截 2 長度截斷: 評論請求超過64KB予以攔截 具體情況還請waf同學斟酌
修復建議
針對超長截斷,官方暫未給出補丁,所以建議臨時關閉評論功能,防范此次的xss -------------我的總結-------------- 1. mysql字符編碼最好采用utf-8mb4(或latin1) 2. mysql一定采用strict mode(mysql5.7好像已經是默認嚴格模式了) 3. 長度超過,程序就應該進行處理,所以還是程序寫的不嚴謹 4. XSS 白名單 5. 該攻擊的原理是,利用mysql在處理特殊字符和超長字符時,其會進行截斷,所以導致了最後的 " 被截斷了,導致了引號"沒有被關閉,所以導致了浏覽器將標簽的屬性當成了js代碼來執行。 6. <abbr title=”123 onmouseover=alert(1) 在輸出時,沒有進行html編碼,將<編碼成< ,onmouseover,alert等在輸入時沒有進行過濾。 7. 存儲型XSS,需要鼠標移動到上面才會觸發。