漏洞时代 - 最新漏洞_0DaY5.CoM漏洞时代 - 最新漏洞_0DaY5.CoM

phpmywind getshell

较鸡肋,就看看而已
phpmywind一直也没有修补漏洞,这里有很多方法,我们这里主要使用一个任意无限制注入得到一个管理员账号,后台进行getshell.先说说 80sec-ids 的绕过吧.做代码审计的时候,遇见ids 这个waf的几率还是很高的,今天我就拿phpmywind cms做分析.我们先看看他的代码

function CheckSql($sql, $querytype='select') 
{
	$clean = '';
	$error = '';
	$pos = -1;
	$old_pos = 0;
	if($querytype == 'select') 
	{
		if(preg_match('/[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}/', $sql)) 
		{
			$this->DisplayError("$sql||SelectBreak",1);
		}
	}
	while(true) 
	{
		$pos = strpos($sql, '\'', $pos + 1);
		if($pos === false) 
		{
			break;
		}
		$clean .= substr($sql, $old_pos, $pos - $old_pos);
		while(true) 
		{
			$pos1 = strpos($sql, '\'', $pos + 1);
			$pos2 = strpos($sql, '\\', $pos + 1);
			if($pos1 === false) 
			{
				break;
			}
			else if($pos2 == false || $pos2 > $pos1) 
			{
				$pos = $pos1;
				break;
			}
			$pos = $pos2 + 1;
		}
		$clean .= '$s$';
		$old_pos = $pos + 1;
	}
	$clean .= substr($sql, $old_pos);
	$clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean)));
	if(strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0) 
	{
		$fail = true;
		$error = 'union detect';
	}
	else if(strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, '#') !== false) 
	{
		$fail = true;
		$error = 'comment detect';
	}
	else if(strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0) 
	{
		$fail = true;
		$error = 'slown down detect';
	}
	else if(strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0) 
	{
		$fail = true;
		$error = 'slown down detect';
	}
	else if(strpos($clean, 'load_file') !== false && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0) 
	{
		$fail = true;
		$error = 'file fun detect';
	}
	else if(strpos($clean, 'into outfile') !== false && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0) 
	{
		$fail = true;
		$error = 'file fun detect';
	}
	else if(preg_match('~\([^)]*?select~s', $clean) != 0) 
	{
		$fail = true;
		$error = 'sub select detect';
	}
	if(!empty($fail)) 
	{
		$this->DisplayError("$sql,$error",1);
	}
	else 
	{
		return $sql;
	}
} }

我们来分析.首先我们看传入的 $sql 变量,这一步是我们sql语句进入mysql的最后一步,我们下面看最核心的代码,

if($querytype == 'select') 
{
	if(preg_match('/[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}/', $sql)) 
	{
		$this->DisplayError("$sql||SelectBreak",1);
	}
} while(true) 
{
	$pos = strpos($sql, '\'', $pos + 1);
	if($pos === false) 
	{
		break;
	}
	$clean .= substr($sql, $old_pos, $pos - $old_pos);
	while(true) 
	{
		$pos1 = strpos($sql, '\'', $pos + 1);
		$pos2 = strpos($sql, '\\', $pos + 1);
		if($pos1 === false) 
		{
			break;
		}
		else if($pos2 == false || $pos2 > $pos1) 
		{
			$pos = $pos1;
			break;
		}
		$pos = $pos2 + 1;
	}
	$clean .= '$s$';
	$old_pos = $pos + 1;
} 

这里通过匹配 '/ 确定 最开始 ‘ 两个 单引号的内容(即 通过转义是 '/ 的内容)并且将其中的内容通过 substr()函数 截断下来,再将剩下来的语句进行匹配,所以只要我们将我们需要的语句藏在 两个单引号之间就OK了

藏在两个单引号之间虽然绕过了这个waf,但是我们需要sql语句的正确性, 我们通过资料知道 在mysql 里面,可以用@引入变量,如 @'xxx',@"xxx",@`xxx`等等,大家可以自己写一个脚本 fuzz,其中的xxx为任意字符 ,引入变量初始值都为 NULL,so @`'` @`\'` 变量的默认值是 null ,所以我们 用包含单引号的 @`'` 去包含我们的语句就可以了。有些时候插入 @`'` 会报错,我们用 char(@`'`) 就可以了。

本原创文章未经允许不得转载 | 当前页面:漏洞时代 - 最新漏洞_0DaY5.CoM » phpmywind getshell

评论