DVWA靶场通关笔记-文件上传(Medium级别)

目录

一、文件上传

二、文件上传之MIME绕过

三、代码审计

1、渗透准备

2、源码分析

(1)index.php

(2)服务端Medium.php

二、渗透实战

1、构造脚本

2、bp拦截报文

3、上传脚本

4、bp拦截并修改报文

5、获取脚本地址

6、访问脚本


本系列为通过《DVWA靶场通关笔记》的文件上传关卡(low,medium,high,impossible共4关)渗透集合,通过对相应关卡源码的代码审计找到讲解渗透原理并进行渗透实践,本文为文件上传Medium级别关卡的渗透部分。

一、文件上传

文件上传是指Web应用程序未对用户上传的文件进行严格验证,导致攻击者可上传恶意文件(如Webshell、木马程序等)到服务器,从而获取系统控制权或执行任意代码,该风险通常出现在应用程序允许用户上传文件的场景中。

二、文件上传之MIME绕过

文件上传 MIME 绕过是一种常见的攻击手段。在文件上传过程中,服务器通常会根据文件的 MIME 类型来验证文件是否合法。攻击者通过修改文件的 MIME 类型字段,将恶意文件伪装成合法的文件类型,如将可执行文件伪装成图片或文档类型。这样,服务器在验证时会误认为该文件是允许上传的类型,从而绕过上传限制。一旦恶意文件被成功上传并执行,攻击者就可能获取服务器的控制权,窃取敏感信息或进行其他破坏活动。MIME常用的类型如下所示。

MIME类型 文件扩展名 用途描述 安全风险等级
image/jpeg .jpg, .jpeg JPEG图像文件
image/png .png PNG图像文件
image/gif .gif GIF动画文件
text/plain .txt 纯文本文件
application/pdf .pdf PDF文档文件
application/zip .zip 压缩文件
application/x-php .php PHP脚本文件 极高
application/x-javascript .js JavaScript文件
text/html .html, .htm HTML网页文件
application/x-sh .sh Shell脚本文件 极高

三、代码审计

1、渗透准备

配置security为中等Medium级别,具体如下图红框所示。

进入到文件上传关卡Medium页面,完整URL地址具体如下所示。

复制代码
http://127.0.0.1/DVWA/vulnerabilities/upload/ 

2、源码分析

(1)index.php

进入DVWA靶场源目录,找到Medium.php源码。

这段代码实现了 DVWA (Damn Vulnerable Web Application) 中的文件上传关卡演示页面,主要功能包括如下处理流程。

  • 安全级别控制:根据用户`` Cookie ``中的``security``值`` (``低、中、高、不可能``)``,加载不同安全级别的处理逻辑
  • 环境检查:验证上传目录是否可写以及`` PHP-GD ``扩展是否安装
  • 表单展示:显示文件上传表单,允许用户上传文件
  • 辅助功能:提供安全文档链接,帮助用户理解文件上传安全风险

经过注释后的详细代码如下所示。

复制代码
<?php

// 定义网站根目录的相对路径
define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' );
// 包含 DVWA 的页面初始化文件
require_once DVWA_WEB_PAGE_TO_ROOT . 'dvwa/includes/dvwaPage.inc.php';

// 初始化页面,确保用户已认证,并加载 PHPIDS(PHP入侵检测系统)
dvwaPageStartup( array( 'authenticated', 'phpids' ) );

// 获取页面信息
$page = dvwaPageNewGrab();
// 设置页面标题
$page[ 'title' ]   = 'Vulnerability: File Upload' . $page[ 'title_separator' ].$page[ 'title' ];
// 设置页面 ID
$page[ 'page_id' ] = 'upload';
// 设置帮助按钮和源代码按钮
$page[ 'help_button' ]   = 'upload';
$page[ 'source_button' ] = 'upload';

// 连接数据库
dvwaDatabaseConnect();

