revision trick
漏洞發現者的文章最開始提到了一個revision的trick,用于承接越權寫文章之后如何繼續進行深入攻擊。但是由于這個老外隱藏了部分技巧,導致按照他文章所說的內容無法復現訂閱者賬號觸發SQL注入漏洞WordPress批量添加欄目 ,所以phithon在文章中沒有提到這個trick。我在這里本著還原作者思路的目的,向大家介紹一下關于這個trick的原理。
下面是原文關于這個trick部分的翻譯:
revisions字段用于記錄草稿或者更新的發布,Wordpress中用revisions記錄對于完成的提交和存儲都會在posts數據庫表中將post_type設置成revision,每個revision都會有一個’post_parent’字段,指明這個revision所基于的原版提交。
當嘗試編輯一個revision時,會通過post_parent來進行校驗,而不是revision本身。這樣,如果我們基于一個post創建一個revision,那么我們可以任意設置它的狀態為“trash”之外的任何狀態,即使原始的post的狀態是“trash”
使用這個trick,我們能夠編輯這個“puppet revision”(傀儡文章?)和自由的向他添加評論,即使他的原版post已經被丟棄到了垃圾箱當中。
結合我們上文的越權寫漏洞,可以看出作者提出使用這個trick的目的是為了,利用我們之前寫進垃圾箱中文章(post)的修訂版(revision)來進行編輯和評論進行操縱。因為類型為post的文章,即使是當前訂閱用戶提交的WordPress批量刪除關鍵詞 ,也是沒有權限編輯的WordPress批量上傳內容 ,而revision卻是可以編輯的。所以按照原文中所說,我們可以使用這個trick繼續后面的操作。
漏洞原因
這個漏洞其實是一個二次注入的漏洞,它的本質原因是在從垃圾箱還原文章時,也要還原文章下面的評論,而在還原評論的代碼中存在直接拼接用戶可控內容,從而導致SQL注入漏洞。下面為問題代碼:
function wp_untrash_post_comments( $post = null ) {
global $wpdb;
$post = get_post($post);
if ( empty($post) )
return;
$post_id = $post->ID;
$statuses = get_post_meta($post_id, '_wp_trash_meta_comments_status', true);
if ( empty($statuses) )
return true;
do_action( 'untrash_post_comments'WordPress批量添加產品 , $post_id );
// Restore each comment to its original status.
WordPress批量助手$group_by_status = array();
foreach ( $statuses as $comment_id => $comment_status )
$group_by_status[$comment_status][] = $comment_id;
foreach ( $group_by_status as $status => $comments ) {
// Sanity check. This shouldn't happen.
if ( 'post-trashed' == $status )
$status = '0';
$comments_in = implode( "', '", $comments );
$wpdb->query( "UPDATE $wpdb->comments SET comment_approved = '$status' WHERE comment_ID IN ('" . $comments_in . "')" );
}
clean_comment_cache( array_keys($statuses) );
delete_post_meta($post_id, '_wp_trash_meta_comments_status');
do_action( 'untrashed_post_comments', $post_id );
}
從代碼中我們可以看到$status和$comments變量的內容會拼接到SQL中,而這兩個變量的內容是用戶可以操控的。因為用戶傳入的數據會先被過濾處理后存儲到數據庫中,然后直接從數據庫提取數據進行拼接,所以如果我們的攻擊語句會在數據庫提取時恢復本來面貌——標準的二次注入。
文章地址:http://www.meyanliao.com/article/wordpress/xSQLzrld.html