SQL注入缺陷在2013年的OWASP Top10清单中排名第一,大多数Web应用使用了某种数据库,SQL语言是其中最流行的。在 SQL注入攻击中,攻击者通过改写表单输入项参数、查询参数,在参数中添加SQL语句,构造含SQL语句的请求,发给服务器。这篇文章里,我们会测试Web应用的一些输入项,看是否存在SQL注入漏洞。
实践
登陆到 DVWA 并执行下列操作:
-
跳转到 SQL Injection 页面
跟上一篇文章类似,我们先来走一遍正常的请求,在User ID处输入数字 1,然后点击** Submit **,通过查看结果,我们猜测,应用根据输入的ID值查询数据库中是否有用户的ID匹配1,如果有则返回该结果。
下一步,我们测试异常输入的响应结果,比如输入双引号中的内容“ 1' ”,然后提交,得到的响应结果为:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1''' at line 1
这个错误信息告诉我们,刚才的输入破坏了一个正常的查询语句,间接告诉我们,这里可能存在SQL注入的可能。
此时返回 DVWA/SQL Injection 页面
-
为了确认这里是否真的有一个基于错误的SQL注入点,我们尝试另外一个查询输入: 1'' (这次ID后面跟两个撇号)
这次没有报错,也就意味着这里确实是一个应用的注入点。
-
现在,我们尝试一个非常基本的SQL注入攻击,这次在文本框输入: ' or '1'='1,然后点击提交:
如此一来,我们看到了注册到数据库的所有用户清单。
总结
SQL注入常发生在输入数据没有经过校验或清洗,就被作为查询语句的一部分提交给数据库了。我们假设应用的服务器端代码 (PHP代码)构造一个查询语句,如:
$query = "SELECT * FROM users WHERE id='".$_GET['id']. "'";
发送到服务器的id字段的参数会被集成到这条查询语句,替换形参id,如此,我们得到:
$query = "SELECT * FROM users WHERE id='"."1". "'";
因此,当我们输入恶意字符串,例如我们前面输入的,跟查询语句拼接后就变成了:
$query = "SELECT * FROM users WHERE id='"."' or '1'='1"."'";
把上面的语句连起来就是:
$query = "SELECT * FROM users WHERE id='' or '1'='1'"
这句查询语句的意思是,从users表里面查询所有记录(如果user id 等于空或者 1 等于 1 成立,当然,1永远等于1,这句话是永远成立的,这个条件语句永远为真)。我们输入的第一个撇号关闭了原来的SQL语句,之后我们又添加了新的SQL语句(没有加右撇号,是因为原来的SQL最右侧本来就有一个)。
一个 SQL 攻击带来的危害往往不只是查看到用户名这么简单。通过利用这个漏洞,攻击者可能会执行恶意命令和提权操作,进而危害到整个服务器。攻击者还可能会获取整个数据库的数据,包括系统级的用户名和密码。 基于被攻击的服务器在整个网络中所处的位置、角色和配置情况,利用这个 SQL 注入漏洞可能会危及整个网络和内部设施。