文件上传漏洞简单介绍
一、文件下载漏洞介绍
一些网站由于业务需求,往往需要提供文件查看或文件下载功能,但若对用户查看或下载的文件不做限制,则恶意用户就能够查看或下载任意敏感文件,这就是文件查看与下载漏洞。
二、方式
2.1、一般链接形式:
download.php?path=
down.php?file=
data.php?file=
download.php?filename=
例:下载pikachu配置文件
或者包含参数:
&Src=
&Inputfile=
&Filepath=
&Path=
&Data=
2.2、思路:
(1)下载常规的配置文件,例如: ssh,weblogic,ftp,mysql等相关配置
(2)下载各种.log文件,从中寻找一些后台地址,文件上传点之类的地方,如果运气好的话会获得一些前辈们的后门。
(3)下载web业务文件进行白盒审计,利用漏洞进一步攻入服务器。
尝试读取/root/.bash_history看自己是否具有root权限。如果没有的话。我们只能按部就班的利用../来回跳转读取一些.ssh下的配置信息文件,读取mysql下的.bash_history文件。来查看是否记录了一些可以利用的相关信息。然后逐个下载我们需要审计的代码文件,但是下载的时候变得很繁琐,我们只能尝试去猜解目录,然后下载一些中间件的记录日志进行分析。
如果我们遇到的是java+oracle环境
可以先下载/WEB-INF/classes/applicationContext.xml 文件,这里面记载的是web服务器的相应配置,然后下载/WEB-INF/classes/xxx/xxx/ccc.class对文件进行反编译,然后搜索文件中的upload关键字看是否存在一些api接口,如果存在的话我们可以本地构造上传页面用api接口将我们的文件传输进服务器
如果具有root权限
在linux中有这样一个命令 locate 是用来查找文件或目录的,它不搜索具体目录,而是搜索一个数据库/var/lib/mlocate/mlocate.db。这个数据库中含有本地所有文件信息。Linux系统自动创建这个数据库,并且每天自动更新一次。当我们不知道路径是什么的情况下,这个可以说是一个核武器了,我们利用任意文件下载漏洞mlocate.db文件下载下来,利用locate命令将数据输出成文件,这里面包含了全部的文件路径信息。
locate 读取方法: locate mlocate.db admin
可以将mlocate.db中包含admin文件名的内容全部输出来
(4)常见利用文件
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_ras.keystore
/root/.ssh/known_hosts //记录每个访问计算机用户的公钥
/etc/passwd
/etc/shadow
/etc/my.cnf //mysql配置文件
/etc/httpd/conf/httpd.conf //apache配置文件
/root/.bash_history //用户历史命令记录文件
/root/.mysql_history //mysql历史命令记录文件
/proc/mounts //记录系统挂载设备
/porc/config.gz //内核配置文件
/var/lib/mlocate/mlocate.db //全文件路径
/porc/self/cmdline //当前进程的cmdline参数
三、文件下载漏洞修复
(1)过滤".",使用户在url中不能回溯上级目录
(2)正则严格判断用户输入参数的格式
(3)php.ini配置open_basedir限定文件访问范围
四、文件上传简介
1、文件上传(File Upload)是大部分web应用都具备的功能,例如用户上传附件、修改头像、分享图片视频等
2、正常的文件一般是文档、图片、视频等,Web应用收集之后放入后台存储,需要的时候再调用出来返回
3、如果恶意文件如PHP、ASP等执行文件绕过eb应用,并顺利执行,则相当于黑客直接拿到了webshell
4、一旦黑客拿到webshell,则可以拿到Web应用的数据,删除web文件,本地提权,进一步拿下整个服务器甚至内网
5、SQL注入攻击的对象是数据库服务,文件上传漏洞主要攻击web服务,实际渗透两种相结合,达到对目标的深度控制
web service和后端通过fast_cgi协议通信
web service和前段通过http或https协议通信
五、低安全上传漏洞
点击查看代码
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
?>
5.1、蚁剑连接
选择一句话的PHP脚本上传
打开蚁剑输入脚本所在路径,获取网站
双击URL就能看见网站目录了
5.2、冰蝎连接
注意:冰蝎只能使用自身带的脚本
打开冰蝎输入脚本所在路径,获取网站
双击打开后功能比蚁剑多
六、中安全文件上传漏洞
中安全级别对文件的MIME和文件大小做了限制
点击查看代码
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
// Is it an image?
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
6.1、MIME介绍
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。客户端和服务器端通过MIME类型约定那种资源用那种应用程序打开。
在HTTP中设定MIME类型的方法是通过Response对象的ContentType属性。
每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
6.2、常见的MIME类型
超文本标记语言文本 .html text/html
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
PDF文档 .pdf application/pdf
Microsoft Word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
任意的二进制数据 application/octet-stream
通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件。
第一个参数是表单的 input name,第二个下标可以是 "name", "type", "size", "tmp_name" 或 "error"。就像这样:
$_FILES["file"]["name"] - 被上传文件的名称
$_FILES["file"]["type"] - 被上传文件的类型
$_FILES["file"]["size"] - 被上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"] - 由文件上传导致的错误代码
分析代码逻辑:首先会获取到前端的提交请求,然后定义了一个数组(定义图片上传指定类型),然后通过upload_sick函数对上传的文件进行一定的检查。
分析upload_sick函数(定义在uploadfunction.php文件里面)存在漏洞的的原因是因为 $ _FILES() 这个全局的方法是通过浏览器http头去获取的content-type,content-type是前端用户可以控制的。容易被绕过。
上传一张正常的符合标准的图片,对其content-type进行抓包操作。可见正常上传符合要求的图片中数据包中content-type为image/png对比符合条件,而php文件则不符合条件返回文件类型错误。
开启代理功能拦截数据
将MIME类型修改为网站识别的image/jpeg再转发
最后成功转发
七、高安全上传漏洞
点击查看代码
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
// Is it an image?
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
7.1、代码注入绕过getimagesize()
getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息,如果用这个函数来获取类型,从而判断是否是图片的话,会存在问题。
语法格式:
array getimagesize ( string $filename [, array &$imageinfo ] )
getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。
7.2、文件包含漏洞之文件上传漏洞利用
方法一:CMD方法,copy test.png/b+1.php/a muma.png
方法二:直接使用工具(edjpgcom.exe)增加备注写入一句话木马。
点击查看代码
<? fputs(fopen("shell20.php","w"),'<?php @eval($_POST[mima]);?>')?>
意思是生成shell20.php文件,文件内容包含一句话马
方法三:直接伪造头部
决定文件是否是jpeg格式?
二进制形式打开文件,文件开始字节为FFD8,文件结束两字节为FF D9。则初步判定文件为jpeg。
jpeg的SOI(start ofimage) 为ff d8,EOD(end of image)为ff d9
注意:通过修改脚本文件后缀去上传是没有效果的,因为这个函数会去检测图片格式。
文件上传后通过文件包含漏洞利用
如果出现上图所示,服务器中还是没有生成文件,在我多次尝试换图片,检测代码还是无效的情况下,最终换了别的浏览器尝试,结果就可以了
八、其他文件上传绕过的方法
8.1、路径绕过白名单
0x00截断或x.php%00.jpg
不过这需要对文件有足够的权限,如:上传的文件名save_path后面改成../upload/x.php%00其实就是改变文件路径%00后面的数据直接丢弃.
8.2、黑名单
(1)文件名大小写绕过
(2)名单绕过
用黑名单里没有的名单进行攻击,比如黑名单里没有.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess后缀文件之类
(3)特殊文件名或文件夹绕过(windows)
还有比如发送的http 包里把文件名改成test.asp. 或test.asp_(下划线为空格),这种命名方式在windows 系统里是不被允许的,所以需要在burp 之类里进行修改,然后绕过验证后,会被windows 系统自动去掉后面的点和空格,但要注意Unix/Linux 系统没有这个特性。
(4)双后缀名绕过:x.pphphp
(5)::$DATA绕过
是Windows下NTFS文件系统的一个特性,即NTFS文件系统的存储数据流的一个属性 DATA 时,比如x.php::$DATA上传成功后文件名其实就是x.php