SQL注入漏洞原理

由于开发者在编写数据库操作代码时,直接将外部可控的参数拼接到sql语句中,没有经过任何过滤就直接放入数据库引擎执行。

挖掘经验

普通注入

最容易利用的sql注入漏洞,比如直接通过union查询就可以查询数据库。普通注入有int型和string型。可通过查找数据库操作的一些关键字如:select frommysql_connectmysql_querymysql_fetch_rowupdateinsertdelete等定向挖掘sql注入漏洞。

编码注入

在做编码处理时,如果输入转码函数不兼容的特殊字符,就会导致输出的字符变成有害数据。在sql注入里,最常见的编码注入是mysql宽子节以及urldecode/rawurldecode函数导致的。

宽子节注入

在使用PHP连接mysql的时候,当设置set character_set_client=gbk时会导致宽子节注入。当存在宽子节注入时,注入参数里带入%df%27,即可把程序中过滤的\(%5c)吃掉

修复方法:

  • 在执行查询之前先执行SET NAMES 'gbk',character_set_client=binary设置character_set_clientbinary
  • 使用pdo方式,在php5.3.6及以下版本需要设置setArribute(PDO::ATTR_EMULATE_PREPARES,false);来禁用prepared statements的仿真效果。

挖掘方法: 搜索如下关键字即可:

  • SET NAME
  • character_set_client=gbk
  • mysql_set_charset('gbk')
二次urldecode注入

如果某处使用了urldecode或者rawurldecode函数,则会导致二次解码生成单引号而引发注入。我们提交参数到WebServer时,WebServer会自动解码一次,假设目标开启了GPC,我们提交/1.php?id=1%2527因为我们提交的参数里没有单引号,所以第一次解码后的结果是id=1%27%25解码的结果是%,如果程序里面使用了urldecode或者rawurldecod函数来解码id参数,解码后的结果是id=1'单引号成功出现引发注入。

挖掘方法: 搜索urldecoderawurldecode函数来挖掘二次urldecode注入漏洞。

漏洞防范

gpc/runtime魔术引号
  • magic_quotes_gpc 负责对GET、POST、COOKIE的值进行过滤
  • magic_quotes_runtime 对从数据库或者文件中获取的数据进行过滤

这种方法只对单引号、双引号、反斜杠以及空字符NULL进行过滤,在int型的注入上没有多大作用的。

PHP4.2.3以及之前的版本可以在任何地方设置开启,即配置文件和代码中,之后的版本可以在php.inihttpd.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。