sqlmap宽字节注入_sql注入orderby子句的功能

sqlmap宽字节注入_sql注入orderby子句的功能AboutSQLInjection宽字节注入0x01前言对于SQL注入,我估计搞安全的都玩的滚瓜烂熟了,搞站什么的都是分分钟来的,但是之前做了一道宽字节注入的题目,又打开了我一扇通往新世界的大门(PS:早都碰到过,只不过一直没有时间写)。0x02宽字节和mysql单字节字符集:所有的字符都使用一个字节来表示,比如ASCII编码。多字节字符集:在多字节字符集中,一部分字节用多个字节来…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

About SQL Injection

宽字节注入

0x01 前言

对于SQL注入,我估计搞安全的都玩的滚瓜烂熟了,搞站什么的都是分分钟来的,但是之前做了一道宽字节注入的题目,又打开了我一扇通往新世界的大门(PS:早都碰到过,只不过一直没有时间写)。

0x02 宽字节和mysql

单字节字符集: 所有的字符都使用一个字节来表示,比如 ASCII 编码。

多字节字符集: 在多字节字符集中,一部分字节用多个字节来表示,另一部分(可能没有)用单个字节来表示。

两位的多字节字符有一个前导字节和尾字节。 在某个多字节字符集内,前导字节位于某个特定范围内,尾字节也一样。

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

常见的宽字节: GB2312、GBK、GB18030、BIG5、Shift_JIS,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象。(GB2312 不存在宽字节注入。)

在mysql中,用于转义(即在字符串中的符号前加上””)的函数有addslashes,mysql_real_escape_string,mysql_escape_string等,还有一种情况是magic_quote_gpc,不过高版本的PHP将去除这个特性。

注意:HTML页面设置的编码跟注入是没有任何联系的,它只不过使规定了HTML渲染时候的字符集设置,与服务器端以及数据库没有任何联系。

0x03 简单的宽字节示例

出自Bugku的一道题目,非常基本。正常的传递单引号,没有任何效果。

%E5%AE%BD%E5%AD%97%E8%8A%82%E6%B3%A8%E5%85%A5-1.png

查看源代码

%E5%AE%BD%E5%AD%97%E8%8A%82%E6%B3%A8%E5%85%A5-2.png

红线标注了gb2312,这是html编码方式,但是提示了我们可能是这个方向,于是就尝试http://103.238.227.13:10083/?id=1%df’

%E5%AE%BD%E5%AD%97%E8%8A%82%E6%B3%A8%E5%85%A5-3.png

发现页面报错,也就是’没有被闭合,而是逃逸了出来生效了,SQL语句如下:select * from key where id=’1運” limit 1

这时候就明显的看出来了有个多余的单引号逃逸了,也就是你传递进去的那个单引号生效了,至此,这道题目的考察项已经完全get到了。

构造payload:http://103.238.227.13:10083/?id=1%df’ union select 1,string from sql5.key–+

那么问题来了,为什么会出现这种情况呢?

mysql设置的字符集为gbk,并且使用了那些上面所提到的过滤函数,在你传递’的时候,会在前面加上,导致’,使之被转义,从而无法闭合SQL语句,无法达到预期效果。

上面介绍了gbk是一种两个字节的编码方式,当传递%df’的时候,后台接收为%df%5c%27,这时候,数据库由于是gbk编码,所以数据库会认为%df%5c是一个中文字符’運’,转义的被吃掉了,无法转义’,这时候就导致了’可以成功逃逸出来,可以对SQL语句进行下一步改造。

可以写个php页面验证下gbk编码中文字符的长度:<?php

header(‘content-type:text/html;charsetr=gbk’);

echo strlen(“哇”);

?>

这里还要提一点,不管你在单引号前面加什么字符,都要确保这个字符的ascii大于128,否则无法达到汉字的范围,也就无法使宽字节注入生效。

0x04 gbk与gb2312

前文提到了,gb2312不存在宽字节注入,我当时也很不理解,看了离别歌大佬的博客以后,顿有所悟(大佬终究是大佬)。

GBK与GB2312都是宽字节家族的一员,按理来说,GBK都存在宽字节注入,GB2312也存在,但是实际上,当采用字符集编码为GB2312时,宽字节注入这种情况便无法发生了,为什么呢?这要归结于GB2312编码的取值范围,它的高位范围是0xA1~0xF7,低位范围是0xA1~0xFE(PS:前一位是高位,后一位是低位),而是0x5c,是不在低位范围中的。所以,0x5c也就是根本不在gb2312的编码范围内,也就是说,无论如何,都无法构造出gb2312认识的编码,也就不存在吞掉,无法构造注入了。

搬运大佬的一句总结:把这个思路扩展到世界上所有多字节编码,我们可以这样认为:只要低位的范围中含有0x5c的编码,就可以进行宽字符注入。

0x05 进阶示例在 PHP 代码中使用 mysql_query(“set names GBK”); 指定三个字符集(客户端、连接层、结果集)都是GBK编码。

demo:<?php

$name = addslashes($_GET[‘name’]);

$con=mysqli_connect(“localhost”,”root”,”fuckroot”,”sqli”);

if (mysqli_connect_errno($con))

{

echo “连接 MySQL 失败: ” . mysqli_connect_error();

}

