wordpress<4.7.1 远程代码执行漏洞分析

前言

作者:血魂

声明

1.这个漏洞涉及到了phpmailer命令执行漏洞(CVE-2016-10033),对于这个漏洞我没写过漏洞分析,做这个漏洞分析的时候就大概的看了一下,先在这里留个坑把,以后有时间在补上phpmailer命令执行漏洞(CVE-2016-10033)的漏洞分析
2.这个漏洞的漏洞思路我个人觉得反向看,思路会比较清晰,所以漏洞思路那一块是反向分析的,但是在下面的具体漏洞分析我是正向分析的
3.我会尽量将每个函数的代码贴出来,保证完整性(会有很多和漏洞无关代码,不过分析过程中关键代码我会说明行数),但是有些函数代码太长,实在不方便截全图,就只截了相关代码。
4.因为我个人习惯把关键代码贴到notepad++分析,为了方便阅读,提到的代码行数都是notepad++里的,在源码相应的代码行数我会在后面括号里附上
5.这篇文章是学习代码审计总结笔记,如果有错误和改正之处还望不吝赐教(强烈欢迎批评指正)
6.如转载(或其它),请标注作者,不胜感激
7.本篇漏洞分析借鉴了http://blog.nsfocus.net/wordpress-4-6-implementation-vulnerability-analysis/的审计思路

漏洞涉及版本

小于wordpress v4.7.1版本

漏洞涉及地址

Wp-login.php文件:根目录
retrieve_password函数:Wp-login.php文件
get_user_by函数:wordpress/wp-includes/pluggable.php
get_data_by函数:wordpress/wp-includes/class-wp-user.php
wp_mail函数:wordpress/wp-includes/pluggable.php
Setfrom函数:wordpress/wp-includes/class-phpmailer.php
Send函数:wordpress/wp-includes/class-phpmailer.php
Postsend函数:wordpress/wp-includes/class-phpmailer.php
mailSend函数:wordpress/wp-includes/class-phpmailer.php
Mailpassthru函数:wordpress/wp-includes/class-phpmailer.php

整体思路

这个漏洞的问题出在再mailPassthru中将可控变量传入给了@mail导致的漏洞,而传递进去的可控变量params的值是我们在setFrom函数设置的$this->Sender,而$this->Sender的值是我们在wp_mail函数中传递进来的参数SERVER_NAME的值拼接出来的。所以我们需要向办法调用wp_mail函数。而在wp-login.php文件中,会接收action参数,当传递进来的action参数的值为lostpassword时会调用retrieve_password函数,而在这个函数中会接收我们传递进来的user_login参数并通过get_user_by函数来查询相关信息,而其中一条user_mail的信息会被传递进wp_mail函数,也就是我们想要调用的函数,所以我们传递进来的user_login参数也就是用户名得是存在的,才能查出user_mail信息从而调用wp_mail函数。

漏洞分析

wp-login.PNG
wp-login2.PNG
wp-login3.PNG
上面是wp-login.php文件部分代码,我们可以看到在第4行(源码390行)接收了参数action,而在代码的56行(源码439行)判断了action的值,在代码的116行(源码499行),当action的值为lostpassword时执行下面的代码,而下面的代码在120行(源码503行),我们可以看见调用了retrieve_password函数,我们跟进
retrieve_password.PNG
retrieve_password2.PNG
retrieve_password3.PNG
retrieve_password函数代码如上,这里我贴出了retrieve_password函数全代码,我们看第7行(源码298行),接收了user_login参数也就是用户名在第18行(源码306行)传递给了get_user_by函数,我们看看这个函数
get_user_by.PNG
get_user_by函数调用了get_data_by函数,我们同样看看这个函数
get_data_by.PNG
get_data_by2.PNG
代码如上,这个函数就是调用了wp_cache_get函数对用户信息进行了查询和调用,wp_cache_get函数就不继续跟了,我们已经明白了get_user_by函数干了什么。我们在回到retrieve_password函数,继续往下看代码,在代码的43行$user_email = $user_data->user_email;我们看到将用户信息的user_email赋值给了变量,我们继续往下,在代码93行(源码330行)我们看到将user_email变量传递给了wp_mail函数,到这里我们知道,我们传递进来的user_login参数也就是用户名得是存在的才能走到wp_mail函数。我们接着看wp_mail函数
wp_mail.PNG
Wp_mail函数代码较长,我就只截了关键代码,我们看代码155行(源码326行)接收了SERVER_NAME参数在163行(源码331行)经过拼接赋值给了from_email变量,是可控的,而from_email变量在184行(源码352行)代码被传递进了setFrom函数,我们跟进
setfrom.PNG
setFrom函数代码如上,我们知道address变量,也就是我们传递进来的第一个参数from_email变量是可控的,而在setFrom函数代码74行(源码954行)被赋值给了$this->Sender。我们继续回到wp_mail函数看如下代码
wp_mail2.PNG
上面代码是wp_mail函数的一部分,我们看到在303行(源码471行)调用了send函数,我们跟进这个send函数
send.PNG
Send函数代码如上,在代码的88行调(源码1125行)用了postSend函数,我们继续跟
postsend.PNG
postSend函数代码如上,在105行(源码1240行)判断了$this->Mailer的值,而我们调用的是系统的mail,所以会在112行(源码1247行)进入mailSend函数,我们跟进
mailSend.PNG
mailSend函数代码如上,在第25行(源码1368行)我们看到params变量进入了mailPassthru函数,而params变量的值在第15行(源码1355行)我们可以看到是$this->Sender也就等于from_email变量是可控的,我们继续看mailPassthru函数
mailpassthru.PNG
mailPassthru函数代码如上,在56行(源码677行),我们看到params变量作为第5个参数进入了@mail,导致了漏洞产生。
至此漏洞分析完。
为什么params变量作为第5个参数进入了@mail,会导致了漏洞产生,请回顾一下phpmailer命令执行漏洞(CVE-2016-10033),有时间我再来补坑。

添加新评论