SQL注入漏洞介绍

在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是SQL注入漏洞。

SQL 注入式攻击技术,一般针对基于 Web 平台的应用程序造成 SQL 注入攻击漏洞的原因,是由于程序员在编写 Web 程序时,没有对浏览器端提交的参数进行严格的过滤和判断。用户可以修改构造参数,提交 SQL 查询语句,并传递至服务器端,从而获取想要的敏感信息,甚至执行危险的代码或系统命令。

虽然 SQL 注入攻击技术早已出现,但是时至今日仍然有很大一部分网站存在 SQL 注入漏洞,在本章开篇中进行的入侵检测中就发现了各大门户网站同样存在SQL 注入漏洞,更别说一些小网站了。由于 SQL 漏润存在的普遍性,因此 SQL 入侵攻击技术往往成为黑客入侵攻击网站渗透内部服务的首选技术,其危害性非常大。

下面对目前的各种流行 SQL 注入攻击技术进行总结,以便网络安全管理人员和工作者更加深入地了解这种攻击与防御方法。

注入式攻击的原理

注入式攻击的根源在于,程序命令和用户数据(即用户输入)之间没有做到泾渭分明。这使得攻击者有机会将程序命令当作用户输入的数据提交给 Web 程序,以发号施令,为所欲为(注:注入最终是数据库,与脚本、平台无关)。

总之一句话:注入产生的原因是接受相关参数未经处理直接带入数据库查询操作。

为了发动注入攻击,攻击者需要在常规输入中混入将被解释为命令的“数据”,想要成功,必须要做三件事情:

  • 确定Web应用程序所使用的技术

注入式攻击对程序设计语言或者硬件关系密切,但是这些可以通过适当的踩点或者索性将所有常见的注入式攻击都搬出来逐个试一下就知道了。为了确定所采用的技术,攻击者可以考察 Web 页面的页脚,查看错误页面,检查页面源代码,或者使用诸如 Nessus、AWVS、APPSCAN 等工具来进行刺探。

  • 确定所有可能的输入方式

Web 应用的用户输入方式比较多,其中一些用户输入方式是很明显的,如 HTML 表单;另外,攻击者可以通过隐藏的 HTML 表单输入、HTTP 头部、cookies、甚至对用户不可见的后端 AJAX 请求来跟 Web 应用进行交互。一般来说,所有 HTTP 的 GET 和 POST 都应当作用户输入。为了找出一个 Web 应用所有可能的用户输入,我们可以求助于 Web 代理,如 Burp 等。

  • 查找可用于注入的用户输入

在找出所有用户输入方式后,就要对这些输入方式进行筛选,找出其中可以注入命令的那些输入方式。这个任务好像有点难,但是这里有一个小窍门,那就是多多留意 Web 应用的错误页面,很多时候您能从这里得到意想不到的收获。

万能密码漏洞解析

大家经常听到网站万能密码登录,今天我们就来分析分析万能密码是怎么回事。先给大家来一个简单的实例:

  1. 登录页面关键代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
require '../config.php';
$adminname = $_POST['adminname'];
$adminpass = $_POST['adminpass'];
$adminpass .= "Axphp.com";
$adminpass = md5($adminpass);
$adminsql = "select * from axphp_admin where adminname='$adminname' and adminpass='$adminpass'";
$adminery = mysql_query($adminsql, $config);
$adminnum = mysql_num_rows($adminery);
if ($adminnum == "1") {
setcookie("admin", "Y", time() + 3600, '/');
setcookie("admin_name", $adminname, time() + 3600, '/');
header("location:axadmin.php");
} else {
header("location:axphp.php");
}
?>
1
$adminsql = "select * from axphp_admin where adminname='$adminname' and adminpass='$adminpass'";

我们发现没有做任何过滤直接拿前端传入的数据,这样拼接的 SQL 会存在注入漏洞。

1)先输入正常数据(账号admin,密码admin),效果如下:

733007d88171f2ead549ef362c4941c1.png

150e121789c8e535341bbb3cbbd9f2e0.png

查询的SQL语句为:

1
select * from axphp_admin where adminname='admin' and adminpass='admin'

2)输入注入数据:

如图,即用户名为:用户名:’or 1=1 #,密码可随便输入

dee795e02a077323b41c4a6a81645357.png

85fdeb8d3c5fa55984f84efcbe73101f.png

查询的SQL语句为:

1
select * from axphp_admin where adminname=''or 1=1 #' and adminpass='aaa'
  1. 现在我们来分析一下:’ or 1=1 # 为什么能登录系统,原因如下:

1) select * from axphp_admin where adminname=''or 1=1 首先看这条查询语句,查询所有来自axphp_admin 表的数据, 条件 name 为空或者 1=1,这两个条件只要一个满足就为真,adminname=''or 1=1现在 1=1 就是真而且是是没任何作用的真,那么最终数据库执行的语句相当于 select * from axphp_admin

2)因为adminname值中输入了“#”注释符,后面语句被省略而登录成功。(常用的注释手法:“#”与“—+”)

3)不同的程序万能密码也是不一样的,如 ASP 的万能密码是'or'='or',PHP的万能密码是'or 1=1 #

手工检测SQL注入点

最常用的 SQL 注入点判断方法,是在网站中寻找如下形式的网页链接。

http://www.abc.com/sss.asp?id=xx (ASP)

http://www.abc.com/sss.php?id=xx (PHP)

http://www.abc.com/sss.jsp?id=xx (JSP)

http://www.abc.com/sss.aspx?id=xx (ASPX)

http://www.abc.com/sss/new/id/8 (伪静态)

http://www.abc.com/sss/new/php-8.html (伪静态)

其中的“xx”可能是数字,也有可能是字符串,分别被称为整数类型数据和字符型数据。

如何判断某个网页链接是否存在 SQL 注入漏洞呢?通常有两种检测方法。

  1. “单引号”法

第一种检测 SQL 注入漏洞是否存在的方法是“单引号”法。方法很简单,直接在浏览器地址栏中的网址链接后加上一个单引号,如果页面不能正常显示,浏览器返回一些异常信息,则说明该链接可能存在注入漏洞。

  1. “1=1 和 1=2” 法

很多时候检测提交包含引号的链接时,会提示非法字符,或者直接不返回任何信息,但这并不等于不存在 SQL 注入漏洞。此时可使用经典的“1=1 和 1=2”法进行检测。方法很简单,就是直接在链接地址后分别加上 and 1=1 和 and 1=2 进行提交,如果返回不同的页面,那么说明存在 SQL 注入漏洞。

SQL注入的防护方式

  1. 永远不要信任客户端提交的数据,一定要对客户端提交的数据进行校验,校验可以考虑数据类型,字符长度或者正则表达式等方式。

  2. 对客户端提交的数据进行转义,例如将” ‘ “转义为” ‘ “。

  3. 采用预编译绑定变量的SQL语句而不是直接拼接SQL语句。

  4. 避免在生产环境中,直接输出错误信息,因为这些错误信息有可能被攻击者利用。

  5. 严格执行数据库账号权限管理。

  6. 对用户敏感信息特别是密码做严格加密处理。

参考资料