审计日记2——偷懒的waf{爱频道音乐管理系统}

  我们都知道addslashes()与magic_quotes_gpc 只能对sql语句中被引号包围的部分加固安全,对于数字型的可以用intval或者(int)强制转换或者is_numric检测,但是一些php项目中,开发者没有考虑周全,导致我们可以绕过他看似坚固的WAF。

  在第一篇日记中,我们遇到了order by后注入的问题,这个是可以绕过addslashes()与magic_quotes_gpc的,同样的,$SERVER变量也可以绕过magic_quotes_gpc,这点基本都是利用伪造ip来构造注入的。看似很强大的addslashes()对于数字型的,而且没有被 '包裹的sql语句毫无作用。

  我们来看一下这个“爱频道音乐管理系统”。

 首先大致看了下对get和post数据的处理,发现基本都被一个SafeRequest函数进行处理,我们跟踪一下这个函数 

function SafeRequest($key,$mode,$isfilter=''){
	set_magic_quotes_runtime(0);
	$magic= get_magic_quotes_gpc();	
	switch ($mode){
		case 'post':
			$value=isset($_POST[$key]) ? $magic?trim($_POST[$key]):addslashes(trim(
			$_POST[$key])) : '';
			break;
		case 'posts':
			$value=isset($_POST[$key]) ? $magic?trim($_POST[$key]):addslashes(trim(
			$_POST[$key])) : '';
			$value=shtmlspecialchars($value);
			break;
		case 'get':
			$value=isset($_GET[$key]) ? $magic?trim($_GET[$key]):addslashes(trim(
			$_GET[$key])) : '';
			break;
		case 'gets':
			$value=isset($_GET[$key]) ? $magic?trim($_GET[$key]):addslashes(trim(
			$_GET[$key])) : '';
			$value=shtmlspecialchars($value);
			break;
		default:
			$value=isset($_POST[$key]) ? $magic?trim($_POST[$key]):addslashes(trim(
			$_POST[$key])) : '';
			if($value==""){
				$value=isset($_GET[$key]) ? $magic?trim($_GET[$key]):addslashes(trim(
				$_GET[$key])) : '';
			}
			break;
	}
	if($isfilter!=''){
		$value=str_encode($value);
	}
	return $value;	
}

  其中,str_encode是XSS的过滤函数(可以猜想这个程序员想一个函数用在整个系统里了)

function str_encode($str) {
	$str=ReplaceStr($str, "<", "&lt;");
	$str=ReplaceStr($str, ">", "&gt;");
	$str=ReplaceStr($str, "'", "&apos;");
	$str=ReplaceStr($str, " ", "&nbsp;");
	$str=ReplaceStr($str, "\r\n", "<br>");
	$str=ReplaceStr($str, "\"", "&quot;");
	$str=ReplaceStr($str, "&", "&amp;");
	return $str;
}

  可以看到,这个系统对于被引号包裹的sql语句有着一定的抵抗能力,然而如果是数字型的,缺完全没有抵抗能力,有了这个思路,我们就可以搜索所有数字型的注入点了。

  使用这个函数的共有2358处,带有**id我们就可以猜测是数字型的了。比如

  isNul函数

function IsNul($str) {
	if(!is_string($str))
		return false;
	if(empty($str))
		return false;
	if($str=='')
		return false;
	return true;
}

 之后就直接带入sql语句了,结果想必大家都应该知道了......

 但在审计的过程中,我又发现了一处cookie注入,这个就是根本没有过滤

if(($_COOKIE["cd_name"]<>"") || ($_COOKIE["cd_password"]<>"")) {

	$userid=$_COOKIE["cd_id"];
	$username=$_COOKIE["cd_name"];
	$password=$_COOKIE["cd_password"];
	
	global $db;
	$cd_ids=$db->getrow("select cd_id,cd_logintime from " . tname('session') . " where 
	cd_uid =$userid and cd_uname='$username'");

 测试一下,可以盲注...

 总之都是考虑不周带来的后果。

  • 用支付宝打我
  • 用微信打我

一条回应:“审计日记2——偷懒的waf{爱频道音乐管理系统}”

  1. s1N说道:

    打开\(≧▽≦)/

发表评论

电子邮件地址不会被公开。 必填项已用*标注