• 影响条件:
  • 程序:WordPress
  • 版本:<= 1.5.1.2
  • 严重程度:高危

基础知识

想要分析这个漏洞首先要了解xmlrpc的相关知识.

什么是xmlrpc?

xml rpc是使用http协议做为传输协议的rpc机制,使用xml文本的方式传输命令和数据调用远程的方法。

用wordpress xmlrpc.php的sayHello函数来演示一个例子

发送以下的xmlrpc数据包到wordpress的xmlrpc.php路径上,wordpress就会返回返回一个xmlrpc Response

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /xmlrpc.php HTTP/1.1
Host: example.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Content-Length: 114
<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
<methodName>demo.sayHello</methodName>
</methodCall>

这是上面一个请求返回的数据包

E31985B9-FD8A-4813-B32E-5A80ABDA8DB9.png

我们可以看见在<string></string>标签中返回了一个Hello!

所以想要调用它的过程,只要遵循xmlrpc协议格式,例如以下

1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>
<methodCall>
<methodName></methodName>
<params>
<param>
<value></value>
</param>
</params>
</methodCall>

##漏洞分析正文
首先根据exp来定位漏洞点

1
2
3
4
5
6
7
8
9
<?xml version=\"1.0\"?>
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param><value><string>1'</string></value></param>
<param><value><string>http://wordpress1.5.1/?p=1#1</string></value></param>
<param><value><string>admin</string></value></param>
</params>
</methodCall>

上面这个xml文件是这个exp最核心的地方,我把原exp中填充payload的地方换成了1'

返回了如下数据,在这里可以看到返回数据库的错误提示信息

6A97CEB7-6745-48B9-BD52-E90070EC2449.png

来看一下整个执行流程

8D317E7F-120B-4BC2-94C7-98C5958030AD.png

#8中实例化了wp_xmlrpc_server()类,wp_xmlrpc_server()类是wordpress对IXR库的扩展,里面定义了wordpress xmlprc的API.

#3开始,流程就进入了wordpress所添加的api ->pingback_ping()中.

参数赋值语句

1
$pagelinkedfrom = $args[0];

args[0]哪来的?args是class IXR_Message中parse()函数处理之后返回的.

1
2
3
4
5
6
$data = $HTTP_RAW_POST_DATA;
$this->message = new IXR_Message($data);
if (!$this->message->parse()) {
$this->error(-32700, 'parse error. not well formed');
}

我把上面的代码段给摘录出来,parse()解析了标签里面的内容.

解析出来的内容也就是args[0]直接赋值给了pagelinkedfrom没有经过任何处理直接拼接进了sql语句中.

1
        $result = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post_ID' AND comment_author_url = '$pagelinkedfrom'");
导致的注入.

如果是导致数据库出错的sql语句可以看见它的内容不在xmlrpc response的标签里面

![A89E1453-DE26-4594-91A5-843C2AA7BF30.png](http://lonelyrain.me/usr/uploads/2016/06/4217694734.png)

因为调用到`this->query()`的函数中调用到了一个`$this->print_error();`函数.

这个函数是当发生数据库错误的时候显示上一条查询的sql语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        function print_error($str = '') {
        global $EZSQL_ERROR;
        if (!$str) $str = mysql_error();
        $EZSQL_ERROR[] =
        array ('query' => $this->last_query, 'error_str' => $str);
        
        // Is error output turned on or not..
        if ( $this->show_errors ) {
        // If there is an error then take note of it
        print "<div id='error'>
        <p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
        <code>$this->last_query</code></p>
        </div>";
        } else {
        return false;
        }
        }
所以说就是报错语句没有在xml里面的原因了

Comments

⬆︎TOP