Skip to content

代码审计 BEESCMS

字数
1034 字
阅读时间
5 分钟
更新日期
7/15/2017

0x01 前言

跟着@Joseph 大牛学习代码审计系列(J牛审计文章见:https://forum.90sec.org/forum.php?mod=viewthread&tid=10630)

author:小草

BEESCMS企业网站管理系统拥有简单方便的模板标签,能够快速做出模板;自定义表单,自定义模型,内置新闻、下载、产品、招聘、单页模型;SEO功 能,每个页面都可以单独SEO优化;多语言,多风格,每种语言每个页面都可以定义风格;html静态页面生成功能;BEES还可以自定义flash引导页。

审计的是最新版本:v4

0x02 大牛的步伐

@Joseph 大牛审计漏洞出现在了 /member/member.php 文件上,

js
if($action=='ajajx_out'){
        $sql="update ".DB_PRE."member set member_time='{$_SESSION['m_time']}',member_ip='{$_SESSION['m_ip']}' where id={$_SESSION['member_id']}";

这段代码中由于 $_SESSION['m_ip'] 的值没有过滤,由get_ip()函数获取,而get_ip()函数值可以通过 x-forwarded-for来伪造造成了注入

但是漏洞过程比较繁琐,因为出现在了会员系统上,所以还需要注册一个新用户才能触发漏洞

0x03 跟随大牛的步伐

目的:J牛的利用方法有点复杂,想找个简单点的利用方法 因为beescms系统有着全局防注入,所有get post cookies请求都会被转换,所以需要找到一个未被转换的点。 全局搜索了下get_ip()出现的地方,在mx_form\order_save.php文件出现了 这是一个订单提交处理文件,说明可以之间在前台进行利用

360截图20170713202845921.jpg

但是这个一开始就被验证码挡住了,虽然验证码没什么大问题,但想着如果能写个批量化脚本验证的话,绕过验证码岂不是要好点。虽然弄个验证码的识别很容易。

然后看了下源码,在init.php中

js
@extract($_POST);
@extract($_GET);
@extract($_COOKIE);

这不就是变量覆盖漏洞吗?

所以可以这样提交来绕过验证码

js
POST http://127.0.0.1/beescms/mx_form/order_save.php
DATA feed_code=a&_SESSION=a

还是到后面这里就不知道怎么绕过了

360截图20170713203229569.jpg

js
if(!empty($fields)){
foreach($fields as $key=>$value){
                        if(!is_array($value)){
                        if(!in_array($key,$fd)){die("223333");}
                        }
                        $sql_field.=','.$key;
                        if(is_array($value)){
                                foreach($value as $k=>$v){
                                        $value_str.=$v.',';
                                }
                                $value=$value_str;
                        }
                        $sql_value.=",'".fl_html($value)."'";                        
}
}else{
        die($language['order_msg2']);
}

可以伪造fieldsfields变量的值是个数组呢? 。。

进行到这一步戛然而止 = -

然后找了下资料,发现曾经的dedecms变量覆盖漏洞有类似的利用方法,根据它的经验

修改如下的post data

js
feed_code=a&_SESSION[code]=a&form_id=5&fields[aaa][nnn]=1111

360截图20170714165147400.jpg

成功造成了注入

0x04 后台任意登陆

既然存在变量覆盖漏洞,那么就有很多可以利用的点

在这款CMS后台中,是如何检测登陆的呢?

js
//检查登陆
if(!is_login()){header('location:login.php');exit;}

is_login() 原型方法

js
function is_login(){
	if($_SESSION['login_in']==1&&$_SESSION['admin']){
		if(time()-$_SESSION['login_time']>3600){
			login_out();
		}else{
			$_SESSION['login_time']=time();
			@session_regenerate_id();
		}
		return 1;
	}else{
		$_SESSION['admin']='';
		$_SESSION['admin_purview']='';
		$_SESSION['admin_id']='';
		$_SESSION['admin_time']='';
		$_SESSION['login_in']='';
		$_SESSION['login_time']='';
		$_SESSION['admin_ip']='';
		return 0;
	}

}

由于前面的变量覆盖漏洞,$_session可以伪造,is_login()只要判断成功,后面再无判断

0x05 后台sql注入

出现在了后台 /admin/login.php 文件中,因为没有加载init.php这个文件(init.php包含了全局防注入代码)

js
//判断登录
elseif($action=='ck_login'){
	global $submit,$user,$password,$_sys,$code;
	$submit=$_POST['submit'];
	$user=fl_html(fl_value($_POST['user']));
	$password=fl_html(fl_value($_POST['password']));
	$code=$_POST['code'];
	if(!isset($submit)){
		msg('请从登陆页面进入');
	}
	if(empty($user)||empty($password)){
		msg("密码或用户名不能为空");
	}
	if(!empty($_sys['safe_open'])){
		foreach($_sys['safe_open'] as $k=>$v){
		if($v=='3'){
			if($code!=$s_code){msg("验证码不正确!");}
		}
		}
		}
	check_login($user,$password);
	
}

所以这个文件注入就很简单了,

js
function fl_value($str){
	if(empty($str)){return;}
	return preg_replace('/select|insert | update | and | in | on | left | joins | delete |\%|\=|\/\*|\*|\.\.\/|\.\/| union | from | where | group | into |load_file
|outfile/i','',$str);
}
define('INC_BEES','B'.'EE'.'SCMS');
function fl_html($str){
	return htmlspecialchars($str);
}

fl_html是html过滤,对sql影响不大

fl_value的原型是替换掉那些关键词,但是可以构造如 anandd 等等之类的绕过

撰写

布局切换

调整 VitePress 的布局样式,以适配不同的阅读习惯和屏幕环境。

全部展开
使侧边栏和内容区域占据整个屏幕的全部宽度。
全部展开,但侧边栏宽度可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
全部展开,且侧边栏和内容区域宽度均可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
原始宽度
原始的 VitePress 默认布局宽度

页面最大宽度

调整 VitePress 布局中页面的宽度,以适配不同的阅读习惯和屏幕环境。

调整页面最大宽度
一个可调整的滑块,用于选择和自定义页面最大宽度。

内容最大宽度

调整 VitePress 布局中内容区域的宽度,以适配不同的阅读习惯和屏幕环境。

调整内容最大宽度
一个可调整的滑块,用于选择和自定义内容最大宽度。

聚光灯

支持在正文中高亮当前鼠标悬停的行和元素,以优化阅读和专注困难的用户的阅读体验。

ON开启
开启聚光灯。
OFF关闭
关闭聚光灯。

聚光灯样式

调整聚光灯的样式。

置于底部
在当前鼠标悬停的元素下方添加一个纯色背景以突出显示当前鼠标悬停的位置。
置于侧边
在当前鼠标悬停的元素旁边添加一条固定的纯色线以突出显示当前鼠标悬停的位置。