如何深度分析宽字节sql注入


如何深度分析宽字节sql注入,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法.宽字节是相对于ascII这样单字节而言的;像GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节GBK是一种多字符的编码,通常来说,一个gbk编码汉字,占用2个字节。一个utf-8编码的汉字,占用3个字节转义函数:为了过滤用户输入的一些数据,对特殊的字符加上反斜杠“”进行转义;Mysql中转义的函数addslashes,mysql_real_escape_string,mysql_escape_string等,还有一种是配置magic_quote_gpc,不过PHP高版本已经移除此功能宽字节注入先了解下SQL的执行过程:1.以php客户端为例,使用者输入数据后,会通过php的默认编码生成sql语句发送给服务器。在php没有开启default_charset编码时,php的默认编码为空

此时php会根据数据库中的编码自动来确定使用那种编码,可以使用 来进行判断,如果输出的值是3说明是utf-8编码;

如果输出的值是2说明是gbk编码;

2.服务器接收到请求后会把客户端编码的字符串转换成连接层编码字符串(具体流程是先使用系统变量 character_set_client 对 SQL 语句进行解码后,然后使用 系统变量 character_set_connection 对解码后的十六进制进行编码)。
3.进行内部操作前,将请求按照如下规则转化成内部操作字符集,如下:3.1 使用字段 CHARACTER SET 设定值;3.2 若上述值不存在,使用对应数据表的DEFAULT CHARACTER SET设定值;

3.3 若上述值不存在,则使用对应数据库的DEFAULT CHARACTER SET设定值;

3.4 若上述值不存在,则使用character_set_server设定值。4.执行完 SQL 语句之后,将执行结果按照 character_set_results 编码进行输出。宽字节注入指的是mysql数据库在使用宽字节(GBK)编码时,会认为两个字符是一个汉字(前一个ascii码要大于128(比如%df),才到汉字的范围),而且当我们输入单引号时,mysql会调用转义函数,将单引号变为’,其中的十六进制是%5c,mysql的GBK编码,会认为%df%5c是一个宽字节,也就是’運’,从而使单引号闭合(逃逸),进行注入攻击

宽字节注入发生的位置就是PHP发送请求到MYSQL时字符集使用character_set_client设置值进行了一次编码,然后服务器会根据character_set_connection把请求进行转码,从character_set_client转成character_set_connection,然后更新到数据库的时候,再转化成字段所对应的编码以下是数据的变化过程:为了方便演示该注入的过程,搭建一下环境链接:https://pan.baidu.com/s/1cMFtCpbbaocMjaWJx7YLcQ密码:ykve数据库名为test,数据库的编码全部为gdk
简单的源码n”加上echo "
"."执行的sql语句是:".$sql."
"
这句话,可以清楚的查看sql语句的变化过程。sql语句是SELECT * FROM news WHERE tid='{$id}根据id从数据库表中获取信息。细节分析单纯加上单引号没有报错,说明addslashes函数发挥了作用,将' --> ',这样就不会存在注入了。

此时,在单引号前面加上前面讲的%df,是mysql认为%df是一个汉字,这样’就可以逃逸出来,使tid = ‘1’闭合。

