浅析白盒审计中的字符编码及SQL注入(1)

尽管现在呼吁所
有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范。但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如gbk,作为自己默认的编码类型。也有一些cms为了考虑老用户,
所以出了gbk和utf-8两个版本。498)this.width=498;' onmousewheel = 'javascript:return big(this)' border="0" alt="浅析白盒审计中的字符编码及SQL注入" width="398" height="274" src="http://s7.51cto.com/wyfs02/M00/24/03/wKiom1NLRBegV-W7AADVV13tiLQ259.jpg" />我们就以gbk字符编码为示范,拉开帷幕。gbk是一种多字符编码,具体定义自行百度。但有一个地方尤其要注意:通常来说,一个gbk编码汉字,占用2个字节。一个utf-8编码的汉字,占用3个字节。在php中,我们可以通过输出echo strlen("和");来测试。当将页面编码保存为gbk时输出2,utf-8时输出3。除了gbk以外,所有ANSI编码都是2个字节。ansi只是一个标准,在
不用的电脑上它代表的编码可能不相同,比如简体中文系统中ANSI就代表是GBK。以上是一点关于多字节编码的小知识,只有我们足够了解它的组成及特性以后,才能更好地去分析它身上存在的问题。说了这么多废话,现在来研究一下在SQL注入中,字符编码带来的各种问题。0×01 MYSQL中的宽字符注入这是一个老话题了,也被人玩过无数遍。但作为我们这篇文章的序幕,也是基础,是必须要提的。我们先搭建一个实验环境。暂且称之为phithon内容管理系统v1.0,
首先先新建一个数据库,把如下压缩包中的sql文件导入:测试代码及数据库:http://pan.baidu.com/s/1eQmUArw 提取密码:75tu之后的phithon内容管理系统会逐步完善,但会一直使用这个数据表。源码很简单(注意先关闭自己php环境的magic_quotes_gpc)://连接数据库部分,注意使用了gbk编码,把数据库信息
填写进去<?php //连接数据库部分,注意使用了gbk编码,把数据库信息填写进去 $conn=mysql_connect('localhost','root','toor!@#$')ordie('bad!'); mysql_query("SETNAMES'gbk'"); mysql_select_db('test',$conn)ORemMsg("连接数据库失败,未找到您填写的数据库"); //执行sql语句 $id=isset($_GET['id'])?addslashes($_GET['id']):1; $sql="SELECT*FROMnewsWHEREtid='{$id}'"; $result=mysql_query($sql,$conn)ordie(mysql_error());//sql出错会报错,方便观察 ?> <!DOCTYPEhtml> <html> <head> <metacharset="gbk"/> <title>新闻</title> </head> <body> <?php $row=mysql_fetch_array($result,MYSQL_ASSOC); echo"<h2>{$row['title']}</h2><p>{$row['content']}<p>\n"; mysql_free_result($result); ?> </body> </html>SQL语句是SELECT * FROM news WHERE tid='{$id}',就是根据文章的id把文章从news表中取出来。在这个sql语句
前面,我们使用了一个addslashes函数,将$id的值转义。这是通常cms中对sql注入进行的操作,只要我们的输入参数在单引号中,就逃逸不出单引号的限制,无法注入,如下图:
那么怎么逃过addslashes的限制?众所周知addslashes函数产生的效果就是,让’变成\’,让引号变得不再是“单引号”,只是一撇而已。一般绕过方式就是,想办法处理\’前面的\:1.想办法给\前面再加一个\(或单数个即可),变成\\’,这样\被转义了,’逃出了限制2.想办法把\弄没有。我们这里的宽字节注入是利用mysql的一个特性,mysql在使用GBK编码的时候,会
认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围)。如果我们输入%df’看会怎样:498)this.width=498;' onmousewheel = 'javascript:return big(this)' style="width: 408px; height: 88px" border="0" alt="浅析白盒审计中的字符编码及SQL注入" width="690" height="109" src="http://s6.51cto.com/wyfs02/M01/24/03/wKioL1NLO_DQF4gwAABfXtEUSUk155.jpg" />我们可以看到,已经报错了。我们看到报错,说明sql语句出错,看到出错说明可以注入了。为什么从刚才到现在,只是在’也就是%27前面加了一个%df就报错了?而且从图中可以看到,报错的原因就是多了一个单引号,而单引号前面的反斜杠不见了。这就是mysql的特性,因为gbk是多字节编码,他认为两个字节代表一个汉字,所以%df和后面的\也就是%5c变成了一个汉字“運”,而’逃逸了出来。因为两个字节代表一个汉字,所以我们可以试试“%df%df%27”:498)this.width=498;' onmousewheel = 'javascript:return big(this)' border="0" alt="浅析白盒审计中的字符编码及SQL注入" width="445" height="236" src="http://s2.51cto.com/wyfs02/M00/24/03/wKiom1NLPDnRzSVuAABNcndAOAo907.jpg" />不报错了。因为%df%df是一个汉字,%5c%27不是汉字,仍然是\’。那么mysql怎么判断一个字符是不是汉字,根据gbk编码,第一个字节ascii码大于128,基本上就可以了。比如我们不用%df,用%a1也可以:498)this.width=498;' onmousewheel = 'javascript:return big(this)' style="width: 477px; height: 95px" border="0" alt="浅析白盒审计中的字符编码及SQL注入" width="571" height="133" src="http://s6.51cto.com/wyfs02/M02/24/03/wKioL1NLPCehOP7OAABbgdeRPEo089.jpg" />%a1%5c他可能不是汉字,但一定会被mysql认为是一个宽字符,就能够让后面的%27逃逸了出来。于是我可以构造一个exp出来,查询管理员账号密码:498)this.width=498;' onmousewheel = 'javascript:return big(this)' style="width: 477px; height: 128px" border="0" alt="浅析白盒审计中的字符编码及SQL注入" width="690" height="204" src="http://s6.51cto.com/wyfs02/M00/24/03/wKioL1NLPEfyqD7LAAB93JqIrtI649.jpg" /> 1 2 3 4 5 6 下一页>>查看全文 内容导航第 1 页:MYSQL中的宽字符注入 第 2 页:GB2312与GBK的不同 第 3 页:mysql_real_escape_string解决问题 第 4 页:宽字符注入的修复 第 5 页:iconv导致的致命后果 第 6 页:总结 原文:浅析白盒审计中的字符编码及SQL注入(1) 返回网络安全首页

