轉自: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;執行結果
$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下面提交評論後可以發現,成功彈窗,代碼如下圖
<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,需要鼠標移動到上面才會觸發。