二十一.WEB漏洞-文件上传之后端黑白名单绕过
2022年 06月 10 日

BIGFISH

  • 知识点


    文件上传常见验证:后缀名,类型,文件头等

    1.后缀名:黑名单,白名单


    • 黑名单:明确不让上传的格式后缀,比如asp,php,jsp,aspx,cgi,war等,但是黑名单易被绕过,比如上传php5,Phtml等
    • 白名单:明确可以上传的格式后缀,比如jpg,png,zip,rar,gif等,推荐白名单

    2.文件类型:MIME信息


    • content-type字段校验,可以通过抓包改包方式绕过

    3.文件头:内容头信息


    • 每种类型的文件都有自己固定的文件头信息,比如GIF89a是gif图片的文件头信息,可以通过手动在脚本文件前面增加文件头的方式绕过。

    4.windows特性


    • windows下文件名不区分大小写,linux下文件名区分大小写
    • windows下NTFS 特征,导致上传文件xxx.php::$DATA = xxx.php
    • windows下文件名结尾加入“.”、“空格”、“<”、“>”、“>>>”、“0x81-0xff”等字符,最终生成的文件均被windows忽略。

    upload-labs
    • 下载:https://github.com/c0ny1/upload-labs
    • 1.GET优先于POST
    • 2.搭建upload 靶场时 php环境尽量选低,要不然会出现访问木马文件出现下载的现象
      • 案例1:Pass-1 $_FILES[‘upfile’]访问文件的有关信息
      • 案例2:Pass-2 MIME-Type验证
      • 案例3:Pass-3 黑名单绕过 特殊解析后缀
      • 案例4:Pass-4 .htaccess绕过
      • 案例5:Pass-5 大小写绕过
      • 案例6:Pass-6 后缀名空格绕过
      • 案例7:Pass-7 点绕过
      • 案例8:Pass-8 ::$DATA绕过
      • 案例9:Pass-9 点+空格+点绕过(循环递归过滤)
      • 案例10:Pass-10 双写绕过
      • 案例11:Pass-11 %00截断 GET请求
      • 案例12:Pass-12 00截断 POST请求

    案例演示
    • Pass1:$_FILES[‘upfile’]访问文件的有关信息


      $_FILES[‘upfile’][‘name’]; //客户端上传文件的原名称,不包含路径
      $_FILES[‘upfile’][‘type’]; //上传文件的MIME类型
      $_FILES[‘upfile’][‘tmp_name’]; //已上传文件在服务器端保存的临时文件名,包含路径
      $_FILES[‘upfile’][‘error’]; //上传文件出现的错误号,为一个整数
      $_FILES[‘upfile’][‘size’]; //已上传文件的大小,单位为字节
      • 我们首先进行第一关的尝试,通过f12将网页代码复制下来发现验证代码时用前端js编写的 image-20210829231834831
      • 这时候我们在自己本地新建一个文件(存放我们的第一关,防止误删其他重要代码),在代码中我们将验证部分删掉,同时加上对应的提交位置 image-20210829233400467
      • 添加上传到的位置
      • image-20210829233315295
      • 进行上传操作,在对应文件看到php文件,成功上传! image-20210829233831103 image-20210829233802030
      • 第二个思路:利用bp抓包进行修改,将后缀直接改成php即可实现上传脚本文件操作 image-20210829234412743
    • 案例2:Pass-02 MIME-Type验证
      • MIME(multipurpose Internet mail extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
      • 查看代码,系统校验了MIME-Type
      • 因此只要抓包修改content-type值为符合条件的值即可绕过。
      • 修改为:image/jpeg
      • 然后发包,我们发现已经成功上传

    [blockquote2 name='附各类文件MIME_type对照表 ']
    • {".3gp", "video/3gpp"},
    • {".apk", "application/vnd.android.package-archive"},
    • {".asf",    "video/x-ms-asf"},   
      {".avi",    "video/x-msvideo"},   
      {".bin",    "application/octet-stream"},   
      {".bmp",    "image/bmp"},   
      {".c",  "text/plain"},   
      {".class",  "application/octet-stream"},   
      {".conf",   "text/plain"},   
      {".cpp",    "text/plain"},   
      {".doc",    "application/msword"},   
      {".docx",   "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},   
      {".xls",    "application/vnd.ms-excel"},    
      {".xlsx",   "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},   
      {".exe",    "application/octet-stream"},   
      {".gif",    "image/gif"},   
      {".gtar",   "application/x-gtar"},   
      {".gz", "application/x-gzip"},   
      {".h",  "text/plain"},   
      {".htm",    "text/html"},   
      {".html",   "text/html"},   
      {".jar",    "application/java-archive"},   
      {".java",   "text/plain"},   
      {".jpeg",   "image/jpeg"},   
      {".jpg",    "image/jpeg"},   
      {".js", "application/x-javascript"},   
      {".log",    "text/plain"},   
      {".m3u",    "audio/x-mpegurl"},   
      {".m4a",    "audio/mp4a-latm"},   
      {".m4b",    "audio/mp4a-latm"},   
      {".m4p",    "audio/mp4a-latm"},   
      {".m4u",    "video/vnd.mpegurl"},   
      {".m4v",    "video/x-m4v"},    
      {".mov",    "video/quicktime"},   
      {".mp2",    "audio/x-mpeg"},   
      {".mp3",    "audio/x-mpeg"},   
      {".mp4",    "video/mp4"},   
      {".mpc",    "application/vnd.mpohun.certificate"},          
      {".mpe",    "video/mpeg"},     
      {".mpeg",   "video/mpeg"},     
      {".mpg",    "video/mpeg"},     
      {".mpg4",   "video/mp4"},      
      {".mpga",   "audio/mpeg"},   
      {".msg",    "application/vnd.ms-outlook"},   
      {".ogg",    "audio/ogg"},   
      {".pdf",    "application/pdf"},   
      {".png",    "image/png"},   
      {".pps",    "application/vnd.ms-powerpoint"},   
      {".ppt",    "application/vnd.ms-powerpoint"},   
      {".pptx",   "application/vnd.openxmlformats-officedocument.presentationml.presentation"},   
      {".prop",   "text/plain"},   
      {".rc", "text/plain"},   
      {".rmvb",   "audio/x-pn-realaudio"},   
      {".rtf",    "application/rtf"},   
      {".sh", "text/plain"},   
      {".tar",    "application/x-tar"},      
      {".tgz",    "application/x-compressed"},    
      {".txt",    "text/plain"},   
       {".wav",    "audio/x-wav"},   
      {".wma",    "audio/x-ms-wma"},   
      {".wmv",    "audio/x-ms-wmv"},   
      {".wps",    "application/vnd.ms-works"},   
      {".xml",    "text/plain"},   
      {".z",  "application/x-compress"},   
      {".zip",    "application/x-zip-compressed"},   
      {"",        "*/*"}[/blockquote2]

    • 案例3:Pass-3 黑名单绕过 特殊解析后缀
      • 查看源码,发现源码配置了黑名单,不允许上传.asp,.aspx,.php,.jsp后缀的文件
      • 但apache服务器能够使用php解析.phtml .php3 .php5。前提是apache的httpd.conf中有如下配置代码
        • AddType application/x-httpd-php .php .phtml .php3 .php5
      • 因此可以上传.phtml .php3 .php5文件,绕过黑名单
    • 案例4:Pass-4 .htaccess绕过
      • 查看源码,发现源码配置了黑名单,拒绝了几乎所有有问题的后缀名,除了.htaccess
      • .htaccess作为局部变量成功作用于当前目录下文件的两个条件(1.启用AllowOverride,2.开启mod_rewrite模块)
        • 修改httpd.conf:
          1、Allow Override All
          2、LoadModule rewrite_module modules/mod_rewrite.so
      • 本关正好符合,因此先上传一个.htaccess文件,内容如下:

        <FilesMatch "hello">
        setHandler application/x-httpd-php
        </FilesMatch>

        作用是使当前目录下所有文件名包含“hello”字符串的文件当作php文件解析。
      • 然后再上传一个hello.jpg文件,内容如下:<?php phpinfo(); ?>
      • 此时访问该文件web路径,服务器执行hello.jpg文件中的PHP代码。
    • 案例5:Pass-5 大小写绕过
      • 查看源码
      • 发现没有strtolower函数将大小写转换,可以利用大小写绕过
      • 抓包修改后缀为大写
      • 然后上传成功
    • 案例6:Pass-6 后缀名空格绕过
      • 原理是 服务器在校验黑名单时,校验的后缀名是.php+空格,由于.php+空格不在黑名单内,可以通过校验,而windows系统在保存文件时,会自动去掉后面的空格,因此文件最终保存在服务器上的后缀名为.php。(linux系统在保存文件时应该也会自动去除空格,可以自行测试一下?)
      • 查看源码
      • 发现没有trim函数去除末尾空格,在php后面加一个空格
      • 然后上传成功
    • 案例7:Pass-7 点绕过
      • 查看源码
      • 源码相较于pass-4,没有deldot函数删除文件名末尾的点,利用windows特性,会自动去掉后缀名中最后的”.”,可在后缀名中加”.空格.”绕过。
    • 案例8:Pass-8 ::$DATA绕过
      • 补充知识:deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来
      • 查看源码
      • 源码相较于pass-4,没有str_iplace函数对后缀名中的“::$DATA”进行过滤。在php+windows的情况下,如果文件名+“::$DATA”会把“::$DATA”之后的数据当成文件流处理,不会检测后缀名,且保持“::$DATA”之前的文件名。利用windows特性,可在后缀名后面加“::$DATA”绕过。例如“phpinfo.php: :$DATA” Windows会自动去掉末尾的“::$DATA”变成“phpinfo.php”。
      • 在php后面加 :空格:$DATA
    • 案例9:Pass-9 点 空格 点 绕过
      • 查看源码
      • 发现他把之前的漏洞都补上了,但他代码本身就有问题 : 只过滤了 一个 点 和 一个 空格 还有PATH :
      • 首先需要了解deldot函数,当deldot函数检测到末尾的第一个点时将继续从后向前检测,当检测到空格时就停下来,因此当后缀是php.[空格].时,经过deldot函数过滤后,后缀变成php.[空格],最终绕过黑名单,且上传上去的文件名为php.,在windows下会自动去除点。
      • 所以, 可以用 bs 将1.php 改为 1.php. . (点+空格+点) 成功绕过
      • 这里发现$_FILES['upload_file']['name']获取的是文件名中/后面的字符串,本来还想用但move_uploaded_file会忽略/.的trick绕过
    • 案例10:Pass-10 双写绕过
      • 操作过程:查看源代码 发现 依旧是黑名单过滤 关键过滤就这两句:
      • 当file_name中出现deny_ext中存在的字符串,就把它去掉,但只处理了一次.
      • 可以用双写后缀名 进行绕过 将1.php 改为 1.pphphp 成功绕过
    • 案例11:Pass-11 %00截断 GET请求
      • 操作过程:查看源代码,发现是白名单过滤
      • 但是img_path直接使用点号拼接路径,这里就存在风险.
      • $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
      • 我们可以使用%00截断来实现绕过.
        • php版本5.5.9
        • php的magic_quotes_gpc为OFF状态
      • 但这东西有点过气了,因为需要以上两个条件
      • 如果要完成这一个题目就必须要实现上面的两个条件,但是现在都PHP7了,这东西也就很少见了,满足上面的条件的时候php就是把它当成结束符,后面的数据直接忽略
    • Pass-12 00截断 POST请求
      • 查看代码,发现和11关一样,只不过get请求换为了post请求
      • 上传php文件后,抓包在在a.php后面加一个空格
      • 然后将空格的十六进制 20 改为 00 ,上传即可
      • 然后上传,发现成功!

二十一.WEB漏洞-文件上传之后端黑白名单绕过

  • 知识点


    文件上传常见验证:后缀名,类型,文件头等

    1.后缀名:黑名单,白名单


    • 黑名单:明确不让上传的格式后缀,比如asp,php,jsp,aspx,cgi,war等,但是黑名单易被绕过,比如上传php5,Phtml等
    • 白名单:明确可以上传的格式后缀,比如jpg,png,zip,rar,gif等,推荐白名单

    2.文件类型:MIME信息


    • content-type字段校验,可以通过抓包改包方式绕过

    3.文件头:内容头信息


    • 每种类型的文件都有自己固定的文件头信息,比如GIF89a是gif图片的文件头信息,可以通过手动在脚本文件前面增加文件头的方式绕过。

    4.windows特性


    • windows下文件名不区分大小写,linux下文件名区分大小写
    • windows下NTFS 特征,导致上传文件xxx.php::$DATA = xxx.php
    • windows下文件名结尾加入“.”、“空格”、“<”、“>”、“>>>”、“0x81-0xff”等字符,最终生成的文件均被windows忽略。

    upload-labs
    • 下载:https://github.com/c0ny1/upload-labs
    • 1.GET优先于POST
    • 2.搭建upload 靶场时 php环境尽量选低,要不然会出现访问木马文件出现下载的现象
      • 案例1:Pass-1 $_FILES[‘upfile’]访问文件的有关信息
      • 案例2:Pass-2 MIME-Type验证
      • 案例3:Pass-3 黑名单绕过 特殊解析后缀
      • 案例4:Pass-4 .htaccess绕过
      • 案例5:Pass-5 大小写绕过
      • 案例6:Pass-6 后缀名空格绕过
      • 案例7:Pass-7 点绕过
      • 案例8:Pass-8 ::$DATA绕过
      • 案例9:Pass-9 点+空格+点绕过(循环递归过滤)
      • 案例10:Pass-10 双写绕过
      • 案例11:Pass-11 %00截断 GET请求
      • 案例12:Pass-12 00截断 POST请求

    案例演示
    • Pass1:$_FILES[‘upfile’]访问文件的有关信息


      $_FILES[‘upfile’][‘name’]; //客户端上传文件的原名称,不包含路径
      $_FILES[‘upfile’][‘type’]; //上传文件的MIME类型
      $_FILES[‘upfile’][‘tmp_name’]; //已上传文件在服务器端保存的临时文件名,包含路径
      $_FILES[‘upfile’][‘error’]; //上传文件出现的错误号,为一个整数
      $_FILES[‘upfile’][‘size’]; //已上传文件的大小,单位为字节
      • 我们首先进行第一关的尝试,通过f12将网页代码复制下来发现验证代码时用前端js编写的 image-20210829231834831
      • 这时候我们在自己本地新建一个文件(存放我们的第一关,防止误删其他重要代码),在代码中我们将验证部分删掉,同时加上对应的提交位置 image-20210829233400467
      • 添加上传到的位置
      • image-20210829233315295
      • 进行上传操作,在对应文件看到php文件,成功上传! image-20210829233831103 image-20210829233802030
      • 第二个思路:利用bp抓包进行修改,将后缀直接改成php即可实现上传脚本文件操作 image-20210829234412743
    • 案例2:Pass-02 MIME-Type验证
      • MIME(multipurpose Internet mail extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
      • 查看代码,系统校验了MIME-Type
      • 因此只要抓包修改content-type值为符合条件的值即可绕过。
      • 修改为:image/jpeg
      • 然后发包,我们发现已经成功上传

    [blockquote2 name='附各类文件MIME_type对照表 ']
    • {".3gp", "video/3gpp"},
    • {".apk", "application/vnd.android.package-archive"},
    • {".asf",    "video/x-ms-asf"},   
      {".avi",    "video/x-msvideo"},   
      {".bin",    "application/octet-stream"},   
      {".bmp",    "image/bmp"},   
      {".c",  "text/plain"},   
      {".class",  "application/octet-stream"},   
      {".conf",   "text/plain"},   
      {".cpp",    "text/plain"},   
      {".doc",    "application/msword"},   
      {".docx",   "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},   
      {".xls",    "application/vnd.ms-excel"},    
      {".xlsx",   "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},   
      {".exe",    "application/octet-stream"},   
      {".gif",    "image/gif"},   
      {".gtar",   "application/x-gtar"},   
      {".gz", "application/x-gzip"},   
      {".h",  "text/plain"},   
      {".htm",    "text/html"},   
      {".html",   "text/html"},   
      {".jar",    "application/java-archive"},   
      {".java",   "text/plain"},   
      {".jpeg",   "image/jpeg"},   
      {".jpg",    "image/jpeg"},   
      {".js", "application/x-javascript"},   
      {".log",    "text/plain"},   
      {".m3u",    "audio/x-mpegurl"},   
      {".m4a",    "audio/mp4a-latm"},   
      {".m4b",    "audio/mp4a-latm"},   
      {".m4p",    "audio/mp4a-latm"},   
      {".m4u",    "video/vnd.mpegurl"},   
      {".m4v",    "video/x-m4v"},    
      {".mov",    "video/quicktime"},   
      {".mp2",    "audio/x-mpeg"},   
      {".mp3",    "audio/x-mpeg"},   
      {".mp4",    "video/mp4"},   
      {".mpc",    "application/vnd.mpohun.certificate"},          
      {".mpe",    "video/mpeg"},     
      {".mpeg",   "video/mpeg"},     
      {".mpg",    "video/mpeg"},     
      {".mpg4",   "video/mp4"},      
      {".mpga",   "audio/mpeg"},   
      {".msg",    "application/vnd.ms-outlook"},   
      {".ogg",    "audio/ogg"},   
      {".pdf",    "application/pdf"},   
      {".png",    "image/png"},   
      {".pps",    "application/vnd.ms-powerpoint"},   
      {".ppt",    "application/vnd.ms-powerpoint"},   
      {".pptx",   "application/vnd.openxmlformats-officedocument.presentationml.presentation"},   
      {".prop",   "text/plain"},   
      {".rc", "text/plain"},   
      {".rmvb",   "audio/x-pn-realaudio"},   
      {".rtf",    "application/rtf"},   
      {".sh", "text/plain"},   
      {".tar",    "application/x-tar"},      
      {".tgz",    "application/x-compressed"},    
      {".txt",    "text/plain"},   
       {".wav",    "audio/x-wav"},   
      {".wma",    "audio/x-ms-wma"},   
      {".wmv",    "audio/x-ms-wmv"},   
      {".wps",    "application/vnd.ms-works"},   
      {".xml",    "text/plain"},   
      {".z",  "application/x-compress"},   
      {".zip",    "application/x-zip-compressed"},   
      {"",        "*/*"}[/blockquote2]

    • 案例3:Pass-3 黑名单绕过 特殊解析后缀
      • 查看源码,发现源码配置了黑名单,不允许上传.asp,.aspx,.php,.jsp后缀的文件
      • 但apache服务器能够使用php解析.phtml .php3 .php5。前提是apache的httpd.conf中有如下配置代码
        • AddType application/x-httpd-php .php .phtml .php3 .php5
      • 因此可以上传.phtml .php3 .php5文件,绕过黑名单
    • 案例4:Pass-4 .htaccess绕过
      • 查看源码,发现源码配置了黑名单,拒绝了几乎所有有问题的后缀名,除了.htaccess
      • .htaccess作为局部变量成功作用于当前目录下文件的两个条件(1.启用AllowOverride,2.开启mod_rewrite模块)
        • 修改httpd.conf:
          1、Allow Override All
          2、LoadModule rewrite_module modules/mod_rewrite.so
      • 本关正好符合,因此先上传一个.htaccess文件,内容如下:

        <FilesMatch "hello">
        setHandler application/x-httpd-php
        </FilesMatch>

        作用是使当前目录下所有文件名包含“hello”字符串的文件当作php文件解析。
      • 然后再上传一个hello.jpg文件,内容如下:<?php phpinfo(); ?>
      • 此时访问该文件web路径,服务器执行hello.jpg文件中的PHP代码。
    • 案例5:Pass-5 大小写绕过
      • 查看源码
      • 发现没有strtolower函数将大小写转换,可以利用大小写绕过
      • 抓包修改后缀为大写
      • 然后上传成功
    • 案例6:Pass-6 后缀名空格绕过
      • 原理是 服务器在校验黑名单时,校验的后缀名是.php+空格,由于.php+空格不在黑名单内,可以通过校验,而windows系统在保存文件时,会自动去掉后面的空格,因此文件最终保存在服务器上的后缀名为.php。(linux系统在保存文件时应该也会自动去除空格,可以自行测试一下?)
      • 查看源码
      • 发现没有trim函数去除末尾空格,在php后面加一个空格
      • 然后上传成功
    • 案例7:Pass-7 点绕过
      • 查看源码
      • 源码相较于pass-4,没有deldot函数删除文件名末尾的点,利用windows特性,会自动去掉后缀名中最后的”.”,可在后缀名中加”.空格.”绕过。
    • 案例8:Pass-8 ::$DATA绕过
      • 补充知识:deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来
      • 查看源码
      • 源码相较于pass-4,没有str_iplace函数对后缀名中的“::$DATA”进行过滤。在php+windows的情况下,如果文件名+“::$DATA”会把“::$DATA”之后的数据当成文件流处理,不会检测后缀名,且保持“::$DATA”之前的文件名。利用windows特性,可在后缀名后面加“::$DATA”绕过。例如“phpinfo.php: :$DATA” Windows会自动去掉末尾的“::$DATA”变成“phpinfo.php”。
      • 在php后面加 :空格:$DATA
    • 案例9:Pass-9 点 空格 点 绕过
      • 查看源码
      • 发现他把之前的漏洞都补上了,但他代码本身就有问题 : 只过滤了 一个 点 和 一个 空格 还有PATH :
      • 首先需要了解deldot函数,当deldot函数检测到末尾的第一个点时将继续从后向前检测,当检测到空格时就停下来,因此当后缀是php.[空格].时,经过deldot函数过滤后,后缀变成php.[空格],最终绕过黑名单,且上传上去的文件名为php.,在windows下会自动去除点。
      • 所以, 可以用 bs 将1.php 改为 1.php. . (点+空格+点) 成功绕过
      • 这里发现$_FILES['upload_file']['name']获取的是文件名中/后面的字符串,本来还想用但move_uploaded_file会忽略/.的trick绕过
    • 案例10:Pass-10 双写绕过
      • 操作过程:查看源代码 发现 依旧是黑名单过滤 关键过滤就这两句:
      • 当file_name中出现deny_ext中存在的字符串,就把它去掉,但只处理了一次.
      • 可以用双写后缀名 进行绕过 将1.php 改为 1.pphphp 成功绕过
    • 案例11:Pass-11 %00截断 GET请求
      • 操作过程:查看源代码,发现是白名单过滤
      • 但是img_path直接使用点号拼接路径,这里就存在风险.
      • $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
      • 我们可以使用%00截断来实现绕过.
        • php版本5.5.9
        • php的magic_quotes_gpc为OFF状态
      • 但这东西有点过气了,因为需要以上两个条件
      • 如果要完成这一个题目就必须要实现上面的两个条件,但是现在都PHP7了,这东西也就很少见了,满足上面的条件的时候php就是把它当成结束符,后面的数据直接忽略
    • Pass-12 00截断 POST请求
      • 查看代码,发现和11关一样,只不过get请求换为了post请求
      • 上传php文件后,抓包在在a.php后面加一个空格
      • 然后将空格的十六进制 20 改为 00 ,上传即可
      • 然后上传,发现成功!

赞 (0)

猜您想看

评论区(暂无评论)

这里空空如也,快来评论吧~

我要评论