文件上传初探

7erry

在Web应用的各种服务场景中,文件上传是相当常见的业务。例如用户上传图片作为自己的头像,或者作为发布的文章的插图等等。如果后端没有对用户上传的文件做出充分的过滤与适当的处理,很容易导致包括但不限于被上传WebShell、垃圾文件等安全问题。从红队视角来看,文件上传也是一个高回报的渗透点。

简单绕过

截断绕过

后端对文件名后缀的检测方式是多样的,不过最常用的要么是截取第一个后缀名,要么是截取最后一个后缀名。而当WAF与后端代码检测的不一致时,例如WAF检测第一个后缀名,而后端保存文件时会保存到最后一个后缀名为止,那这样的防御很有可能会是失败的,因为实际解析一个文件时往往是根据最后一个后缀名解析。而如果WAF检测第二及第二个以后的文件后缀名,那么无论实际保存文件以哪一个后缀名进行保存,我们可以尝试截断的方式进行绕过,即我们可以想办法让后端在读入文件名时,停在我们想要的那个后缀名的位置。

00截断

00截断是绕过文件上传限制的一种常见手段,因为在C语言中,’\0’表示一个字符串的结尾,如果我们能够在文件名中加入’\0’,就能实现截断。
00截断绕过上传限制使用的场景为,后端先获取用户上传文件的文件名,如x.php\00.jpg,它的实际后缀名,以及WAF检测的文件后缀名为jpg,但保存文件时会发生截断,上传后的文件名会是x.php
PHP是C语言编写的,因此也存在这一问题,不过00截断实际上不怎么起得了作用,因为00截断会在Apache把文件名写入$_FILE全局变量时就发生,而非在我们想要得文件保存时发生。具体可见PHP处理上传请求的部分调用栈:

  • rfc1867_post_handle
  • multipart_buffer_headers

而在Java中,jdk7u40以下版本存在00截断问题,7u40后的版本,在上传、写入文件等操作都会调用File中的isInvalid()方法判断文件名是否合法,具体操作时如果发现文件名中有’\0’等违法字符则抛出异常结束流程

Go语言查半天死活找不到,日后补充 :P

字符集转换截断

在后端对用户上传的文件名进行字符集转换时也可能发生截断。例如PHP在实现字符集转换的时候通常会使用iconv函数,UTF-8在单字节允许的字符范围为0x00到0x7F。PHP在5.4以下版本时,如果处理的字符串不在范围内,会停止处理接下来的字符造成截断

更改HTTP首部行绕过

有的站点仅仅在前端检测了文件类型,这种类型的检测可以直接修改HTTP首部行绕过。同样的,有的站点在后端仅检查了HTTP Header中的信息,比如 Content-Type 等,这种检查同样可以通过修改HTTP首部行绕过

Magic检测绕过

有的站点使用文件头来检测文件类型,这种检查可以在Shell前加入对应的字节以绕过检查。几种常见的文件类型的头字节如下表所示
类型 二进制值
JPG FF D8 FF E0 00 10 4A 46 49 46
GIF 47 49 46 38 39 61
PNG 89 50 4E 47
TIF 9 49 2A 00
BMP 42 4D

特殊后缀绕过

部分服务仅根据后缀、上传时的信息或Magic Header来判断文件类型,此时可以绕过。
php由于历史原因,部分解释器可能支持符合正则 /ph(p[2-7]?|t(ml)?)/ 的后缀,如 php / php5 / pht / phtml / shtml / pwml / phtm 等 可在禁止上传php文件时测试该类型。
jsp引擎则可能会解析 jspx / jspf / jspa / jsw / jsv / jtml 等后缀,asp支持 asa / asax / cer / cdx / aspx / ascx / ashx / asmx / asp{80-90} 等后缀。
除了这些绕过,其他的后缀同样可能带来问题,如 vbs / asis / sh / reg / cgi / exe / dll / com / bat / pl / cfc / cfm / ini 等。

系统重命名绕过

在Windows系统中,上传 index.php. 会重命名为 . ,可以绕过后缀检查。 也可尝试 index.php%20 , index.php:1.jpg index.php::$DATA 等。 在Linux系统中,可以尝试上传名为 index.php/. 或 ./aa/../index.php/. 的文件

藏木于林

