详解SQL报错盲注

1. SQL报错盲注介绍

SQL注入攻击(SQL Injection)是指攻击者通过构造恶意的SQL语句,插入到应用程序的输入参数中,进而达到欺骗数据库服务器执行恶意操作的目的,从而实现对数据库的任意读写权限。

而SQL报错盲注攻击则是一种常用的SQL注入技巧,其原理是通过构造不合法的SQL语句,从而引发数据库服务器的异常报错信息,从而获取有用信息。SQL报错盲注能够在不知道表结构的情况下,获取到敏感信息,如管理员密码、数据库版本、表结构等。

2. SQL报错信息利用方法

攻击者通过构造SQL语句,从而引发数据库服务器的异常报错信息。这些报错信息通常包含有敏感的数据库信息,如表结构、列名和字段类型等。攻击者可通过分析这些报错信息, 获取有用信息以实现攻击。

2.1 利用错误提示获取表信息

攻击者首先通过构造 SQL 语句引起错误提示,然后分析错误提示信息,从而获取到表信息。 具体方法如下:

SELECT id,name FROM users WHERE id=1';

上面的SQL查询语句,在执行时会因为缺少引号而报错,报错信息通常会明确地指出出错的字符。通过根据错误提示信息修正SQL语句,最终可以获取到表的信息。

SELECT id,name,password FROM users WHERE id=1";

在上例中,我们通过错误提示获取到了表名及字段名,同时还可以查看到该字段数据的一些信息,例如该字段是CHAR或VARCHAR类型等。

2.2 利用错误提示获取列信息

同理,攻击者可以根据错误提示,获取数据库列信息。当SQL语句执行时会返回一些列信息,如果SQL语句中的字段不存在就会返回错误信息。具体方法如下:

SELECT id,name,username,password FROM users WHERE id=1 and 1=2 union select 1,table_name,column_name from information_schema.columns--;

这条SQL语句将查询结果分为两个结果集,从而引起了错误提示,其中第一个结果集只有一个字段1,但它的列数和第二个结果集相同。第二个结果集可以返回表名和列名等详细信息。

2.3 利用错误提示获取管理员账户密码

攻击者可以利用 SQL 注入使 SELECT 密码等于特定字符返回错误,由此发现管理员账户的密码,这是SQL注入攻击中最危险的一种。 具体方法如下:

SELECT id,name,password FROM users WHERE name='admin' and substring(password, 1, 1) ='s';

3. SQL保护方法

3.1 参数化查询

在编写 SQL 查询时,所有的参数输入都应该使用参数化查询的方式,而且,不要使用字符串直接拼接 SQL 语句的方式,否则极易被注入攻击利用。 具体方法如下:

sql_command = "SELECT id,name,password FROM users WHERE name=? and password=?";

statement = conn.prepareStatement(sql_command);

statement.setString(1, username);

statement.setString(2, password);

以上方法就可以有效地防止 SQL 注入攻击,因为参数拼接过程中,所有的参数值都会被转译掉。

3.2 过滤输入变量

开发者开发程序时,应该对输入变量进行校验和过滤,只接受规定的输入内容,拒绝错误、非法字符的输入。这样可以有效地防止输入有害的字符进行 SQL 注入攻击。

3.3 致力于后端安全

一个安全保障的系统应该致力于后端的安全,可以对数据库进行加密、进行数据分析等,同时增加日志记录机制等等,从而全方面的进行防护。

4. 总结

对于SQL注入攻击,应该注意程序中输入变量的过滤和校验;不要使用字符串直接拼接 SQL 语句的方式,而应该目标参数化查询的方式;开发应以后端安全为重点进行开发逻辑。此外,也可以应用白名单机制来减少 SQL 注入的风险等。通常情况下,只要我们注意到进行必要的防护工具,就能防止绝大部分的 SQL 注入攻击。

数据库标签