这时候,按说是可以构造查询语句了,可是为什么还在报错呢,因为tid=’1’后面的’没有闭合,需要使用注释符号(– ‘或#)将这个多余的’注释掉,这样就可以构造注入语句了。

下面就可以按照手动注入的思路进行数据的获取了。确定表的字段数由于接下来要采用union探测内容,而union的规则是必须要求列数相同才能正常展示,因此必须要探测列数,保证构造的注入查询结果与元查询结果列数与数据类型相同; ‘order by 1’代表按第一列升序排序,若数字代表的列不存在,则会报错,由此可以探测出有多少列。

可知一共有3个字段确定字段的显示位显示位:表中数据第几位的字段可以 显示,因为并不是所有的查询结果都 会展示在页面中,因此需要探测页面 中展示的查询结果是哪一列的结果; ‘union select 1,2,3 — ‘ 通过显示的数字可以判断那些字段可以显示出来。

id的值要用-1或者该表中没有用过的id值,否则测试值会被覆盖。获取当前数据库信息现在只有两个字段可以显示信息,显然在后面的查询数据中,两个字段是不够用,可以使用:group_concat()函数(可以把查询出来的多行数据连接起来在一个字段中显示) database()函数:查看当前数据库名称 version()函数:查看数据库版本信息 user():返回当前数据库连接使用的用户 char():将十进制ASCII码转化成字符

当前数据库名为’test’。获取test数据库中的表信息Mysql有一个系统的数据库information_schema,里面保存着所有数据库的相关信息,使用该表完成注入

由于存在addslashes转义了单引号,如果在table_schema中继续使用单引号包裹数据库名字,就会报错,这时候需要使用十六进制编码来避免这个问题。获取admin表的字段column_name表示获取字段名
table_name需要使用十六进制编码获取admin表的数据

数据获取到了,可以更深入一下,比如进行文件的读取,提权等操作。获取当前用户信息此次会用到工具SQLMAP,sqlmap是一个SQL注入工具。此一具在业界称为神器。sqlmap是用python语言编写,如果想对工具详细了解,请到官网了解。下载和使用http://sqlmap.org/http://blog.csdn.net/whatday/article/details/54766536本实验用到sqlmap,以下是用sqlmap工具操作。使用sqlmap工具第一步猜用户

看到是root用户,可以更方便的搞事情了。读服务器中的文件sqlmap 中--file-read参数,可以读取服务器端任意文件

已经将文件保存到了本地/root/.sqlmap/output/127.0.0.1/files文件夹下正常思路,接下来可以进行提权了,由于该环境是搭建在windows下的,使用--file-write参数进行写文件的操作不能执行,这里就不做演示了。为了方便演示该注入的过程,搭建一下环境链接:https://pan.baidu.com/s/1WC4D-3o-A7uYAi8w_yQ7sA密码:sbwy数据库名为test,数据库的编码全部为gdk

4.将index.php放到phpStudy的WWW目录下,将test.sql文件导入到数据库中即可源码n”同样也试用了 addslashes转义,然后使用iconv进行转码,由utf-8 –>gbk细节分析为了避免宽字节注入,很多人使用iconv函数(能够完成各种字符集间的转换$text=iconv("UTF-8","GBK",$text);),其实这样做是有很大风险的,仍旧可以造成宽字节注入。可以使用逆向思维,先找一个gbk的汉字,錦的utf-8编码是0xe98ca6,它的gbk编码是0xe55c,是不是已经看出来了,当传入的值是錦''通过addslashes转义为'(%5c%27),通过icov转换为%e5%5c,终止变为了%e5%5c%5c%27,不难看出%5c%5c正好把反斜杠转义,使单引号逃逸,造成注入。按照实验1的思路,可以执行宽字节注入

出现报错信息,说明存在宽字节注入。%5c%5c正好把反斜杠转义,使单引号逃逸获取到数据信息(这里的sql注入方法和实验1一样,读者可以自己尝试练习)bluecms 1.6 版本存在宽字节注入,环境源码:链接:https://pan.baidu.com/s/11PQqPdopA9bkLBY9gYrpqA 密码:ek6o漏洞复现该cms的宽字节注入漏洞存在于http://127.0.0.1/bluecmsv1.6/uploads/admin/index.php.此地址是我们的安装地址,如果是在本地搭建,需要根据你的本地地址和路径来进行判断。为了更好演示效果,我们进行如下安装。首先根据上面提示的下载地址进行下载源码。将整个bluecms文件放到phpStudy的WWW目录下,浏览器访问url/bluecms/uploads/install 根据提示进行安装。

打勾继续即可
这一步一定要根据自己的本地数据库信息进行配置,否则会失败。配置好后,下一步会进行安装,稍微一等,就安装完成了。访问http://127.0.0.1/bluecmsv1.6/upload免费云主机域名s/admin/login.php?act=login 进入存在注入的页面。在管理员界面输入登录信息:

使用burp suit 进行抓包:admin_name就是注入点,可以实现万能密码登录(具体的溯源请看细节分析部分)构造payload成功登录后台
可以看到宽字节显示的汉字‘運’细节分析看下管理员登录界面的源码admin/login.php在第二行可以看到包含了/include/common.inc.php文件,跟进一下第一行包含了include/mysql.class.php文件,第二行实例化mysql对象,继续跟进mysql.class.php/include/common.inc.php文件中的mysql实例化对象,调用了这个mysql类,将数据库的连接信息进行封装,重点关注下mysql_query( "SET NAMES gbk");这一句,使三个字符集(客户端、连接层、结果集)都是GBK编码,经过前面的讲解可以知道gbk是双字节,如果再使用了addslashes()等前面所说的函数进行转义操作,那么一定可以触发宽字节注入回到common.inc.php,看到如果没有开启get_magic_quotes_gpc(),则会对各种请求数据使deep_addslashes()进行过滤,跟进下这个函数,在common.fun.php文件中不管是数组还是字符串都会调用addslashes()函数进行字符的转义至此可以确定能触发宽字节注入sql语句分析前面已经构造了payload,现在看一看完整的sql语句admin/login.php源码check_admin()函数使用了输入的用户名和密码,跟进一下该函数在include/common.fun.php文件中正常的sql语句当从blue_admin表中查到admin的信息,num的值就会大于零,这样就可以登录成功含有payload的sql语句登录后台管理,可以寻找上传点,或者利用已知的漏洞,从而getshell,进而控制整个服务器。使用mysql_set_charset(GBK)指定字符集使用mysql_real_escape_string进行转义以上两个条件需要同时满足才行,缺一不可。关于如何深度分析宽字节sql注入问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注云编程开发博客行业资讯频道了解更多相关知识。

相关推荐: SaltStack认证绕过漏洞CVE-2020-11651复现的示例分析

这期内容当中小编将会给大家带来有关SaltStack认证绕过漏洞CVE-2020-11651复现的示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。SaltStack是基于Python开发的一套C/S架构配置管理工具,是…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 02/07 12:09
下一篇 02/07 12:09