// 根据安全级别选择对应的文件
$vulnerabilityFile = '';
switch( $_COOKIE[ 'security' ] ) {
	case 'low':
		$vulnerabilityFile = 'low.php'; // 低安全级别
		break;
	case 'medium':
		$vulnerabilityFile = 'medium.php'; // 中安全级别
		break;
	case 'high':
		$vulnerabilityFile = 'high.php'; // 高安全级别
		break;
	default:
		$vulnerabilityFile = 'impossible.php'; // 最高安全级别
		break;
}

// 包含对应级别的文件
require_once DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/upload/source/{$vulnerabilityFile}";

// 检查上传目录是否可写
$WarningHtml = '';
if( !is_writable( $PHPUploadPath ) ) {
	$WarningHtml .= "<div class=\"warning\">Incorrect folder permissions: {$PHPUploadPath}<br /><em>Folder is not writable.</em></div>";
}
// 检查是否安装了 PHP-GD 模块
if( ( !extension_loaded( 'gd' ) || !function_exists( 'gd_info' ) ) ) {
	$WarningHtml .= "<div class=\"warning\">The PHP module <em>GD is not installed</em>.</div>";
}

// 构建页面内容
$page[ 'body' ] .= "
<div class=\"body_padded\">
	<h1>Vulnerability: File Upload</h1>

	{$WarningHtml} // 显示警告信息

	<div class=\"vulnerable_code_area\">
		<form enctype=\"multipart/form-data\" action=\"#\" method=\"POST\"> // 文件上传表单
			<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"100000\" /> // 限制上传文件大小
			Choose an image to upload:<br /><br />
			<input name=\"uploaded\" type=\"file\" /><br /> // 文件选择框
			<br />
			<input type=\"submit\" name=\"Upload\" value=\"Upload\" />\n";

// 如果是最高安全级别,添加 CSRF 令牌字段
if( $vulnerabilityFile == 'impossible.php' )
	$page[ 'body' ] .= "			" . tokenField();

$page[ 'body' ] .= "
		</form>
		{$html} // 显示上传结果或其他信息
	</div>

	<h2>More Information</h2> // 提供更多关于文件上传信息
	<ul>
		<li>" . dvwaExternalLinkUrlGet( '<url id="d0g9jpaej2dnt3123or0" type="url" status="parsed" title="Unrestricted File Upload | OWASP Foundation" wc="24644">https://www.owasp.org/index.php/Unrestricted_File_Upload</url> ' ) . "</li>
		<li>" . dvwaExternalLinkUrlGet( '<url id="d0g9jpaej2dnt3123org" type="url" status="parsed" title="Fortra's Beyond Security" wc="1516">https://blogs.securiteam.com/index.php/archives/1268</url> ' ) . "</li>
		<li>" . dvwaExternalLinkUrlGet( '<url id="d0g9jpaej2dnt3123os0" type="url" status="parsed" title="File Upload Bypass: Upload Forms Threat Explained" wc="13700">https://www.acunetix.com/websitesecurity/upload-forms-threat/</url> ' ) . "</li>
	</ul>
</div>";

// 输出页面内容
dvwaHtmlEcho( $page );

?>

(2)服务端Medium.php

进入DVWA靶场源目录,找到Medium.php源码,如下图所示。

打开源码Medium.php,分析可知这段代码实现了一个不安全的文件上传功能,参数为POST型参数,因为其未对参数进行任何过滤,如下所示。

这段代码实现了一个基本的文件上传功能,具体如下所示。

  • 路径构建
    • 将上传文件存储到 hackable/uploads/ 目录
    • 使用 basename 函数过滤文件名,防止目录遍历攻击
  • 文件验证
    • 类型验证 :检查 $_FILES['uploaded']['type'] 是否为 image/jpeg 或 image/png
    • 大小验证 :检查文件大小是否小于 100KB
  • 文件处理
    • 如果验证通过,使用 move_uploaded_file 将临时文件移动到目标目录
    • 根据处理结果输出成功或失败信息

