文件上传漏洞

文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。 当用户点击上传按钮后,后台会对上传的文件进行判断,比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。 如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击者可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。

工具推荐 BurpSuite工具+SwitchOmega浏览器插件

A 上传漏洞存在的必要条件

  1. 存在上传点
  2. 可以上传动态文件
  3. 上传目录有执行权限,并且上传的文件可执行
  4. 可访问到上传的动态文件

B 上传检测流程

1.前端提交  可能遇到JavaScript检测、flash as检测等
2.数据传输  可能遇到waf拦截、ips拦截等
3.后端处理  可能遇到扩展名检测、文件格式检测、mime ytpe检测、内容检测等
4.写入文件系统    可能遇到文件重命名、杀毒软件查杀等
5.访问文件  可能遇到无执行权限、位置位置等

C 客户端检测绕过

客户端检测一般只检测文件扩展名,可通过对客户端代码的一些修改或拦截器修改报文即可绕过

1 JavaScript检测绕过

  1. 查看onchange、onsubmit等事件 onchange事件会在与的内容改变时发生,如选择文件 onsubmit会在确认按钮点击时发生
  2. 删除掉相关事件中的检测函数

2 提交报文修改检测

这种方法在前端绕过中是通用的,无需理会具体前端的检测代码,直接绕过并提交

  1. 将文件名改为符合要求的文件名后上传
  2. 通过bp截包后,进行改包或重放完成文件上传

3 APP端bp抓包

  1. 将bp的代理端口监听问“all interface”
  2. 在手机wifi设置中将代理地址设置为bpip:8080
  3. 访问***.com下载证书
  4. 安卓将扩展名修改为.crt,然后设置-安装-平局存储-从SD卡安装
  5. ios直接按提示安装完,进入设置-通用-关于本机-证书信任设置,添加信任

如果安卓app使用了证书校验,可以配合xposed框架的JustTrustMe使用,ios没办法 如果使用mumu模拟器,需要用adb打开wifi设置

adb connect 127.0.0.1:7555
adb shell am start -a android.settings.WIFI_SETTINGS

D 服务器检测绕过

1 mime类型检测绕过

waf或代码中,可能会检测mime类型,只允许指定的几种mime类型通过 好在mime类型是浏览器生产的,所以可以通过bp抓包后,修改mime类型来绕过此种检测 常见的白名单mime type

image/jepg
image/png
text/plain
application/zip
application/msword

2 简单文件头检测绕过

文件头是位于文件开头的一段承担一定任务的数据,一般在文件的开头部分,如 gif的文件头是GIF89a,GIT87a jepg的文件头是\xff\xd8\xff(需转码) png的文件头是\x89PNG\x0d\x0a(需转码)

这种检测方法,可以通过在上传的文件前最佳合法的文件头进行绕过,如 GIF89a<?php phpinfo();?>

3 完整文件结构检测

通过调用图像函数(如getimagesize、imagecreatefromgif、imagecreatefrompng等)检测文件是否是图像,需要文件内容保持相对完整,所以无法通过加文件头的方法绕过

针对这种,可以将图片文件与与上传文件合并的方式来绕过检测,合并命令为copy,如

copy /b a.gif+php.info upload_phpinfo.gif

4 恶意文件内容检测

如果服务器端的waf,会检测提交的内容中是否包含webshell等数据时,前几种方式就都不行了 常见的关键字为

eval()
base64_encode()
assert()
java.lang.Runtime
java.lang.ProcessBuilder

推荐使用强混淆的weevely进行尝试,kali中自带 ***.com

或者尝试开源的webshell收集项目(要自己判断是否挂马) ***.com

5 一些小技巧

  1. 文件参数多filename属性 如果waf拦截一些扩展名,可以通过抓包后,写入过个filename属性的方式来尝试绕过
  2. 目录可控时,可以尝试使用目录穿越的方法 例如文件上传到\A\B\C目录,但是禁止访问该路径下的指定类型文件,那么可以尝试截包,将上传路径改为../../的方式传文件到\A下,如果代码中存在穿越目录的漏洞,就能成功
  3. 扩展名检测类型可控的情况,如 1 可以从后台修改允许/禁止的扩展名类型(拿到后台权限) 2 提交参数中存在允许/禁止的扩展名类型(改前端页面代码) 3 前端单独抽出了文件扩展名进行了提交(截包)

E 常见解析漏洞

1 IIS/NGINX+php fastcgi取值错误解析漏洞

此漏洞属于配置错误,不属于软件漏洞

开启了cgi.fix_pathinfo,且未设置security.limit_extensions以限制可以执行的文件类型,那么当执行的文件不存在时,会继续查找上一级文件是否存在,如 abcde.jpp/.php,找不到,就会向上查找abcde.jpg.php

2 nginx文件名逻辑漏洞(CVE-2013-4547)

影响版本:nginx 0.8.41~14.3/1.5.0~1.5.7

当上传一个以空格(%20)结尾的文件,如“abcde.jpg ”,然后访问的时候截包,将文件名改为abcde.jpg%20%00.php时,文件会被当做php脚本执行

3 apache解析漏洞(配置错误)

如果在apache的conf文件中有如下配置:当后缀不能解析时,会往前寻找可解析的后缀

AddHandler application/x-httpd-php .php

则abcde.php.jpg也会被当做php去执行,所以当我们拿到服务器,想要自己留后门时,可以设置指定的扩展名.xxx

AddHandler application/x-httpd-php .xxx

4 IIS 5.X/6.0解析漏洞

  1. 分号文件名漏洞 服务器默认不解析分号后面的内容,因此如果截包上传abcde.asp;.jpg的文件后,再通过浏览器访问改文件,会被当成abcde.asp执行
  2. xxx.asp目录抖动 服务器会将xxx.asp目录下的文件,都当做asp文件解析

F 高级绕过技巧

1 重绘图绕过

当应用调用图片库对上传的图像文件进行了图像转换,会使我们合并到图片中的webshell被删掉而失败,针对这种情况的绕过步骤为:

  1. 将正常图片用目标使用的图形库进行转换
  2. 寻找转换前后未变化的部分
  3. 将未变化的部分替换为欲上传的webshell
  4. 将替换后的文件再次转换,看改部分是否仍然存在,然后进行上传

有一个开源代码可用: ***.com

2 phpinfo与本地文件包含联合使用

使用场景是可以获取phpinfo,也存在文件包含漏洞,但找不到路径的情况下,可以联合使用

  1. php在解析multipart/form-data请求时,会创建临时文件,并写入上传内容,当脚本执行结束后就删除
  2. phpinfo中可以输出$_FILES信息,里面包含临时文件地址
  3. 通过多种方式争取时间,在临时文件删除钱进行执行包含 如大量垃圾数据使phpinfo页面过大,导致php的输出切换为流式输出 或通过大量请求来延迟php脚本的执行速度

有开源代码可用: ***.com

3 在线解压缩的漏洞利用

如果某个网站,可以让你上传压缩包,然后网站会将你的压缩包解压的情况,可以如下利用:

  1. 将webshell打包到压缩包中

  2. 模板上传传常用压缩包上传后进行自动解压 部分网站会检测压缩包中的内容,可以尝试建立目录再进行压缩

  3. 使用目录穿越../的方法向上一级目录进行上传

  4. 将文件/文件夹软连接打包到压缩包中 如链接到/etc/password文件,或连接到根目录等发生