// 执行查询

$sql = “select * from user where name = ‘”.$name.”‘”;

echo “SQL:”.$sql.”
“;

mysqli_query($con,”set names GBK”);

$result = mysqli_query($con,$sql);

if(!$result){

// 打印错误原因

printf(“Error: %sn”, mysqli_error($con));

}

// echo(“Res num_rows:”.$result->num_rows.”
“);

// 一条条获取

while ($row=mysqli_fetch_row($result))

{

printf (“%s : %s”,$row[0],$row[1]);

echo “
“;

}

// 释放结果集合

mysqli_free_result($result);

// $row=mysqli_fetch_row($result);

echo “Closed!”;

mysqli_close($con);

?>

利用的poc:?name=111%de’ or 1=1–+

这里利用了addslashes函数进行转义特殊字符,而我们传递进去的是%de’,就会变成0xde5c,而上文设定的字符集是GBK,之后就会产生宽字节注入,道理与上文一样。

2.

php的iconv函数,对数据进行转码,有三种情况:

2.1$name = iconv(“GBK”,”UTF-8″, addslashes($_GET[‘name’])) ;

页面设置都是UTF-8编码,但是页面为了接受部分用户以GBK编码方式提交的数据,会对用户的数据先进行转码,把GBK转为UTF-8,然后再拼接SQL语句,进行一系列的操作。但是,假如传递了一个%df进去,在拼接SQL语句之前,也就是转码的时候,这个单引号逃逸就已经发生了。因为GBK会把%df解码为一个中文字符,然后进行存储。简单理解,也就是说,进行UTF转码之前,GBK就已经操作过了,所以即便进行UTF-8转码,转的也是已经生效的payload “運’”,无法对单引号进行实际操作。至此,单引号溢出,SQL注入形成。

利用的poc:name=111%B3‘ or 1=1–+

2.2$name = iconv(“UTF-8″,”GBK”, addslashes($_GET[‘name’])) ;

这个跟第一个类似,就是把UTF-8的编码转码成GBK。其实按道理来说对字符串进行转义,然后转码,按照UTF-8的编码方式进行操作,应该不会出现单引号溢出的这种问题。但是,74CMS 3.4版存在这样的漏洞,这就很gay。

现在,直接传递一个GBK编码的中文字符“錦’”参数值,这个参数先被过滤函数转义:graph LR

錦’–>錦’

那么GBK编码的16进制结果就变成了0xE55C5C27,好,现在把数据传入数据库,用UIF-8对其进行解码,UTF-8并不认识0xE5,于是0xE5就变成了乱码,而0x5C5C27会被正常解码为“‘”,就是:graph LR

0xE55C5C2–>�\’

现在,出现了两个转义用的反斜线,这时候,单引号就可以成功溢出了,因为第一个反斜线转义了第二个反斜线,使第二个反斜线失去了转义功能,也就导致了单引号的逃逸。至此,成功引发了SQL注入。

利用的POC:name=錦’ or 1=1–+

name=%E9%8C%A6′ or 1=1–+

2.3

这种情况,我认为,基本不会出现,不过网络世界这么大,啥鸟都有,也说不定。

这种是对UTF-8的编码进行GBK转码,然后使用过滤函数进行转义:$name = iconv(“UTF-8″,”GBK”, $_GET[‘name’]) ;

$name = addslashes($name);

看起来就很奇葩,但是有可能存在,利用的POC与2.2一样,只不过解析过程不一样。传递参数:name=錦’

先进行GBK转码(为了方便理解,我都以16进制表示):graph LR

0xE98CA627–>0xE55C27

然后进行过滤函数转义:graph LR

0xE55C27–>0xE55C5C5C27

惊奇的发现,5C多了两个。这因为,进行完GBK转码以后,在进行过滤函数转义的时候,会把0x5C认为是一个特殊字符,所以会对这个反斜线进行转义,也就是多加一个反斜线变成\,也就是5C5C,之后数据进入数据库,GBK对其进行解码,0xE55C会被解码为“錦”,0x5C5C27会被解码为“\‘”,也就是:graph LR

0xE55C5C5C27–>錦\’

至此,又跟2.2介绍的一样了,殊途同归,单引号成功逃逸,SQL注入产生。

0x06 小结

关于宽字节,我目前也就在CTF里面接触到了,不过既然碰到了我就写一写,这方面确实菜的不行,所以避免不了去看一些大佬的分析,也学到了很多的东西。

防范:

1.gbk编码造成的宽字符注入问题,解决方法是设置character_set_client=binary。

2.单独调用set names gbk和mysql_real_escape_string是无法避免宽字符注入问题的。还得调用mysql_set_charset来设置一下字符集。

3.谨慎使用iconv来转换字符串编码,很容易出现问题。只要我们把前端html/js/css所有编码设置成gbk,mysql/php编码设置成gbk,就不会出现乱码问题。不用画蛇添足地去调用iconv转换编码,造成不必要的麻烦。

4.在代码审计或网站开发中需要留意一下,类似 GBK 和 BIG5 这种的双字节编码,同时存在低位可以是 %5C 的字符。

PS:最近老是写到凌晨,有不足或者错误的地方,看到了希望可以及时联系我进行纠正。

特别鸣谢

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/181971.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号