我们将要讨论的下一类常见配置问题相当广泛。这组问题可能泄露应用所有者不打算泄露的信息,常常被攻击者利用完成更有效的Web应用攻击。这些问题的根源不在于任何特定的Web服务器扩展或者附加模块,而来源于许多不同的配置参数,所以我们将其分组处理。这一小节我们所要讨论的漏洞包括:
·文件、路径和用户泄露
·状态页面信息泄露
·默认错误页面
文件、路径和用户泄露
网站信息泄露的常见根源之一是由于管理不善,服务器根目录上散布着零散的文件和其他可能提供信息的小部件。Web服务器和应用刚刚投产时,一切都很纯净——文件和文件夹结构是一致的。但是随着时间的推移,由于应用程序修改和升级以及配置的更改,Web根目录开始变得零乱。文件四处散放,文件夹和旧的应用被人遗忘。这些丢失和被遗忘的文件对于攻击者来说可能是有用的珍宝。你可以使用多种方法找到这些信息,接下来我们就此进行讨论。
HTML源代码: 攻击者寻找的第一个位置常常是容易查看的Web应用/网页HTML源代码。HTML源代码可能在注释(寻找<!--标记)、包含文件(查找.inc文件扩展)等地方各种有趣的信息。
目录猜测: 第一种方法最简单——用Web结构中常见的文件夹名称列表进行猜测。例如,我们知道许多网站有“admin”文件夹。所以简单地猜测并且请求“http://www.site.com/admin/”,攻击者可能很容易看到网站的管理界面。我们在表8-3中列出了文件和文件夹猜测生成的最常见HTTP响应码。
注意 关于HTTP状态码的信息的链接可以在本章结尾处的“参考与延伸阅读”小节中找到。
我们现在通过一个目录猜测攻击的步进式示例来说明一些关键点。我们首先用常见名“stats”发现目标的Web根目录下的一个文件夹。当我们尝试访问这个文件夹时,会看到一个友好的403 Forbidden响应:“Directory Listing Denied——This Virtual Directory does not allow content to be listed(目录列表被拒绝——这个虚拟目录不允许列出内容)”。
这个响应并不意味着该目录受到保护,只是我们无法查看其中的文件列表而已。因此,如果一个文件存在于这个目录下,我们仍然能够访问。我们所需要做的是一些基本的勘查和猜测。现在我们必须像网站的管理员一样思考。管理员会把什么内容放在“stats”目录中呢?是不是Web统计信息?进一步研究,我们在Google上输入inurl:/stats/+"index of"查询,找出其他网站放在“stats”目录中的常见文件。我们发现最常在这个目录下放置的文件是“stats.html”,这一点都不意外。发出对http://www.site.com/stats/stats.html的请求,我们获得成功的结果——该网站的Web统计信息。下一步是查看URL,看看能否找到有趣的东西。请求统计对攻击者可能没有多大吸引力,但是“stats”目录往往包含有潜在破坏性的信息,例如日志文件、凭据重置脚本、账户选项、配置工具等。OWASP的DirBuster是猜测目录和文件名的一种非常好的工具。
表8-3 常见HTTP响应代码
常见文件名猜测: 我们前面已经提到过,网站管理员有在Web根目录上乱放文件(旧代码、过时文件和其他不应该在那里的东西)的坏名声。你应该利用这种惰性来获利。大部分管理员没有意识到这些文件可能像网站的其他文件一样下载。攻击者所需要知道的就是文件名称和所在的位置。这种攻击比你所想象的容易得多,理解Web服务器的攻击和防御同样重要。
图8-3 目录猜测攻击揭露了Web统计页面
注意 我们将在接下来的“包含文件泄露”小节中讨论IIS上包含文件的特殊情况。
例如,许多开发人员使用流行的源代码控制系统——并发版本系统(Concurrent Versions System,CVS)。这个软件让开发人员很轻松地管理多个在同一软件上协作的人。CVS将在整个文件夹结构中搜索源代码并且添加自己的/CVS/子文件夹。这个子文件夹包含三个文件——Entries、Repository和Root,CVS用它们控制目录中源代码的变化。CVS源代码树的例子如下:
/WebProject/ /WebProject/File1.jsp /WebProject/File2.jsp /WebProject/CVS/Entries /WebProject/CVS/Repository /WebProject/CVS/Root /WebProject/Login/Login.jsp /WebProject/Login/Fail.jsp /WebProject/Login/CVS/Entries /WebProject/Login/CVS/Repository /WebProject/Login/CVS/Root
许多使用CVS进行Web开发的组织中都发生过这样的事情,应用一完成,开发人员或者Web管理员就将整个/WebProject/目录上传到Web服务器。现在所有CVS文件夹都存在于公共的Web根目录中,可以用http://www.site.com/CVS/Entries轻松地请求。这将会返回源代码控制下的文件夹中所有文件的列表,如图8-4所示。
图8-4 发现CVS Entries文件能够泄露许多关于Web应用的信息
另一个常见文件猜测目标是源于流行FTP客户端WS_FTP的使用。这个程序在每个文件上传的文件夹中留下一个名为WS_FTP.LOG的文件(例如,http://www.site.com/WS_FTP.LOG)。这个日志列出所有上传的文件。表8-4展示攻击者评估网站时查找的常见文件。记住,攻击者在他们的搜索中不会遗漏任何文件夹或者子文件夹!
表8-4 猜测攻击中常用的文件名
提示 对于表8-4中列出的许多文件名,简单地加上".old"、".backup"及/或".bak",也可能泄露这些文件所存在的存档版本,例如global.asa.bak或global.asa.old。前面提到的OWASP DirBuster工具对使用常见文件名识别备份文件也很有用。
时光机方法 (Wayback Machine Method):网站和应用持续变化,它们常常对架构和设计进行完全的翻新。而且,根据网站的不同,开发人员可能使用两种方法来处理这种变化。他们或者同时开发新的网站,将整个软件包投产,或者用新开发的部件逐步升级网站的各个部分。往往,在新网站开始运作时,组织会将以前的代码移到备份位置而遗忘。这些旧代码的备份产生了一个严重的安全弱点。
让我们考虑一个公司从旧的ASP平台升级到ASP.NET的情况。使用ASP.NET,这个组织能够设计和构建一个更加健壮和安全的平台。他们采取了合适的措施,测试新应用的安全漏洞并且宣布它是完全纯净的。但是在升级到ASP.NET时,他们将整个旧的ASP应用转移到Web根文件夹“backup”中。这是个大错误。现在,黑客识别出这个文件夹,并且确定文件夹中有旧版本的网站。我们的黑客浏览http://web.archive.org(时光机),这个网站完整地维护着网站的可浏览存档,如图8-5所示。
图8-5 时光机
攻击者现在进入该网站的网址,浏览存档的网站,仔细地记录遇到的页面和表单名称。他发现一个表单似乎是动态的,列出了文章的内容:http://www.site.com/article.asp?id=121879。
具备了这些信息,攻击者返回到原来的网站,试图访问http://www.site.com/backup/article.asp页面。他的聪明得到了报酬。不仅找到了这个网页,而且仍然能从公司数据库提取数据。攻击者欣喜地发现旧的应用容易遭受SQL注入攻击,结果是,他现在能够通过备份内容访问数据库。成功识别旧网站内容的其他手段包括返回缓存网页的Google搜索。有时候,甚至使用网站自己的搜索引擎也会返回极其有用的旧文件。
用户枚举: 默认情况下,Apache允许通过“~”语法识别用户主目录。因此,发送用户名请求如http://www.site.com/~root或http://www.site.com/~asimons,很容易识别有效的用户名。识别用户相当有用,例如发现系统存在一个Oracle用户,就可以引导攻击者转向某些有趣的Oracle漏洞利用程序。攻击者知道了后端上使用的数据库类型,检查SQL盲注入之类的漏洞就容易得多了。
注意 SQL注入和其他Web数据存储漏洞在第6章中讨论。
文件泄露对策
这个安全问题很容易弥补:只要保持网站目录(尤其是根目录(/))干净,并且实施适当的ACL就行了。一般来说,在Web根目录下的任何文件都可以被任何人访问,所以这是一个需要严格检查的位置。下面是其他一些措施:
·在独立的卷上部署Web根目录。这在IIS系统上特别重要。IIS历史上曾经遭受逃脱Web根目录的攻击,这种攻击通常进入%systemroot%,运行像Windows 32位命令外壳cmd.exe等有诱惑力的文件。
·将备份/存档/旧文件移到单独的文件夹,尽可能完全在网站/应用目录结构之外。如果因为某些原因做不到,对访问存储敏感文件的目录要求验证。
·不要为文件夹和文件取容易猜测的名称。例如,不要将数据目录命名为“data”。
·为了避免使用容易猜测的“~”语法进行的用户枚举,编辑Apache httpd.conf文件,确保UserDir设置为禁用(UserDir disabled)。
·用验证保护包含重要数据的文件夹。
避免文件泄露漏洞的最好方法可能是假定攻击者能够看到你的网站的整个目录结构,完全避免“不公开的安全性”。每当你发现自己有“没有人能够猜出我的文件在这里”的想法,请牢记:真的有人能猜出来。
状态页面信息泄露
Apache一度曾经有默认下可以访问的状态页面。这些页面提供服务器及其连接的有用信息的输出。现在,这些页面默认已经被禁用,但是许多部署仍然启用这一个功能。寻找状态页面非常简单,用下列请求就能在有漏洞的网站上找到它:
·http://www.site.com/server-info
·http://www.site.com/server-status
·http://www.site.com/status
下图是用上述的请求可能得到的服务器状态页面的一个例子:
状态页面信息泄露对策
和我们迄今为止讨论过的大部分Apache漏洞一样,修复这个问题很简单,只要编辑Apache服务器配置文件httpd.conf,添加如下配置就可以了:
<Location /server-info> SetHandler server-info Order deny,allow Deny from all Allow from yourcompany.com </Location> <Location /server-status> SetHandler server-status Order deny,allow Deny from all Allow from yourcompany.com </Location>
默认错误页面信息泄露
每当HTTP请求发送到Web服务器,Web服务器生成的响应中会返回HTTP状态。你可能见过的最常见的Web服务器返回状态码是404 Not Found。正如它的名称所代表的,这个响应是在HTTP客户端(例如浏览器)请求一个不存在的资源时收到的。下面的例子显示了对Apache服务器不存在的资源发起的一次手工请求,以及服务器返回的状态码:
telnet www.server.com 80 Trying www.server.com... Connected to www.server.com. Escape character is '^]'. GET /thereisnosuchfile HTTP/1.0 HTTP/1.1 404 Not Found Date: Thu, 18 Feb 2010 20:38:06 GMT Server: Apache/2.2.12 (Ubuntu) Vary: Accept-Encoding Content-Length: 290 Connection: close Content-Type: text/html; charset=iso-8858-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> </head><body> <h1>Not Found</h1> <p>The requested URL /thereisnosuchfile was not found on this server.</p> <hr> <address>Apache/2.2.12 (Ubuntu) Server at 127.0.1.1 Port 80</address> </body></html> Connection closed by foreign host.
如果你研究这里显示的响应,就会注意到Web服务器不仅返回404 Not Found HTTP状态码,而且返回让你知道所发生情况的默认网页,图8-6显示了浏览器中的这个网页。
图8-6 Apache默认的404 Not Found HTTP状态码网页
你还可能注意到了,默认网页显示了Web服务器版本(Apache/2.2.12)等信息。这种信息对于攻击者确定对服务器尝试什么攻击或者漏洞利用程序是有益的。
使用IIS和ASP.NET也会看到同样的场景。图8-7显示ASP.NET应用显示的“资源未找到”错误。服务器安装的.NET Framework的版本号显示在这个错误页面的底部。而且,如果应用抛出一个未处理的异常,错误页面将包含导致错误的代码的详细堆栈跟踪信息,例如导致错误的文件的完整路径。图8-8显示了一个带有栈跟踪信息的错误示例。
图8-7 ASP.NET的“资源未找到”错误信息
图8-8 ASP.NET的默认系统异常错误页面显示详细的栈跟踪信息,对攻击者可能有帮助
默认错误页面信息泄露对策
这个问题的解决方案非常简单:自定义Web服务器返回的错误页面。在Apache中,使用ErrorDocument指令指定错误代码和想要显示的信息来自定义错误页面。例如:
ErrorDocument 404 "Error" ErrorDocument 403 http://server/error403.html
你可以指定一个硬编码的信息或者指向脚本或者静态HTML文件的URL。在任何情况下,关键的一点是在生产环境中显示尽可能少的关于错误原因的信息。
在IIS和ASP.NET,中,你可以使用应用的web.config文件中的<customErrors>元素自定义错误信息,例如:
<customErrors mode="On" defaultRedirect="error.html"> <error statusCode="404" redirect="FileNotFound.html"/> </customErrors>
<customErrors>元素有3个基本模式,可以通过mode属性配置:
·On指定启用自定义错误。如果没有指定defaultRedirect属性,用户会看到通用的错误。自定义错误向远程和本地主机用户显示。
·Off指定禁用自定义错误。详细的ASP.NET错误向远程和本地主机用户显示。
·RemoteOnly指定自定义错误仅向远程客户端显示,ASP.NET错误向本地主机用户显示。
默认值是RemoteOnly,在显示默认页面的时候不会向远程客户泄露版本信息或者栈跟踪信息。但是,Web开发人员在开发过程中常常把模式属性设置为Off,而在生产服务器上部署时忘记改回RemoteOnly或On指定自定义错误信息。你将在本章结尾处的“参考与延伸阅读”小节中找到更多关于<customErrors>元素和ErrorDocument指令的信息。
包含文件泄露
在IIS 5.x中,Web服务器默认将未知扩展名的普通文本文件返回给用户。例如,如果Web根目录下创建了一个名为test.ars的文件,从浏览器请求该文件时,将会出现一个下载提示。这是因为扩展名ARS不是已知的文件类型如ASP和HTML。这个似乎不显眼的默认设置可能导致严重的信息泄露。最常见的是下载所谓的包含(.inc)文件。
包含文件是什么?当开发人员进行ASP编码时,通常将常用的函数库放到包含文件中,这样他们可以有效地从网站/应用的其他部分调用这些函数。包含文件的位置常常可以在HTML源代码中或者通过前面讨论的文件/路径泄露漏洞中发现。下面是我们最近审计的一个网站的HTML源代码中的注释示例:
<!-- #include virtual ="/include/connections.inc" -->
掌握了路径和文件名,攻击者现在只要浏览http://www.site.com/include/connections.inc就可以请求包含文件。
瞧!响应包含了该文件的所有源代码,包括数据库用户名和密码!
<% ' FileName="Connection_ado_conn_string.htm" ' Type="ADO" ' DesigntimeType="ADO" ' HTTP="false" ' Catalog="" ' Schema="" Dim MM_Connection_STRING MM_Connection_STRING = "Driver={SQL Server};Server=SITE1;Database= Customers;Uid=sa;Pwd=sp1Int3nze!*;" %>
注意 这个Web服务器以sa用户登录,这是个坏习惯!
而且,攻击者还知道了这个应用/网站的包含文件目录,可以开始猜测其他敏感的包含文件,希望下载更加敏感的信息。
包含文件对策
有三种消除这一烦人问题的方法,评价分别是“好”、“较好”和“最好”。
好: 将所有.inc文件移出Web应用/网站结构,使标准请求无法找到它们。这个解决方案对于大型的现有Web应用不可行,因为在应用代码中的所有路径名都需要修改,以反映新的文件位置。而且,这种方法不能预防以后人们由于懒惰或是缺乏意识,再次将.inc文件放在不合适的位置。
较好: 将所有.inc文件改名为.inc.asp。这将强制.inc文件在ASP引擎中运行,客户端不能看到源代码。
最好: 将.inc扩展名与asp.dll关联。这也将强制.inc文件在ASP引擎中运行,客户端不能看到源代码。这种对策比移动文件或者改名为.asp更好,因为任何不小心被命名为.inc的文件不会再成为问题——未来的懒惰或者缺乏认识都没有关系。
注意 Microsoft的ASP引擎过去曾经受到一些漏洞的折磨,导致某些文件类型的信息泄露。虽然这些问题很早以前就为Microsoft修复,但是你永远不知道,运行那些不是设计用来直接运行的代码会造成什么影响。值得注意的是,这个问题在IIS 6.0中已经得以修复;当你从IIS 6.0 Web服务器中请求带有未定义MIME类型扩展名的文件时,将会返回一个HTTP 404 File Not Found错误。