SQL 注入漏洞简介

SQL 注入漏洞产生原因及危害

SQL 注入漏洞是指攻击者通过浏览器或者其他客户端将恶意 SQL 语句插入到网站参数中,而网站应用程序末对其进行过滤,将恶意 SQL语句带入数据库使恶意 SQL 语句得以执行,从而使攻击者通过数据库获取敏感信息或者执行其他恶意操作。
SQL 注入漏洞可能会造成服务器的数据库信息泄露、数据被窃取、网页被篡改,甚至可能会造成网站被挂马、服务器被远程控制、被安装后门等。

SQL 注入漏洞示例代码分析

以下是 SQL 注入漏洞的示例代码:

1
2
3
4
$id=$_GET['id'];
$sql-"SELECT * FROM users WHBRE id=$id LIMIT O,1";
$result=mysql_query(fsql);
$row=mysql_fetch_array($result);

中间件通过 $_GET['id'] 获取用户输入的 id 参数的值,并赋值给$id 这个变量。$id 在后面没有经过任何过滤,直接拼接到 SQL 语句中,然后在数据库中执行了此 SQL 语句。
如果用户提交 index.php?id=1 and 1=1,那么后面的 SQL 语句就变为 SELECT * FROM users WHERE id=1 and 1=1 LIMIT 0,1,会有正常的结果返回。
如果用户提交 index.php?id=1 and 1=2,那么后面的 SQL 语句就变为 SELECT * FROM users WHERE id=1 and 1=2 LIMIT 0,1,会有不正常的结果返回。

SQL注入分类

SQL注入按照数据类型分为数字型注入字符型注入。注入点的数据类型为数字型时为数字型注入,注入点的数据类型为字符型时为字符型注入。
SQL注入按照服务器返回信息是否显示分为报错注入和盲注。如果在注入的过程中,程序将获取的信息或者报错信息直接显示在页面中,这样的注入为报错注入;如果在注入的过程中,程序不显示任何SQL报错信息,只能通过精心构造SQL语句,根据页面是否正常返回或者返回的时间判断注入的结果,这样的注入为盲注。

数字型注入

数字型注入就是注入点的数据类型是数字型,没有用单引号引起来。数字型注入的典型示例代码如下:

1
2
3
4
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"; //$id没有单引号
$result=mysql_query($sql);
$row=mysql_fetch_array($result);

WHERE id=$id这个SQL语句的子句中,$id变量没有用单引号或者双引号引起来,而是直接拼接到了后面,这样的注入就是典型的数字型注入。

判断数字型注入的方法如下:

输入单引号,不正常返回。

如果用户提交 index.php?id=1',那么后面的SQL语句就变为 SELECT * FROM users WHERE id=1' LIMIT 0,1,SQL语句本身存在语法错误,会有不正常的结果返回。

输入and 1=1,正常返回。

如果用户提交 index.php?id=1 and 1=1,那么后面的SQL语句就变为 SELECT * FROM users WHERE id=1 and 1=1 LIMIT 0,1,会有正常的结果返回。

输入and 1=2,不正常返回

如果用户提交 index.php?id=1 and 1=2,那么后面的SQL语句就变为 SELECT * FROM users WHERE id=1 and 1=2 LIMIT 0,1,会有不正常的结果返回。
数字型注入的注入点主要通过上面3个语句来判断,如果输入的返回结果与上面相符,说明测试语句中的恶意SQL语句被带入数据库中并且成功执行,那么就可能存在数字型注入。具体有没有数字型注入,是否可以通过数字型注入获取有效信息,还需要大量的测试来验证。

字符型注入

字符型注入就是注入点的数据类型是字符型。字符型注入与数字型注入的区别就是字符型注入要用一对单引号引起来。字符型注入的典型示例代码如下:

1
2
3
4
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; //'$id'有单引号
$result=mysql_query($sql);
$row=mysql_fetch_array($result);

这个示例代码与数字型注入的示例代码基本一致,只是在后面的SQL语句拼接中,$id多了一对单引号,$id是字符型数据,这就是典型的字符型注入。

判断字符型注入的方法如下:

输入单引号,不正常返回。

如果用户提交 index,php?id=1',那么后面的SQL语句就变为 SELECT * FROM users WHERE id=1' LIMIT 0,1,SQL语句本身存在语法错误,会有不正常的结果返回。

输入'and'1'='1,正常返回

如果用户提交 index.php?id=1 'and' 1'='1,那么后面的SQL语句就变为 SELECT * FROM users WHERE id='1' and '1'='1' LIMIT 0,1,会有正常的结果返回。

输入'and'1'='2,不正常返回

如果用户提交 index.php?id=1 'and' 1'='2,那么后面的SQL语句就变为 SELECT * FROM users WHERE id='1' and '1'='2' LIMIT 0,1,会有不正常的结果返回。
字符型注入的注入点主要通过上面3个语句来判断,如果输入的返回结果与上面相符,说明测试语句中的恶意SQL语句被带入数据库中并且成功执行,那么就可能存在字符型注入。具体有没有字符型注入,是否可以通过字符型注入获取有效信息,还需要大量的测试来验证。