前言
之前在《mysql下读取文件的几种方式及应用》一文中提到在mysql注入中理论上应该可以导出可执行二进制文件到启动项的说法,现给出原理及实例供大家参考。
MYSQL注入中导出文件需满足的条件大家都知道,就不多说了,要导出可执行二进制文件还需注入点必须存在二进制编码格式数据类型的字段(如BLOB或LONGBLOB数据类型)。要导出可执行bat文件对字段的数据类型没有要求。其他一些附加限制条件依环境而定。
在注入页面无法爆出物理路径的情况下,如果满足上述条件,可以考虑用这种方法得到权限。
实现原理
将可执行文件用HEX()编码后,分段导出并UNHEX()解码所有HEX()编码后的文件分段,在导出的文件中重组为完整的文件。
相关以下几个方面的知识,不懂可以参考。
1. 不同数据类型的字段可存储同种编码方式的数据
MYSQL数据库中,要存取不同编码方式的数据,列数据类型必须与欲存取数据的编码方式相对应。当表中各不同数据类型的列中存储的数据采用同一种编码方式时,尽管各个列的数据类型不同,此时表中只有一种编码方式。因此当把一个文件按数据表中的列数分为多段并以同种编码方式存储于各不同数据类型的列中时,若将整个数据表中的数据按列顺序导出到同一个文件中,就可以重组还原成同一编码的完整文件。HEX编码方式役属于几乎所有数据类型,在int,text,blob,data …等数据类型中,在其存储范围内,被hex()编码过的文件都可以合法存储。
2. 各数据类型的存储范围
我们平时在注入中使用UNION查询一般都采用数字匹配字段的方式以达到select_expression的适用条件(即UNION后面查选的字段数量、字段数据类型都应该与最前面SELECT的一样),这是因为数字役属于几乎所有数据类型,因此可以匹配任何字段,HEX编码方式同样役属于几乎所有数据类型,因此我们可以把一个文件用HEX()函数编码,接着把编码后的文件按数据表中的列数分为多段数据,每一段数据按顺序匹配对应字段,构造注入URL,导出完整的文件。
在把HEX()编码后的文件分段时,需要了解各数据类型的存储范围,从而判断注入点各字段允许提交数据的长度和可存储编码范围,以便把最长的分段数据放在存储范围最大的数据类型的字段上。详细请参照《MySQL数据类型简介》(http://www.sai52.com/archives/769/)。
3. UNION的特性导致的不同注入点利用方法
MYSQL只要数据能在对应数据类型的列中完整存储,就可以导出任意文件名的完整文件。也就是说,我们把二进制文件用HEX()编码后可以存储在TEXT数据类型等非二进制编码的字段上,导出时UNHEX()解码依然能保存为完整的二进制文件。
语句中unhex(cmd)已经改变了所选字段的数据类型为二进制,因此可以导出完整的二进制文件,而在注入中我们用UNION连接SELECT语句时,UNION后面查询的字段数量、字段数据类型都得与最前面的SELECT一样,此时
语句中unhex(cmd)字段的数据类型与最前面的cmd字段的数据类型不同,二进制编码的数据无法在TEXT数据类型中完整储存,因此无法导出完整的二进制文件。要导出完整的二进制文件,最前面SELECT所选的字段中必须有以二进制存储数据的数据类型,如BLOB,LONGBLOB等。导出bat文件无此要求,任何类型的字段只要在其存储范围内都可以。
4. INTO DUMPFILE 的特性
如果使用INTO DUMPFILE导出数据,则MySQL只把一行写入到文件中,不对任何列或行进行终止,也不执行任何转义处理。INTO DUMPFILE 的这个特性说白了就是“无缝连接”,它既可以用于从列中导出数据到文件,也可以用于从表中导出数据到文件。
UNHEX()函数执行从HEX()的反向操作。就是说,它将参数中的每一对十六进制数字理解为一个数字,并将其转化为该数字代表的字符。结果字符以二进制字符串的形式返回。0x与UNHEX()意义相同。
当表中的各个不同数据类型的列依次存储了所有的HEX编码后的文件分段时,用SELECT0x文件十六进制数据part1,0x文件十六进制数据 part2,0x文件十六进制数据part3,….0x文件十六进制数据partNINTO DUMPFILE的方式导出表中全部数据到一个新文件,此时各个列中的HEX编码文件分段分别被还原到新文件中的对应顺序部分,之后被“无缝连接”在一起,形成一个与原文件编码方式及大小一模一样的新文件,被保存到你想要它去的地方,比如启动项。
5. GET与POST方式提交数据的限制
注入点多以GET方式取得数据,而GET方式请求的URL长度受特定的浏览器及服务器两方面的限制(注意这个限制是整个URL长度,而不仅仅是你的参数值数据长度):
如果URL的长度超出客户端浏览器限制,提交时浏览器无响应。
如果URL的长度超出服务器限制,服务器不处理请求,返回错误提示“Url Too Long”。
GET方式提交超长URL时,建议使用NC或数据提交工具。
经过实验得知,用GET方式传递WEB页面参数时服务器允许的最大值为16000字节左右(WIN2003+IIS环境),也即是说,导出的可执行二进制文件在7.9k以内时,可以正常导出。如果是POST方式的注入点,提交数据的最大长度只受限于服务器设置,如php.ini的设置等。
.MySQ默认字符集对导出路径中双字符编码的影响
mysql5提供了几个设置字符集的系统变量,其中character_set_client的值是MYSQL用来获得客户端传递数据的字符集的。
MYSQL(默认安装)设置是latin1的瑞典语排序方式,当我们按照默认设置方式通过PHP存取MySQL数据库时,无论通过哪种方式的编码发送查询,MYSQL都认为传输过来的数据是latin1编码。
网页提交的双字节字符编码数据(如中文,日文,韩文等),(在服务器没有进行特殊设置的情况下)被提交后被默认是UTF8编码(与提交时设定的编码无关),MYSQL按自身默认的latin1编码来读取,双字符编码的文字必然会显示为乱码,这样在用INTO OUTFILE 或 INTODUMPFILE 导出数据到文件时,导出路径中的双字符编码文字就会显示为乱码,导致MYSQL因为找不到显示成乱码的路径而导致导出文件失败。
如果被注入的php程序源码中包含类似
mysql_query(“SET NAMES ’utf8’”); |
之类的设置使MYSQL服务器用来读取客户端传递数据的字符集为utf8,那么注入中就可以导出文件到双字节字符命名的目录,否则MYSQL会因为找不到显示成乱码的路径而导致导出文件失败。
图01
因此,如果MYSQL服务器使用的是UTF编码,或者PHP连接MYSQL数据库的语句中包含类似
mysql_query(“SET NAMES ’utf8’”);
之类的设置时,导出文件到双字节字符编码的文件路径成为可能,否则会导致导出失败。如果导出文件的保存路径中不包含双字节字符编码,则没有任何限制。
实例1 导出exe文件到启动项(本机搭建的 WIN2003+IIS+PHP5+MYSQL5 环境 magic_quotes_gpc=off)
1、显示正常的页面
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
作者
相关推荐
-
2017年5月数据库流行度排行榜 MySQL与Oracle“势均力敌”
数据库知识网站DB-engines.com最近更新了2017年5月的数据库流行榜单。TechTarget继续与您一起分享最新的榜单情况。
-
2017年3月数据库流行度排行榜 Oracle卫冕之路困难重重
时隔一个月,数据库市场经过一轮“洗牌”,旧的市场格局是否会被打破,曾经占巨大市场份额的企业是否可能失去优势?
-
2017年2月数据库流行度排行榜 攻城容易守城难
2016年下半年,数据库排行榜的前二十名似乎都“固守阵地”,在排名上没有太大的变动。随着2017年的悄然而至,数据库的排名情况是否会有新的看点?
-
MySQL管理特性:让企业适合交易平台
当Alexander Culiniac和他的同事在TickTrade系统公司建立一个基于云的交易平台时,面临一些基本的约束。那就是,系统必须在云上工作良好并且经济实用。