《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 v
version where rownuum=1
- postgresql:select version()