有的waf在编写过程中考虑到性能原因,只处理一部分数据,这时可以通过加入大量垃圾数据来绕过其处理函数。
另外,Waf和Web系统对 boundary 的处理不一致,可以使用错误的 boundary 来完成绕过。

竞争上传绕过

服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生,此漏洞一般发生在多个线程同时访问同一个共享代码、变量、文件等没有进行锁操作或者同步操作的场景中

黑名单绕过

上传.htaccess文件绕过

.htaccess是Apache分布式配置文件的默认名称,也可以在Apache主配置文件中通过AccessFileName指令修改分布式配置文件的名称。Apache主配置文件中通过AllowOverride指令配置.htaccess文件中可以覆盖只配置文件的那些指令,在低于2.3.8的版本中,AllowOverride指令默认为All,在更高版本中默认为None(即.htaccess文件不发挥作用)。因此在低版本的Apache服务器环境中,我们可以尝试长传.htaccess文件修改部分配置,使用SetHandler/Addtype/AddHandler等指令使php解析指定文件,例如
AddType application/x-httpd-php .png
php_flag engine 1
即可用png文件做php脚本

上传.user.ini文件绕过

自PHP5.3.0起,在php执行的过程中,除了主 php.ini 之外,PHP 还会在每个目录下扫描.htaccess风格的 INI 文件(ini文件仅被CGI/FastCGI SAPI处理,默认文件名.user.ini),从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER[‘DOCUMENT_ROOT’] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。 .user.ini 中可以定义除了PHP_INI_SYSTEM以外的模式的选项,故可以使用 .user.ini 加上非php后缀的文件构造一个shell,比如 auto_prepend_file=01.gif。其中,auto_prepend_file命令可以指定一个文件在主文件解析前解析,相似的指令auto_append_file可以指定一个文件在主文件解析后解析
不过上传.user.ini文件绕过黑名单有比较大的限制,例如只有在当前目录下有PHP文件被执行时才会加载当前目录下的.user.ini文件,而上传目录下通常不会存在PHP文件,真要利用可能还需要配合其他漏洞

白名单绕过

IIS解析漏洞

IIS6 中有两个解析漏洞:

  • .asp 文件夹下的所有文件都会被当作脚本文件解析
  • xx.asp;xxx.jpg文件会被解析为脚本文件

Nginx解析漏洞

Nginx 的解析漏洞为配置不当时,例如try_files未配置且FPM未设置security.limit_extensions的场景下,如果上传了x.jpg文件,,再访问x.jpg/1.php, location为.php结尾,惠交给FPM处理,此时$fastcgi_script_name的值为x.jpg/1.php;在PHP开启cgi.fix_pathinfo配置时,x.jpg/1.php文件不存在,开始fallback去掉最右边的/及其后续内容,此时弱x.jpg存在,则会用PHP处理该文件

Apache解析漏洞

多后缀文件解析漏洞

当Apache使用了AddType(而非AddHandler)时,多后缀文件会从最右后缀开始识别,如果后缀不存在对应MIME type或Handler,则会继续向左识别直到有对应的MIME type或Handler,例如php。

Apache CVE-2017-15715漏洞

见参考链接

其他文件类型检查绕过

利用上传生成的临时文件绕过

PHP在上传文件时惠生成临时文件,在上传完成后会删除临时文件,在存在包含漏洞却无文件可包含时,可以尝试包含上传生成的临时文件配合利用

  • LFI via phpinfo
    由于上传生成的临时文件的文件名存在六位随机字符,并且在上传完成后会删除该文件,因此在有限的时间内找到临时文件名是一大重点。phpinfo会输出当前环境下的所有变量,包括 $_FILES,故可借phpinfo其获取tmp_name
  • LFI via Upload_Progress
  • LFI via Segmentation fault

利用file_put_contents绕过

Zip上传问题绕过

  • 未处理解压文件绕过
  • 未递归检测上传目录绕过
  • 条件竞争绕过
  • 解压异常导致推出绕过
  • 解压特殊文件绕过

Reference

构造优质上传漏洞Fuzz字典
.user.ini官方手册
.htaccess官方手册
Apache CVE-2017-15715
竞争上传
LFI

  • Title: 文件上传初探
  • Author: 7erry
  • Created at : 2023-08-22 00:00:00
  • Updated at : 2023-08-22 00:00:00
  • Link: http://7erry.com/2023/08/22/文件上传初探/
  • License: This work is licensed under CC BY-NC 4.0.