手把手带你理解 SQL 注入之报错注入:没有回显位如何获取数据库信息 大家好最近在学习 SQL 注入。上一篇文章我们学习了 UNION 联合查询注入。通过 UNION我们能够把数据库中的内容显示到页面上。但是现实中很多网站并没有回显位。例如UNION SELECT 1,2,3执行成功了页面却什么都没有显示。那么问题来了攻击者还能获取数据库信息吗答案是可以。这就是今天要学习的内容——报错注入Error-Based SQL Injection。什么是报错注入顾名思义利用数据库返回的错误信息获取数据。正常情况下数据库报错只是提示程序员SQL语句有问题但是某些数据库函数在报错时会把我们构造的数据一起显示出来。攻击者正是利用这一特点获取数据库信息。【图1报错注入原理图】为什么会出现报错注入先看一个例子。正常查询SELECT * FROM users WHERE id1;用户访问?id1页面正常显示。如果存在注入漏洞攻击者提交特殊参数数据库执行过程中出现异常而网站又将错误信息直接返回给用户。此时数据库报错 ↓ 错误信息显示到页面 ↓ 攻击者看到报错内容于是敏感数据就可能泄露。UNION注入与报错注入有什么区别UNION注入需要回显位、页面必须能显示查询结果。例如用户名admin 密码******直接显示出来。报错注入利用错误信息显示数据即使没有正常回显只要错误信息能显示出来依然可能获取数据库内容。【图2UNION与报错注入对比图】报错信息为什么会泄露数据很多数据库函数会把参数内容写进错误信息。例如某些函数执行失败时XPATH syntax error: security这里的security本来是数据库名称。却被显示到了错误信息中。攻击者看到后就获得了数据库名称。报错注入的利用思路整个流程其实与 UNION 注入很像。只是获取数据的方式不同。利用流程发现注入点 ↓ 确认存在报错回显 ↓ 获取数据库名 ↓ 获取表名 ↓ 获取字段名 ↓ 获取数据【图3报错注入完整流程图】第一步获取数据库名攻击者首先希望知道当前数据库叫什么名字因为后续所有操作都围绕数据库展开。数据库中通常存在用户表 订单表 新闻表 管理员表只有知道当前数据库才能继续向下收集信息因此第一步通常是获取数据库名称。页面可能出现Database: security或者XPATH error: security此时数据库名 security第二步获取表名知道数据库名称后。接下来需要知道数据库中有哪些表。例如users admin news orders这些表记录着不同的数据。攻击者会重点关注users admin因为里面通常保存账号信息。【图4数据库结构示意图】第三步获取字段名找到目标表后。继续查看字段结构。例如users表id username password email通过字段名。攻击者就能知道哪些数据值得关注。例如username password显然是重要信息。第四步获取数据知道表名、字段名、之后。攻击者便会尝试读取数据内容。例如admin 123456或者admin 加密后的密码至此完成信息收集。报错注入为什么危险很多开发人员认为页面不显示查询结果就安全了实际上并非如此。如果网站仍然返回详细错误信息。攻击者依然能够获取数据库名 获取表名 获取字段名 获取数据因此关闭数据库报错信息展示也是重要的安全措施之一。如何防御报错注入核心思路依旧是不要相信用户输入。常见做法参数化查询、不要拼接SQL语句、使用预编译机制。输入过滤限制特殊字符输入。例如’ ; – #等敏感字符。关闭详细错误信息用户只能看到系统异常而不是SQL错误详情这样即使出现问题攻击者也无法通过报错获取数据。最小权限原则数据库账号不要拥有过高权限即使出现漏洞损失也会降低很多。学习时容易出现的误区很多新手刚接触报错注入时。喜欢背各种利用语句。实际上更重要的是理解为什么会报错 ↓ 为什么报错信息会显示数据 ↓ 为什么攻击者能利用这些数据理解原理后面对不同数据库和不同环境。才能举一反三。总结报错注入本质上是利用数据库异常信息 泄露数据库内容它解决了 UNION 注入在无回显环境下无法直接获取数据的问题。整个利用流程依然是发现注入点↓获取数据库名↓获取表名↓获取字段名↓获取数据