很明显代码中仅对报文的MIME字段进行检查,可以通过修改MIME字段绕过,故而存在文件上传安全风险。

复制代码
<?php

// 检查用户是否提交了上传表单
if( isset( $_POST[ 'Upload' ] ) ) {
    // 构建上传文件的目标路径
    // DVWA_WEB_PAGE_TO_ROOT 是网站根目录常量
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    // 使用 basename 函数确保文件名不包含路径信息,防止目录遍历攻击
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // 获取上传文件的相关信息
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];  // 原始文件名
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];  // MIME类型(由浏览器提供)
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];  // 文件大小(字节)

    // 验证文件类型和大小
    // 检查 MIME 类型是否为 JPEG 或 PNG,并且文件大小小于 100KB
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {

        // 尝试将临时上传文件移动到目标路径
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
            // 移动失败,输出错误信息
            $html .= '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // 移动成功,输出成功信息(包含完整上传路径)
            $html .= "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // 文件类型或大小不符合要求,输出错误信息
        $html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>

虽然代码尝试进行了安全验证,但仍存在以下安全风险。

  • MIME 类型验证不可靠
    • $_FILES['uploaded']['type'] 由浏览器提供,可被轻易伪造
    • 攻击者可通过修改 HTTP 请求头绕过此验证
  • 无扩展名验证
    • 允许上传任意扩展名的文件,即使 MIME 类型正确
    • 攻击者可上传 .php 文件并伪造 MIME 类型为 image/jpeg

二、渗透实战

1、构造脚本

构造文件上传的脚本test.php,内容为获取服务器的php版本信息,脚本 code 内容如下所示。

复制代码
<?php phpinfo();?>

2、bp拦截报文

burpsuite中的inception设置为on状态,具体如下所示。

3、上传脚本

进入DVWA靶场的文件上传关卡Medium级别,设置代理将报文发送到burpsuite,选择test.php,点击上传如下所示。

4、bp拦截并修改报文

在bp中找到报文,需将下图红框内容修改为合法的MIME字段,如下所示。

将红框内容修改为"image/jpeg"或者"image/png"之一,这里我们选择image/jpeg,修改后的报文如下所示。

5、获取脚本地址

上传后路径如下所示,相对于当前路径/dvwa/vulnerabilities/upload/,webshell被上传至../../hackable/uploads/test.php路径下,故而这个webshell的路径应该如下所示。

复制代码
http://127.0.0.1/dvwa//hackable/uploads/test.php

6、访问脚本

完整的渗透URL地址如下所示,并在浏览器地址栏输入,如下所示获取服务器的php信息,渗透成功。

复制代码
http://127.0.0.1/dvwa//hackable/uploads/test.php
相关推荐
安全系统学习1 小时前
【网络安全】Mysql注入中锁机制
安全·web安全·网络安全·渗透测试·xss
缘友一世13 小时前
网安系列【4】之OWASP与OWASP Top 10:Web安全入门指南
安全·web安全
安全系统学习1 天前
网络安全之SQL RCE漏洞
安全·web安全·网络安全·渗透测试
聚铭网络1 天前
案例精选 | 某省级税务局AI大数据日志审计中台应用实践
大数据·人工智能·web安全
GLAB-Mary1 天前
AI会取代网络工程师吗?理解AI在网络安全中的角色
网络·人工智能·web安全
galaxylove1 天前
Gartner发布最新指南:企业要构建防御性强且敏捷的网络安全计划以平衡安全保障与业务运营
网络·安全·web安全
SuperherRo2 天前
Web攻防-文件上传&黑白名单&MIME&JS前端&执行权限&编码解析&OSS存储&分域名&应用场景
文件上传·mime·黑白名单·js前端·执行权限·编码解析·oss存储
学习溢出2 天前
【网络安全】持续监控CI/CD:自动发现威胁与IoCs,软件供应链安全
运维·安全·web安全·网络安全·ci/cd
速盾cdn2 天前
速盾:高防CDN还有哪些冷知识?
网络·web安全