时间: 2024-09-29 15:56:45

浅析白盒审计中的字符编码及SQL注入(1)的相关文章

mysql数据库中文乱码应该怎么解决,修改配置文件中的字符编码并没有作用

问题描述 mysql数据库中文乱码应该怎么解决,修改配置文件中的字符编码并没有作用 mysql数据库中文乱码应该怎么解决,修改配置文件中的字符编码并没有作用. 解决方案 把当前数据库字符集改为utf8试一下. 解决方案二: 可以设置当前文本编码,与数据库一致 解决方案三: 先把文本粘贴到记事本,然后改成utf-8 保存后再粘贴回去

php中的字符编码转换函数用法示例_php技巧

本文实例讲述了php中的字符编码转换函数的用法,分享给大家供大家参考.具体实现方法如下: 一般来说,在网页程序中,尤其是涉及到数据库的读出过程中,往往最恼火的就是字符编码的问题,php4.0.6以上的版本提供了mb_convert_encoding 可以方便的转换编码. 具体如下: 复制代码 代码如下: <?php /* Convert internal character encoding to SJIS */ $str = mb_convert_encoding($str, "SJIS

怎么把sql2000数据库中的字符编码修改为utf-8?

问题描述 怎么把sql2000数据库中的字符编码修改为utf-8? 解决方案 解决方案二:没有的,mysql和Oracle在安装的时候可设!解决方案三:建数据库的时候是可以选择的,但在现有库上修改还没试过.

php中$_GET与$_POST过滤sql注入的方法_php技巧

本文实例讲述了php中$_GET与$_POST过滤sql注入的方法,分享给大家供大家参考.具体分析如下: 此函数只能过滤一些敏感的sql命令了,像id=1这种大家还是需要自己简单过滤了. 主要实现代码如下: 复制代码 代码如下: if (!get_magic_quotes_gpc()) { if (!empty($_GET)) { $_GET  = addslashes_deep($_GET); } if (!empty($_POST)) { $_POST = addslashes_deep($

Java中的字符集编码入门(五) Java代码中的字符编码转换

如果你是JVM的设计者,让你来决定JVM中所有字符的表示形式,你会不会允许使用各种编码方式的字符并存? 我想你的答案是不会,如果在内存中的Java字符可以以GB2312,UTF-16,BIG5等各种编码形式存在,那么对开发者来说,连进行最基本的字符串打印.连接等操作都会寸步难行.例如一个GB2312的字符串后面连接一个UTF-8的字符串,那么连接后的最终结果应该是什么编码的呢?你选哪一个都没有道理. 因此牢记下面这句话,这也是Java开发者的共同意志:在Java中,字符只以一种编码形式存在,那就

浅谈JavaScript中的字符编码转换问题_基础知识

要获得字符的Unicode编码,可以使用string.charCodeAt(index)方法,其定义为:    strObj.charCodeAt(index)       index为指定字符在strObj对象中的位置(基于0的索引),返回值为0与65535之间的16位整数.例如: var strObj = "ABCDEFG"; var code = strObj.charCodeAt(2); // Unicode value of character 'C' is 67      

Java中的字符编码问题处理心得总结_java

当面对一串字节流的时候,如果不指定它的编码,其实际意义是无法知道的. 这句话应该也是我们面对"字符转字节,字节转字符"问题时候时刻记在脑子里的.否则乱码问题可能就接踵而至. 其实乱码问题的本质就是Encoding和Decoding用的不是一个编码,明白了这个道理就很好解决乱码问题了. Java中常见的时候有如下: 1. String类使用byte[]的构造函数 String(byte[] bytes),String类同时提供了两个重载 (1)String(byte[] bytes, C

java中处理字符编码(网页与数据库)(转)

首先声明一下,此文章时从网上转载的.如下的某些方法是确实管用,但是从中发现了有一点不足,就是原文笔者没考虑使用不同Web Server时出现的情况,比如文章里我用红色字体画出来的部分代码在Tomcat跑的时候得用他说的方法,不过到了WebSphere的时候必须得用原先的 String name = request.getParameter("name"); 所以采取本文方法的时候不要太死板,多试试.  在Java编程中,中文字体编码难倒了不少程序员,如果抓住了影响Java中文显示的几个

php中防xss攻击和sql注入详解

XSS攻击  代码如下 复制代码 任意执行代码 文件包含以及CSRF. } 关于SQL攻击有很多文章还有各种防注入脚本,但是都不能解决SQL注入的根本问题 见代码:  代码如下 复制代码 <?php mysql_connect("localhost","root","123456")or die("数据库连接失败!"); mysql_select_db("test1"); $user=$_post['