Wordpress未授权查看私密内容漏洞 分析(CVE-2019-17671)
目录
0x00 前言
没有
0x01 分析
这个漏洞被描述为“未授权访问私密内容”,由此推断是权限判断出了问题。如果想搞懂哪里出问题,必然要先知道wp获取page(页面)/post(文章)的原理,摸清其中权限判断的逻辑,才能知道逻辑哪里会有问题。
这里我们直接从wp的核心处理流程main函数开始看,/wp-includes/class-wp.php:main()
public function main( $query_args = '' ) { $this->init();//获取当前用户信息 $this->parse_request( $query_args );//解析路由,匹配路由模式,取出匹配的路由中的用户输入参数(比如year,month等)赋值给$this->query_vars。(并将部分用户参数绑定到$this->query_vars中)。然后进行一些过滤操作。 $this->send_headers();//设置HTTP响应头,比如Content-Type等 $this->query_posts();//根据$this->query_vars等参数,获取posts/pages $this->handle_404(); $this->register_globals(); do_action_ref_array( 'wp', array( &$this ) ); }
$this->init()底层直接调用wp_get_current_user()获取全局变量$current_user,这是一个WP_User类,里面存储当前用户的元信息,未登录时$current_user->ID===0。
然后进入$this->parse_request,这个函数主要用于处理路由,初始化$this->query_vars。主要分为两部分来看,第一部分是处理路由,匹配rewrite路由模式。
public function parse_request( $extra_query_vars = '' ) { global $wp_rewrite; ... // Fetch the rewrite rules. $rewrite = $wp_rewrite->wp_rewrite_rules();//加载所有路由重写规则,用于与当前请求路径进行匹配 if ( ! empty( $rewrite ) ) { ... if ( empty( $request_match ) ) { ... } else { foreach ( (array) $rewrite as $match => $query ) {//匹配路由规则 ... if ( preg_match( "#^$match#", $request_match, $matches ) || preg_match( "#^$match#", urldecode( $request_match ), $matches ) ) { ... // Got a match. $this->matched_rule = $match;//找到匹配成功的rewrite规则,立即break break; } } } if ( isset( $this->matched_rule ) ) { ... $query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) );//规则化用户请求url,以与路由进行完美对应 $this->matched_query = $query; // Parse the query. parse_str( $query, $perma_query_vars ); ... } ... }
第二部分,解析用户参数,配置$this->query_vars的值
class WP{ ... public $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order',