前言
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。(以下内容默认为后端检测)
获取文件信息
不能作为文件名的字符
/ 和 \:目录分隔符。
::在某些操作系统中用于分隔驱动器。
*, ?, ", <, >, |:在文件系统中有特殊意义。
控制字符:如 ASCII 0-31(例如换行符、回车符)。
某些文件系统限制的字符:如某些文件系统可能不允许使用空格或特定符号
如果文件名里出现了这些信息,则出现位置前都会被去掉,这样的设定一定程度上限制了文件上传漏洞的利用,如上传到/tmp目录下,而php工作目录在/www,无法用网址解析,则不存在文件上传漏洞
大部分文件上传函数都不会处理文件名里的字符,如$_FILES['userfile']['name']
不会 自动去除或过滤文件名中的 ../ 或其他路径遍历片段;它原样返回浏览器提交的 filename 值
$_FILES
1 | -----------------------------33914302138280584133217113628 |
中括号的file为上传字段名,当然可以是其他字符串,只要对应就好了
1 |
|
通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件。
第一个参数是表单的 input name,第二个下标可以是 “name”、”type”、”size”、”tmp_name” 或 “error”。如下所示:
$_FILES["file"]["name"] - 上传文件的名称
$_FILES["file"]["type"] - 上传文件的类型(抓包可修改)
$_FILES["file"]["size"] - 上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"] - 由文件上传导致的错误代码
UPLOAD_ERR_OK 其值为 0,没有错误发生,文件上传成功。
UPLOAD_ERR_INI_SIZE 其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。
UPLOAD_ERR_FORM_SIZE 其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE选项指定的值。
UPLOAD_ERR_PARTIAL 其值为 3,文件只有部分被上传。
UPLOAD_ERR_NO_FILE 其值为 4,没有文件被上传。
UPLOAD_ERR_NO_TMP_DIR 其值为 6,找不到临时文件夹。
UPLOAD_ERR_CANT_WRITE 其值为 7,文件写入失败。
WAF绕过
Content-Disposition:一般可修改(接收的类型,form-data就表示接收的是表单的数据)
name:表单参数值,不能更改
filename:文件名,可以更改
Content-Type:文件MIME,视情况更改
1 | MIME值 含义 |
常见绕过方法:
- 数据溢出-防匹配(xxx…)
- 符号编译-防匹配(’ “ ; )
- 数据截断-防匹配(%00 ; 换行)
- 重复数据-防匹配(参数多次)
黑名单
黑名单后缀检测绕过
一般分为两种,一种是代码层次的黑名单绕过,及在检测后缀后,有可能存在修改,如检测后删除文件名中的空格,把后缀一起修改了
第二种是系统与代码解析差异导致的绕过,如win不区分大小写,Windows中文件后缀名.系统会自动忽略
1 | $file_name = deldot($file_name);//删除文件名末尾的点 Windows中文件后缀名.系统会自动忽略,点号绕过 |
在window的时候如果文件名+::$DATA
会把::$DATA
之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名
其他有可能正常解析的后缀
PHP: .php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc
ASP: .asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
Jsp: .jsp, .jspx, .jsw, .jsv, .jspf
exif_imagetype
和@getimagesize($tmp_name)[2]
可以通过抓包将文件内容的开头加上GIF89a(一种GIF标识)的方法绕过
利用自定义解析绕过白名单
Apache的.htaccess
从安全性考虑,根目录的AllowOverride属性一般都配置成None
不允许任何Override,需要更改文件 /etc/apache2/apache2.conf
htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置,利用Apache的rewrite模块对URL进行重写,rewrite规则会写在 .htaccess 文件里
1 | <Directory /var/www/> |
需要用到的代码如下:
1 | <FilesMatch "匹配内容"> |
实战意义:
1、如果存在可以上传 .htaccess 文件,就可以直接利用此规则解析;
2、如果存在修改文件权限,就直接修改解析规则;
.user.ini留后门
.htaccess是伪静态环境配置文件,用于lamp。
.user.ini是lnmp文件,里面放的是你网站的文件夹路径地址。目的是防止跨目录访问和文件跨目录读取.
指定一个文件,自动包含在要执行的文件前,类似于在文件前调用了require()函数。而auto_append_file类似,只是在文件后面包含。
跟.htaccess后门比,适用范围更广,nginx/apache/IIS都有效,而.htaccess只适用于apache
使用方法很简单,直接写在.user.ini中:
1 | GIF89a |
11.gif是要包含的文件。
1 | auto_prepend_file 在文顶部插入加载文件; |
我们可以借助.user.ini轻松让所有php文件都“自动”包含某个文件,而这个文件可以是一个正常php文件,也可以是一个包含一句话的webshell。
白名单
绕过白名单的方法同样适用于黑名单
1 | $ext_arr = array('jpg','png','gif'); |
php老版本文件截断绕过
1 | include('files/'.$action.'.php'); //载入相应文件 |
00截断绕过
要求:
php<5.3.4 magic_quotes_gpc=off(默认on,5.4以后该选项被移除)
检测原理:
有很多0x00,%00,/00之类的截断,但是核心都在chr(0)这个字符,它可以返回ascii字符,所以chr(0)表示的是null,如果变量是从用户$_GET或$_POST中获得的并且我们可控,那么我们可以利用空字符\x00来截断后面的拓展名,从而造成任意文件上传。
长度截断绕过
要求:
php版本<=5.2.8
linux 需要文件名长于 4096,windows 需要长于 256,超过部分会被丢弃从而实现文件包含绕过后缀.php限制
竞争上传
检测原理:
1 | $upload_file = $UPLOAD_ADDR . '/' . $file_name; |
文件先经过保存 ,然后判断后缀名是否在白名单中, 如果不在则删除. 此时可以利用条件竞争在保存文件后删除文件前来执行php文件
中间件解析漏洞
IIS5.x-6.x解析漏洞
使用iis5.x-6.x版本的服务器,大多为windows server 2003,网站比较古老,开发语句一般为asp;该解析漏洞也只能解析asp文件,而不能解析aspx文件。
目录解析(6.0)
形式:www.xxx.com/xx.asp/xx.jpg
原理::服务器默认会把.asp,.asa目录下的文件都解析成asp文件。
文件解析(5.0/6.0)
形式:www.xxx.com/xx.asp;.jpg
原理:服务器默认不解析;号后面的内容,因此xx.asp;.jpg便被解析成asp文件了。
解析文件类型
IIS6.0 默认的可执行文件除了asp还包含这三种 :
/test.asa
/test.cer
/test.cdx
IIS 7.0、IIS 7.5、Nginx(engine x) <8.03 畸形解析漏洞
漏洞原理
在默认Fast-CGI开启状况下,当访问 www.xx.com/phpinfo.jpg/1.php 这个URL时,$fastcgi_script_name会被设置为“phpinfo.jpg/1.php”,然后构造成SCRIPT_FILENAME传递给PHP CGI,但是PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析。这就要说到fix_pathinfo这个选项了, 如果开启了这个选项,那么就会触发在PHP中的如下逻辑:
PHP会认为SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了。
漏洞形式
www.xxxx.com/UploadFiles/image/1.jpg/1.php
www.xxxx.com/UploadFiles/image/1.jpg%00.php
www.xxxx.com/UploadFiles/image/1.jpg/%20\0.php
另外一种手法:上传一个名字为test.jpg,以下是文件的内容:
‘);?>
然后访问 test.jpg/.php,在这个目录下就会生成一句话木马shell.php。
Nginx(engine x)< 0.8.03 空字节代码 解析漏洞
影响版:0.5、0.6、0.7<= 0.7.65、0.8 <= 0.8.37
Nginx在图片中嵌入PHP代码然后通过访问
xxx.jpg%00.php
来执行其中的代码;
apache 1.x , 2.x解析漏洞
漏洞原理
Apache在解析文件名的时候是从右向左读
例如:test.php.owf.rar “.owf”和”.rar” 这两种后缀是apache不可识别解析,apache就会把test.php.owf.rar解析成php。
Apache%0A解析截断(Apache2.4.0到2.4.29)
如上传a.php,然后在burp中修改文件名为a.php\x0A
图片木马
制作方法
/a表示ASCII码 , /b代表二进制文件
编辑器的利用
- 获取编辑器的名称及版本信息
扫描爬行或字典扫描探针
观察图片的地址或编辑器特征
- 获取编辑器相关的漏洞
例如:直接搜索引擎搜索“fckeditor 漏洞”会出来很多的。
- 利用编辑器漏洞进行攻击测试
unzip() 软链接攻击
1 | #先构造一个指向 /var/www/html 的软连接: |