您好,登錄后才能下訂單哦!
如何解析WordPress-5.1.1-CSRF-To-RCE安全事件,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
2019 年 3 月 13 號,RIPS 又放了一個 WordPress 的 CSRF,與此同時 WordPress 官方也提交相應的 Commit,算是一個比較新的洞。問題出在文章的評論上,其實是有防 CSRF 相應的 wpnonce,熟悉 wp 的人肯定不會陌生 wpnonce,這是 wp 的防御機制,動作和postid構成的token,用來驗證reference,而且 wordpress 對標簽的過濾機制比較嚴格的。白名單機制,列如 a 標簽的名單為:
看起來是比較嚴格的,基本帶動作的標簽不可能出現,插不進 js。比較有趣是兩個對評論的 filter 組合起來造成了,a 標簽中的屬性逃逸。RIPS 文章也說的比較簡單,接下來看看具體的實現過程,其實存在利用條件的,RIPS 也沒有指出來,總結時詳細說明。
1.2.1 漏洞描述
漏洞存在于 5.1.1 之前的 WordPress 版本中,可以使用默認設置進行利用。
根據其 WordPress 官方下載頁面,超過 33%的互聯網網站正在使用 WordPress。文章評論是博客的核心功能并且默認情況下已啟用,該漏洞會影響數百萬個網站。
1.2.2 受影響版本
WordPress <= 5.1.1
Kali 4.19.0 WordPress 5.1.1
環境最新是 5.1.1 昨天才官方剛 commit 的修復過程,算是比較新。既然是是 CSRF,表單提交點在于每篇文章的評論處。wp-comments-post.php:25, wp_handle_comment_submission(wp_unslash( $_POST )),進入 comment_handler 函數 做了一些簡單的賦值過程:
來看看上面對于用戶身份判斷的過程。評論需要用戶為登錄態。關鍵處:
其中判斷用戶能否不需要過濾 html,到下面的判斷提交 comment 過程中的 wpnonce 驗證,若是沒有通過身份驗證會重新定義kses 處理過程的中的 filter,具體看一下 kses_init_filters
這里為什么會重新刪減 filter,在前面初始化的過程中在init標簽的注冊了一個 kses_init()
僅僅判斷通過用戶身份 Session 身份判斷了,需不要添加過濾 html 的 filter。管理員用戶在操作的時候,即默認是沒有插入對 pre_comment_content 的過濾 html 的鉤子,但是在判斷添加評論的時候又因為在想要的 wpnonce 驗證不通過的時候,又添加上了相應的 filter,官方還是考慮到了相應的安全問題,但是為什么又要加一層身份判斷,添加不同的處理函數呢,直接插入 wp_filter_kses 不好嗎?
正是因為 wp_filter_kses 和 wp_filter_post_kses 不同上造成了后面的 js 執行 他們的不同在于過濾的嚴格度上,其實都一樣是白名單過濾。但是跟 pre_comment_content 的鉤子函數組合起來,就發送了屬性逃逸。
看一下這個兩個函數的定義。
傳入的第二參數不同,決定了后面允許使用的標簽和屬性的白名單不同。影響第二個鉤子函數。即使這里 addslashes 轉義了字符內容,緊接著下一個鉤子涉及到對屬性的處理,會恢復被轉義字符內容。
pre_comment_content 標簽的鉤子有默認的 4 個鉤子 (我習慣叫鉤子函數),分別是 convert_invalid_entities,wp_targeted_link_rel,wp_rel_nofollow,balance 根據優先級排序。第一個把€ 及以后的實體轉成相應的合法的 unicode 實體,第二個處理 a 標簽 中target屬性的,第三個是重點了兩個重要鉤子中的第二個,給 a 標簽添加 rel 屬性為 nofollow,如果存在 rel 屬性則在其屬性值中添加 nofollow,并去掉原來的 rel 屬性值,其過程會重新拼接 a 標簽。
wp_rel_nofollow 鉤子在 pre_comment_content 中優先級為 15,當插入 wp_filter_post_kses 鉤子時使用的默認值是 10,在 wp 中執行鉤子時會有優先級判斷,剛好 wp_filter_post_kses 也在前,所以也不涉及到對后面溢出的屬性重新處理。
前面說了 wp_filter_post_kses 和 wp_filter_kses 的不同在于使用的白名單不同。前者傳入的是 post,后者傳入是 current_filter(), 這個值很好理解,這一系列鉤子都在 pre_comment_content 標簽下。所以理所當然是 pre_comment_content, 選擇過程如下:
看當 post 的情況下,默認是沒有注冊 wp_kses_allowed_html 標簽的,即每一步的 apply_filters() 返回輸入的第一個值,post 的$allowedpostags 包含的標簽及其屬性是比較多的,pre_comment_content 只能走到默認 $allowedtags. 其中\$allowedtags 包含情況如下:
可以看到 a 標簽中的只允許 href 和 title,而 post 的$allowedpostags 是允許包含 rel 屬性的
在第二部重要的鉤子 wp_rel_nofollow 中,其中存在 rel 屬性時才會去重新拼接,造成額外的屬性溢出。所以這就是差異之處,確實考慮到了XSS的執行,都是用的白名單,但經過重新拼接會出現額外的屬性。列如
<a title= ' maple " onmouseover=alert(1) id=" ' rel="anything">,通過拼接變成<a title = " maple" onmouseover=alert(1) id="" rel ="anythingnofollow">。
在后面的過程中屬性里面的特殊字符會被轉義成實體。涉及到寫 js 的可能需要繞一下不能用引號和雙引號,可以這樣繞一下:
playload 如下:
其實這個洞再利用條件的有一定限定 RIPS 也沒有指出來,我在剛做時候,我添加了一個評論,我沒有去文章頁面看,我去的后臺管理界面評論管理處看,發現并沒有出現xss的情況,我很詫異不應該是一樣嗎?而后發現在輸出評論前
進行了標簽為comment_text的過濾器,其中包含了wp_kses_post 鉤子 這也是為什么后臺不行。但是應該這個思路,文章顯示處也肯定用了這個標簽的過濾器,但是理論上是沒有使用的,因為使用以后溢出的屬性會被過濾掉。
在仔細跟一下,發現確實有存在使用這個標簽的情況,對 comment_text 過濾器的使用在 check_comment() 中
是個判斷,看到這里你是否明白了這個使用的限定的條件?也就是說用戶評論自己的文章時是不需要 check 的,所以這里存在一定使用條件,在進行添加評論的時候必須是管理員發布的文章才行。
這個洞其實一眼真的很難看出來。白名單驗證,直接就放棄了。可不曾想存在一個弄巧的鉤子。
官方修復在驗證wpnonce 不成立時給強制加了 wp_filter_kses 完全限定死了。當然了這個 csrf 依然存在。因為涉及到 wp 的特性pingback/trackback。總的來說還是非常細節的,在挖洞只能拼細節在這種流行的框架下。
wp 默認是開啟自動更新的,最新版本中已經得到修復,若關閉自動更新的環境,請及時檢查更新。 https://wordpress.org/news/2019/03/wordpress-5-1-1-security-and-maintenance-release/
可手動修復:
看完上述內容,你們掌握如何解析WordPress-5.1.1-CSRF-To-RCE安全事件的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。