SQL注入漏洞原理
由于开发者在编写数据库操作代码时,直接将外部可控的参数拼接到sql语句中,没有经过任何过滤就直接放入数据库引擎执行。
挖掘经验
普通注入
最容易利用的sql注入漏洞,比如直接通过union查询就可以查询数据库。普通注入有int型和string型。可通过查找数据库操作的一些关键字如:select from、mysql_connect、mysql_query、mysql_fetch_row、update、insert、delete等定向挖掘sql注入漏洞。
编码注入
在做编码处理时,如果输入转码函数不兼容的特殊字符,就会导致输出的字符变成有害数据。在sql注入里,最常见的编码注入是mysql宽子节以及urldecode/rawurldecode函数导致的。
宽子节注入
在使用PHP连接mysql的时候,当设置set character_set_client=gbk时会导致宽子节注入。当存在宽子节注入时,注入参数里带入%df%27,即可把程序中过滤的\(%5c)吃掉
修复方法:
- 在执行查询之前先执行
SET NAMES 'gbk',character_set_client=binary设置character_set_client为binary。 - 使用
pdo方式,在php5.3.6及以下版本需要设置setArribute(PDO::ATTR_EMULATE_PREPARES,false);来禁用prepared statements的仿真效果。
挖掘方法: 搜索如下关键字即可:
SET NAMEcharacter_set_client=gbkmysql_set_charset('gbk')
二次urldecode注入
如果某处使用了urldecode或者rawurldecode函数,则会导致二次解码生成单引号而引发注入。我们提交参数到WebServer时,WebServer会自动解码一次,假设目标开启了GPC,我们提交/1.php?id=1%2527因为我们提交的参数里没有单引号,所以第一次解码后的结果是id=1%27,%25解码的结果是%,如果程序里面使用了urldecode或者rawurldecod函数来解码id参数,解码后的结果是id=1'单引号成功出现引发注入。
挖掘方法:
搜索urldecode和rawurldecode函数来挖掘二次urldecode注入漏洞。
漏洞防范
gpc/runtime魔术引号
- magic_quotes_gpc 负责对GET、POST、COOKIE的值进行过滤
- magic_quotes_runtime 对从数据库或者文件中获取的数据进行过滤
这种方法只对单引号、双引号、反斜杠以及空字符NULL进行过滤,在int型的注入上没有多大作用的。
PHP4.2.3以及之前的版本可以在任何地方设置开启,即配置文件和代码中,之后的版本可以在php.ini、httpd.conf、.htaccess中开启。
过滤函数
- addslashes函数 对单引号、双引号、反斜杠和空字符NULL进行过滤,参数必须是
string类型,如果输入的参数是数组的话,会出现绕过的情况。 - mysql_[real_]escape_string函数 PHP4.0.3以上版本才能使用,对
[\x00][\n][\r][\][']["][\x1a]有影响,推荐使用mysql_real_escape_string,它接受一个连接句柄并根据当前字符集转义字符串。
intval等字符串转换
以上方法对int型注入的效果并不好,可以通过报错或者盲注绕过。intval可以将变量转换为int类型。(floatval)
PDO prepare预编译
通过预编译的方式来处理数据库查询,使用ATTR_EMULATE_PREPARES来禁用PHP的本地模拟prepare。