MySQL手工注入学习-1 (4)

举例:过滤空格 select/**/name/**/from/**/user/**/where/**/id=\'kk\' 或 select(name)from(user)where(id=\'kk\')通过这种方法就会规避对空格的过滤;过滤括号和引号select name from user wehere id=0x6b6b0x6b6b(kk的十六进制)

限制查询长度

由于SQL注入过程中需要构造较长的SQL语句,因此,一些特定的程序可以使用限制用户提交的请求内容的长度来达到防御SQL注入的目的,但这种效果并不好。

// 接收参数text if(isset($_GET[\'text\']) && strlen($_GET[\'text\']) < 10){ $text=$_GET[\'text\']; } else { echo "输入内容不符规范"; } 设置数据库权限

根据程序要求为特定的表设置特定的权限,如:某段程序对某表只需具备select权限即可,这样即使程序存在问题,恶意用户也无法对表进行update或insert等写入操作。

限制目录权限

WEB目录应至少遵循“可写目录不可执行,可执行目录不可写”的原则,在次基础上,对各目录进行必要的权限细化。

限制数据类型

因为PHP语言没有严格的限制数据类型的定义例如:“ID=1 就默认ID为Intger ; name=kk 默认name为string”在PHP的弱类型管理中这是不安全的。

举例:

// 接收参数text if(isset($_GET[\'text\'])){ $text=$_GET[\'text\']; } // 拼接sql语句并执行 $sql="SELECT * FROM admin WHERE uid=\'$text\' LIMIT 0,1"; echo \'SQL拼接结果:\'.$sql; echo \'<hr>\'; // 执行sql语句并返回结果 $result=mysqli_query($conn, $sql);

这里的text参数没有限制我们的输入,理论上我们的输入应该限制为“Intger”;当text接到\' union select 1,database(),version(),4; -- +参数后就会自动推导text为“String”类型并拼接为SQL语句。

这里可以使用is_numeric() \ ctype_digit()函数判断数据类型

is_numeric():检测变量是否为数字或数字字符串;指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE。

if(isset($_GET[\'text\']) && is_numeric($_GET[\'text\'])){ $text=$_GET[\'text\']; } else { echo "输入内容不符规范"; }

ctype_digit():纯数字检测;对指定的变量检测判断是否为连续且纯数字的字符串(字符串离全为数字)。

if(isset($_GET[\'text\']) && ctype_digit($_GET[\'text\'])){ $text=$_GET[\'text\']; } else { echo "输入内容不符规范"; }

缺陷:

这里只可以有效的预防数字型的注入点,而String类型的注入点此方法则无效。

限制特殊字符

在字符型注入点,任何恶意的SQL攻击都会包含一些特殊的字符,例如空格、括号、引号……等。如果存在敏感的特殊字符,需要使用字符转义。

使用转义字符函数,防止SQL注入

过滤特殊字符函数:

function safe_replace($string)   {   $string = str_replace(\'%20\', \'\', $string);   $string = str_replace(\'%27\', \'\', $string);   $string = str_replace(\'%2527\', \'\', $string);   $string = str_replace(\'*\', \'\', $string);   $string = str_replace(\'"\', \'&quot;\', $string);   $string = str_replace("\'", \'\', $string);   $string = str_replace(\'"\', \'\', $string);   $string = str_replace(\';\', \'\', $string);   $string = str_replace(\'<\', \'&lt;\', $string);   $string = str_replace(\'>\', \'&gt;\', $string);   $string = str_replace("{", \'\', $string);   $string = str_replace(\'}\', \'\', $string); …… …… …… ……   return $string;   }

mysql_real_escape_string()函数:

对一些例如单引号、双引号、反斜杠等特殊字符添加一个反斜杠以确保在查询这些数据之前,用户提供的输入是干净的。但要注意,你是在连接数据库的前提下使用这个函数。

addslashes()

这个函数的原理跟mysql_real_escape_string()相似。但是当在php.ini文件中,“magic_quotes_gpc“的值是“on”的时候,就不要使用这个函数。magic_quotes_gpc 的默认值是on,对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),因为这样会导致双层转义。你可以使用get_magic_quotes_gpc()函数来确定它是否开启。

htmlentities()

这个函数对于过滤用户输入的数据非常有用。它会将一些特殊字符转换为HTML实体。例如,用户输入<时,就会被该函数转化为HTML实体<(&lt),输入>就被转为实体&gt.(HTML实体对照表:),可以防止XSS和SQL注入攻击。

htmlspecialchars()

在HTML中,一些特定字符有特殊的含义,如果要保持字符原来的含义,就应该转换为HTML实体。这个函数会返回转换后的字符串,例如‘&’ (ampersand) 转为’&amp‘(ps:请参照第三点中的实体对照表链接)

strip_tags()

这个函数可以去除字符串中所有的HTML,JavaScript和PHP标签,当然你也可以通过设置该函数的第二个参数,让一些特定的标签出现。

笔者在学习SQL注入期间了解的注入防御策略很少,可能也是实践的操作还是太少、代码基础仍有欠缺……By:Mirror王宇阳

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzfpdy.html