一,文件上传漏洞的原因:
文件上传漏洞的存在主要是因为开发者未对用户上传的文件进行充分的安全验证,导致攻击者可以上传恶意文件(如 WebShell、恶意脚本等)到服务器,进而控制服务器或实施进一步攻击。
常见的成因有: 未验证文件类型和扩展名,未检测文件内容,未限制文件路径和权限,依赖黑名单而非白名单,服务器解析漏洞
常见的场景有:用户头像上传(允许用户上传头像,但未校验文件类型。),文档或图片分享平台(允许上传 PDF、图片等文件,但未检测文件内容。),CMS 或插件漏洞(内容管理系统(如 WordPress、Joomla)的插件存在上传逻辑缺陷。),API 文件上传接口(后端 API 接收文件时,未对来源和内容进行校验。),压缩包解压漏洞(允许上传 ZIP 压缩包并自动解压,未检查压缩包内文件。)
---------------------------------------------------------------------------------------------------------------------------------
二,案例分析
第一篇:upload-labs靶场(1-21关)
pass01(只使用javascrip过滤)
分析:只使用了JavaScript过滤,直接关掉浏览器的Javascrip功能,或者burp抓包修改文件后缀即可
操作如下:
第一种:禁用JavaScript
可以看到直接上传成功
第二种方法,使用工具(如burp),修改文件后缀,Javascrip只检测了前端的后缀,可以修改发送到服务器的包
pass02(服务端对content-type的限制)
分析:只对content-type进行白名单的限制,几乎没有用,照样发送php文件,用burp抓包,修改content-type进行send即可
方法:上传php文件,并用burp修改content-type内容
pass03(黑名单过滤不全)
某些特定的后缀仍会被php解析:如php、php2、php3、php4、php5、php6、php7、pht、phtm、phtml。
用phtml后缀名试一下
pass04(apache早期版本,.htaccess服务配置文件未过滤)
上传.htaccess文件,内容如下,可以将demo.png解析成php,将demo.phg改后缀上传即可
<FilesMatch "demo.png">
SetHandler application/x-httpd-php
</FilesMatch>
pass05(黑名单过滤少了ini)
user.ini
和.htaccess
一样是目录的配置文件,.user.ini
就是用户自定义的php.ini(全局配置文件)
.user.ini 配置项中有两个配置可以起到一些作用
方法一:
auto_prepend_file = <filename> //包含在文件头
方法二:
auto_append_file = <filename> //包含在文件尾
pass06(无大小写过滤)
windows中对大小写不敏感
pass07(Windows文件后缀未去空)
可以看到和上之前的代码相比,过滤函数少了一个trim()函数去空操作
做法:只需要用burp抓包,改文件后缀添加一个空格即可
pass08(windows文件后缀未去点)
如果上传的是tp.php. strrchr($file_name,".")的返回结果并不是 . 而是.php.
跟之前的代码相比,少了去除文件后缀末尾的.操作,在windows中仍然会识别
做法,使用burp抓包,改掉文件后缀添加.
pass09(windows中文件后缀未去::data)
跟之前的代码相比,少了去::$DATA操作
做法,正常上传文件,用burp抓包,改掉文件后缀添加::$DATA
pass10(后缀过滤考虑不周,仍可以通过一些方式绕过过滤)
看似都过滤了很安全,实则不然,
抓包上传后缀名为.php. .的文件
pass11(双写绕过,或大小写绕过)
直接burp抓包改后缀
pass12(使用$GET("save_path")来自定义保存路径,可以使用%00截断)
在c语言中%00代表阶段,如果我们正常上传正确的文件类型,然后修改save_path的路径如:目录/web.php%00, 在文件上传路径拼接的时候,后面的路径就被截断了,而他在前面已经进行了白名单过滤
%00截断常在url中get请求使用,在url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束。所以一般文件上传绕过%00会在路径上使用
使用条件:
php版本<5.3.29
php.ini配置文件中magic_quotes_gpc = Off
直接上burp抓包,修改save_path路径
pass13($POST(保存路径),使用16进制00截断)
转16进制,将路径后面修改成00截断
这里可以看到保存路径后的php后缀多了一个\0截断
pass14(文件包含,检测图片前面的内容)
这关是文件包含漏洞的关卡,文件包含漏洞是指未正确使用include()函数,在进行文件包含的同时,仍然会用php解释器执行图片的二进制内容,这时候可以将php恶意代码嵌入到图片中
这里可以看到,本关卡对上传的图片进行了前面的内容检测,可以将php代码嵌入到图片尾部
存在文件包含漏洞,直接打开这个网址,给除上传的图片码的file地址变量。
第一步,制作图片码:
第二步,上传文件,并复制文件地址
第三步,点击文件包含漏洞,给出参数?file="复制的文件地址路径",结果如下,在include()时执行了图片码中的php代码
pass15(由于 getimagesize()
只读取文件头信息,恶意代码可能被忽略)
getimagesize()仍然只检测文件头信息,上传pass14的图片码仍然可以成功
做法与pass14一致,结果如下
pass16(exif_imagetype()仍然是通过文件头来检测文件类型)
查看源代码需要php开启exif扩展才生效
开启扩展过后步骤与前面两关一致,制作图片码,上传,用文件包含漏洞进行上传的文件包含,执行图片码中的php代码。
pass17(进行了图片的二次渲染)
这里可以看到,使用了imagecreatefromjpeg()函数,对上传的图片进行打乱,生成新的图片,可以正常上传图片,用010editor工具查看上传前后不变的区域,在那里插入php代码
先正常上传一个文件,然后将上传后二次渲染的文件下载下来,用010editor软件打开,在工具选项---比较文件功能,比较两个文件的16进制,找出前后不变的片段,插入php代码
保存图片,将新构成的图片码上传,后续步骤与上面的关卡一致,进行文件包含,给file参数值
pass18(先上传了文件,再判断是否在白名单里面,存在竞争)
从代码来看,这个页面是先将文件上传了过后,再判断文件的后缀是否在白名单里面,我可以不断的发包上传php(该php代码可以是在上级创建一个的恶意文件代码的php文件)文件,再不断访问文件包含漏洞的界面进行该图片的文件包含,总有一刻是我上传了文件,进行了文件包含,才判断我的文件是否在白名单中,这样已经为时已晚了
修改php代码,这个代码是在上级目录创建一个名未shell.php文件,内容是<?php phpinfo(); ?>
直接上传,用burp抓包,再用intruder模块自动化攻击,持续发上传文件的包
在访问文件包含漏洞的界面,持续刷新
---------------------------------------------------------------------------------------------------------------------------------