大柚子

这世界不过如此

环境:

phpstudy 2018 PHP-5.5.38 apache 2.4.23

漏洞:

SQL注入

stripslashes+addslashes引起的注入

注册界面/ucenter/reg.php存在sql注入漏洞,此页面为会员注册界面,下面是部分代码:

<?php 
include('../system/inc.php');
if(isset($_SESSION['user_name'])){
header('location:index.php');
};
	
if(isset($_POST['submit'])){
$username = stripslashes(trim($_POST['name']));
// 检测用户名是否存在
$query = mysql_query("select u_id from xtcms_user where u_name='$username'");
if(mysql_fetch_array($query)){
echo '<script>alert("用户名已存在,请换个其他的用户名");window.history.go(-1);</script>';
exit;
}
$result = mysql_query('select * from xtcms_user where u_email = "'.$_POST['email'].'"');
if(mysql_fetch_array($result)){
echo '<script>alert("邮箱已存在,请换个其他的邮箱");window.history.go(-1);</script>';
exit;
}

可以看到”$username”来自POST请求包中,其中先经过”trim“和”stripslashesh”函数处理。函数方法如下:

  • trim()函数

移除字符串两侧的空白字符或其他预定义字符(默认为NULL、\t、\n、\r、空格等)。

  • stripslashesh

反引用一个引用字符串。如果 magic_quotes_sybase 项开启,反斜线将被去除,但是两个反斜线将会被替换成一个。

由此可见,$username变量经过stripslashes()和trim()函数处理后,直接拼接进查询语句中,由单引号闭合。但既然存在去除反斜杠,前面应该由addlashes()函数添加反斜杠:因此进一步追踪包含文件,../system/inc.php

逐一查看,最后在../system/library.php文件中看到:

<?php

if (!defined('PCFINAL')) {
	exit('Request Error!');
}
if (!get_magic_quotes_gpc()) {
	if (!empty($_GET)) {
		$_GET = addslashes_deep($_GET);
	}
	if (!empty($_POST)) {
		$_POST = addslashes_deep($_POST);
	}
	$_COOKIE = addslashes_deep($_COOKIE);
	$_REQUEST = addslashes_deep($_REQUEST);
}
function addslashes_deep($_var_0)
{
	if (empty($_var_0)) {
		return $_var_0;
	} else {
		return is_array($_var_0) ? array_map('addslashes_deep', $_var_0) : addslashes($_var_0);
	}
}

分析这个文件,里面自定义了addslashes_deep函数,本意是为了防止注入,对get、post传入的参数用”adddslashes()”进行了转义处理,就是对单引号(’)、双引号(”)、反斜线(\)与 NUL(null 字符)前加入反斜线。乍一看单独存在是没有问题的,但是结合之前”stripslashesh()“函数,增加在减少岂不是相当于没有。那么漏洞点就来了。

回到/ucenter/reg.php,执行查询语句后的结果给到了”$query“变量,但是这里是没有返回$query的值的,故这里的利用方式为使用时间盲注。直接sqlmap跑一波。

那么同样的思路,所有引用了”stripslashes()函数”和引用”system/inc.php”或”/system/library.php”的地方都有一样的漏洞呢?

全局搜索stripslashes,得到如下

  • active.php
  • repass.php
  • /wap/login.php
<?php include('../system/inc.php');
$op=$_GET['op'];

if(isset($_POST['submit'])){
	null_back($_POST['u_name'],'请输入用户名');
	null_back($_POST['u_password'],'请输入密码');
	$u_name = $_POST['u_name'];
	$u_password = $_POST['u_password'];
	$sql = 'select * from xtcms_user where u_name = "'.$u_name.'" and u_password = "'.md5($u_password).'" and u_status=1';
	$result = mysql_query($sql);
	if(!! $row = mysql_fetch_array($result)){
		
	$_data['u_loginnum'] = $row['u_loginnum']+1; 
	$_data['u_loginip'] =$_SERVER["REMOTE_ADDR"]; 
	$_data['u_logintime'] =date('y-m-d h:i:s',time());
	if(!empty($row['u_end'])) $u_end= $row['u_end'];
	if(time()>$u_end){
	$_data['u_flag'] =="0";
	$_data['u_start'] =="";
	$_data['u_end'] =="";
	$_data['u_group'] =1;
	}else{
	$_data['u_flag'] ==$row["u_flag"];
	$_data['u_start'] ==$row["u_start"];
	$_data['u_end'] ==$row["u_end"];
	$_data['u_group'] =$row["u_group"];
	}
	mysql_query('update xtcms_user set '.arrtoupdate($_data).' where u_id ="'.$row['u_id'].'"');
	$_SESSION['user_name']=$row['u_name'];
	$_SESSION['user_group']=$row['u_group'];
	if($_POST['brand1']){ 
setcookie('user_name',$row['u_name'],time()+3600 * 24 * 365); 
setcookie('user_password',$row['u_password'],time()+3600 * 24 * 365); 
} 
		header('location:user.php');
	}else{
		alert_href('用户名或密码错误或者尚未激活','login.php?op=login');
	}
}
if(isset($_POST['reg'])){
$username = stripslashes(trim($_POST['name']));
// 检测用户名是否存在
$query = mysql_query("select u_id from xtcms_user where u_name='$username'");
if(mysql_fetch_array($query)){
echo '<script>alert("用户名已存在,请换个其他的用户名");window.history.go(-1);</script>';
exit;
}

这几个文件中,不但有stripslashes函数,还引用了/system/inc.php文件,故存在同样的注入问题。


template/wapian/vlist.php注入

继续根据seay自动审计工具,发现vlist.php存在注入漏洞,关键代码如下:

对“$_GET[‘cid’]变量进行一个判断,不为0的时候,直接拼接到查询语句中,这里无任何防护,但进一步审查代码,也未发现输出点,sqlmap直接跑。

admin/cms_backup.php注入

关键代码如下:

在代码中可以看到,$vals变量经过array_map()函数处理后,全部经过了addlashes()转义处理来防止注入,之后经过$vals=”‘”.$vals.”‘”;语句处理,添加单引号包裹,就完全杜绝了sql注入的可能性,无法构造闭合。

Print Friendly, PDF & Email

发表回复

您的电子邮箱地址不会被公开。