Web基础-文件上传合集

文件上传在Web业务中很常见。如果没有对用户上传的文件做好处理,会导致非常严重的安全问题。

本专题是对文件上传一些知识点的摘要总结

截断

00截断

php代码的底层是c语言,故字符串的结束符’\0’常用来作截断

常用于通过白名单校验,如1.php\00.jpg可以通过对jpg后缀的白名单检测,但是实际保存文件时将保存为1.php

转换字符集截断

低版本的php在实现字符集转换时常用iconv()函数,超出UTF-8单字节允许的字符范围(0x00~0x7F)时将不再处理之后的字符,从而造成截断

例如1.php\x99.jpg,最终保存为1.php

黑名单校验

常用文件后缀

php: php3,php5,phtml,pht

asp: cdx,der,asa

jsp: jspx

windows系统下也可以尝试”php”,”php::$DATA”,”php.”,”a.php:.jpg”

另,windows环境下文件名不区分大小写,可以绕过in_array

.htaccess文件

.htaccess可以修改配置,使服务器以PHP解析指定文件

1
2
SetHandler application/x-httpd-php//所有的文件当做php文件来解析
AddType application/x-httpd-php .jpg//.jpg文件当作php文件解析

.user.ini文件

.user.ini与.htaccess有相似的效果,在过滤了.htaccess时可以尝试

1
2
3
GIF89a                  //绕过exif_imagetype()
auto_prepend_file=a.jpg //指定在主文件之前自动解析的文件的名称,并包含该文件
auto_append_file=a.jpg //解析后进行包含

白名单校验

ISS解析漏洞

*.asp文件夹下所有文件都会被当作脚本文件解析

1.asp;a.jpg会被解析为asp

Nginx解析漏洞

Nginx未配置try_files且FPM未设置security.limit_extension时可能出现解析漏洞

上传x.jpg文件后,访问x.jpg/x.php会以php解析文件

Apache多后缀解析漏洞

AddHandler application/x-httpd-php .php配置下,x.php.xxx会被application/x-httpd-php处理

若使用AddType,多后缀文件将从最右边的后缀开始识别直到存在对应MIME type或Handler

白名单中有偏门后缀时可尝试

CVE-2017-15715

HTTPD2.4.0到2.4.29版本中,FileMatch指令中的”$”会匹配到换行符,可使用x.php\n(x.php%0A)绕过

文件禁止访问

最好的文件无法访问的绕过方法是上传到根目录

.htaccess禁止脚本文件执行

.htaccess可以配置上传的脚本文件无法执行,不过在AllowOverride为none时,.htaccess下的指令无法使用

文件上传到OSS

可以通过上传HTML,SVG等文件让浏览器解析实现XSS。

虽然XSS在aliyuncs.com域下没什么用,但是很多网站会把OSS绑定在自己的二级域名下,这时XSS就可以利用了

配合文件包含

若是上传的脚本文件无法被访问或不被解析,可以考虑配合文件包含实现解析

SSTI中也可能出现类似的情况

一些不当配置导致绕过

Nginx配置不正确时,x.php/xxx格式可能导致绕过

Nginx的location块先匹配普通location再匹配正则location。如果多个普通location都匹配url,则按最长前缀原则选择,且在非完全匹配情况下还会继续交给正则location检测,并在匹配成功时覆盖匹配结果。

正则location匹配成功后不再继续匹配,正则location匹配顺序与在配置文件中的物理顺序有关

1
2
3
4
5
<Directory "/var/www/html/upload/">
<FilesMatch ".(php|php5|html)$">
Deny from all
</FilesMatch>
</Directory>

Apache配置如上时可以通过上传x.php.aaa绕过

绕过图片验证

getimagesize

把php代码添加到图片内容后面就行了,也可以使用XBM通过getimagesize同时利用imagemagick

imagecreatefromjpeg

绕过脚本:https://github.com/BlackFan/jpg_payload

临时文件利用

常配合文件包含

LFI via phpinfo

phpinfo会输出当前环境下所有变量,包括临时文件文件名。如果存在phpinfo文件,往phpinfo上传一个文件可以拿到tmp_name。

Upload_Progress

当session.upload_progress.enabled开启时,上传文件时POST与ini中设置的session.upload_progress.name同名变量,PHP会往Session中添加一组包含上传进度等信息的数据。上传时POST php_session_upload_progress,上传文件名会写入SESSION,而PHPSESSION默认以文件保存,进而配合LFI

如果session.upload_progress.cleanup配置为ON,则需要用到条件竞争,在Session文件被清除前包含到Session,最终实现代码执行。

Segmentation fault

向Segmentation fault异常的地址上传文件,使其在垃圾回收前异常退出,临时文件就不会被删除,并通过大量上传文件枚举文件名的所有可能,最终实现LFI

file_put_contents的文件上传

黑名单绕过

当文件名为x.php/.时,能够正常写入php文件。

die绕过

很多网站会在文件开头加入<?php exit();?>

可以通过协议进行b64decode进行绕过

ZIP上传

很多系统支持上传zip压缩包,再在后端进行解压

未递归检查

可以尝试在压缩包内新建例如x.jpg的目录

条件竞争

通过脚本在文件被删除前进行访问

使解压异常退出

010 Editor将x.php后的内容修改为0xFF,就会解压失败

目录穿越

在文件名中加入../进行目录穿越(PclZip构造时,包内第一个文件需要是正常文件)