books

267 阅读4分钟

《SQL注入攻击与防御》-第二版

第1章:什么是SQL注入

SQl注入是这样的一种漏洞:应用程序在向后台数据库传递SQL查询时,如果为攻击者提供了影响该查询的能力,就会引发SQL注入。

第2章:SQL注入测试

常见sql 错误

1.sql server错误

  • a)在参数后面加单引号:
eg:http://www.victim.com/showproducts.aspx?category=attacter'
  • b)通过字符串转换为整数来产生错误:
eg:http://www.victim.com/showproducts.aspx?category=bikes' and 1=0/@@version;--  

当该操作失败的时候数据库会显示出变量的内容。可以适用该技术显示数据库中的任何变量。

eg:eg:http://www.victim.com/showproducts.aspx?category=bikes' and 1=0/user;--
  • c)还可以用一些技术显示数据库执行的语句信息,例如:having 1=1例子如下: 1)
http://www.victim.com/showproducts.aspx?category=bikes' having 1=1

则会报错如下:column 'products.productid' is invalid in the select list.....
说明:这里将having子句与group by子句结合使用。也可以在select语句中使用having子句过滤group by返回的记录。group by要求select语句选择的字段是某个聚合函数的结果或者包含在group by子句中。如果该条件不满足,那么数据库会返回一个错误,显示出该问题的第一列。所以可以使用该技术和group by来枚举select语句中的所有列。

eg:http://www.victim.com/showproducts.aspx?category=bikes'  group by productid having '1'='1 

则响应结果为:column 'products.name' is invalid in the select list.....
;同理可以枚举所有的列,eg:www.victim.com/showproduct…' group by productid,name having '1'='1 则响应结果为column 'products.price' is invalid in the select list.....

2.mysql 错误

a)下列错误通常表示存在mysql注入漏洞:
warning:mysql_fetch_array():supplied argument is not a valid mysql result resource in /var/www/victim.com/showproduct.php on line 8

确认sql注入

1.内联SQL注入

  • 定义:指向查询注入一些SQL代码后,原来的查询仍然会全部执行。
eg:select * from administors where username='' and password='' or '1'='1';

由于存在永真条件,上面的语句就会查询出所有的行.

2.终止式SQL注入

定义:攻击者在注入SQL代码时,通过将原查询语句的剩余部分注释掉,从而成功结束原来的查询语句。
说明:SQL server,oracle和postgresql中的注释符号:--用于单行注释;/* /用于多行注释
mysql中的注释符号:--和#都用于单行注释;/
*/用于多行注释

eg: select * from adminstrators where username ='admin'/*' and password = '*/'';

上面的语句将会成功绕过身份验证机制并且只返回包含admin用户的行。

3.时间延迟

测试应用程序是否存在sql注入漏洞时,经常发现某一潜在的漏洞难以确认,对于这种情况,要想识别漏洞,可以向数据库注入时间延迟,并检查服务器的响应是否也已经产生了延迟。 SQLserver数据库中的卷尺的内置命定:waitfor delay 'hours';

eg:http://www.vicitim.com/basket.aspx?uid=45;waitfor delay '0:0:5';--

上面的请求表示向服务器发送请求,服务器的响应大概要花5秒。

第3章:复查代码中的SQL注入

危险的编码行为

ResultSet rs = s.executeQuery("SELECT * from table where field = '"+request.getParameter("input")+"'"); 这种对数据没有做校验直接当参数传递的就是危险的代码

危险的函数

  • mssql_query():向当前使用的数据库发送一个查询。
  • mysql_query():向当前使用的数据库发送一个查询。
  • mysql_db_query():选择一个数据库,在该数据库上执行一个查询。
  • oci_parse():在语句执行之前对其进行解析(在oci_execute()/ociexecute()之前)。
  • ora_parse():语句在执行之前进行解析(在ora_exec()之前)。
  • mssql_bind():向存储过程添加一个参数(在mysql_execute()之前)。
  • mssql_execute():执行一个存储过程。
  • odbc_prepare():准备一条执行语句(在odbc_execute()之前)。
  • odbc_execute():执行一条sql语句。
  • odbc_exec():准备并执行一条SQL语句。
  • pg_query():执行一个查询。
  • pg_exec():出于兼容性原因依然可用,但建议用户使用新的函数名。
  • pg_send_querey():发送一个异步查询。
  • pg_send_querey_params():向服务器提交一个命令并分离参数,无须等待结果。
  • pg_query_params():向服务器提交一个命令并等待结果。
  • pg_send_prepare():发送一个请求以创建一个具有制定参数的预备语句,无须等待完成。
  • pg_prepare():发送一个请求以创建一个具有制定参数的预备语句并等待完成。
  • pg_select():根据指定的assoc_array选择记录。
  • pg_update():用数据更新与指定条件匹配的记录。
  • pg_insert():将assoc_array的值插入到指定的表中。
  • pg_delete():根据assoc_array中指定的键和值删除表中的记录。

第4章:利用SQL注入

获取标志信息

  • SQL Server:select @@version
  • Mysql:select @@version 和 select version()
  • oracle:select banner from vversion 和 select banner from vversion where rownuum=1
  • postgresql:select version()