1. 为什么我建议每个做安全测试的人都从DVWA开始
刚入行做安全测试那会儿,我最头疼的不是挖不到漏洞,而是没有一套能让我放心大胆练手的环境。在真实业务系统上测试,手一抖就可能把生产数据搞崩;随便找个网站练手,又涉及法律风险。后来一位前辈跟我说了句实在话:“你先去把DVWA玩明白,再谈别的。”这句话我记到现在。
DVWA,全称Damn Vulnerable Web Application,翻译过来就是“该死的脆弱Web应用”。它是一套刻意设计得千疮百孔的Web靶场,把SQL注入、XSS跨站脚本、文件包含、命令注入、CSRF等常见Web安全漏洞全部内置其中,并且每个漏洞都提供了从低到高四个安全等级,让你能循序渐进地理解漏洞的成因、利用方式和防御思路。说白了,它就是一个专门给你“合法搞破坏”的沙盒环境。
这篇文章适合谁看?如果你是刚接触安全测试的新人,想找一个能反复练手又不用担心法律问题的环境,DVWA是最合适的起点。如果你已经有一定基础,但一直用别人的在线靶场,想在自己电脑上搭一套随时能用的离线环境,这篇内容同样对你有用。我会从环境选型、搭建步骤、配置细节到常见报错排查,把整个流程拆开揉碎讲清楚,让你照着做就能跑起来。
需要提前说明的是,DVWA本身是一个开源的学习工具,它的价值在于帮助你理解漏洞原理,从而在真实工作中写出更安全的代码、做出更靠谱的防护方案。请务必只在你自己搭建的本地环境中使用,不要拿学到的技术去测试任何未经授权的系统。
2. 搭建前的整体思路与环境选型
2.1 为什么选择本地搭建而不是在线靶场
很多人第一反应是去找一个在线DVWA靶场,打开浏览器就能用,省事。但我实测下来,在线靶场有几个绕不开的问题。第一是网络延迟,尤其是做时间盲注这类需要精确控制请求间隔的测试时,延迟会严重影响判断。第二是数据不持久,你今天传的webshell,明天可能就被环境重置了,没法做持续性的研究。第三是隐私问题,你在靶场里的所有操作记录都在别人的服务器上,虽然DVWA本身不涉及敏感数据,但从习惯养成角度来说,本地环境更让人安心。
本地搭建的核心优势在于完全掌控。你可以随意修改数据库、调整PHP配置、查看服务器日志,甚至把靶场源码改得面目全非来测试特定场景。这种自由度是在线靶场给不了的。而且一旦搭好,断网也能用,通勤路上、出差途中都能随时打开练手。
2.2 三种主流搭建方案对比
DVWA是基于PHP+MySQL的Web应用,所以本质上你需要一个能跑PHP和MySQL的Web服务器环境。目前主流有三种方案,我逐一分析各自的适用场景。
| 方案 | 核心工具 | 优点 | 缺点 | 适合人群 |
|---|---|---|---|---|
| 集成环境包 | XAMPP/phpStudy | 一键安装,省去配置麻烦 | 版本固定,灵活性差 | 纯新手,只想快速跑起来 |
| 容器化部署 | Docker + Docker Compose | 环境隔离,秒级启动,易于迁移 | 需要基础Docker知识 | 有一定运维基础的测试人员 |
| 手动编译安装 | Apache/Nginx + PHP + MySQL | 完全可控,可自定义版本 | 配置繁琐,容易踩坑 | 想深入理解Web架构的学习者 |
我个人推荐新手从XAMPP入手,因为它把Apache、PHP、MySQL、phpMyAdmin打包在一起,安装过程基本就是一路点“下一步”。等你对整套架构熟悉了,再尝试Docker方案,那时候你会对“环境隔离”和“可复现性”有更深的体会。手动编译安装我不建议作为第一次搭建的选择,除非你本身就有Linux运维经验,否则光解决PHP扩展依赖就能耗掉一整天。
2.3 版本选择的一个关键细节
DVWA的源码在持续更新,不同版本对PHP和MySQL的版本要求不一样。我踩过的一个坑是:用最新版DVWA搭配老版本XAMPP,结果因为PHP版本过高导致某些函数被废弃,页面直接报错。反过来,用太老的DVWA搭配新PHP,也会因为MySQL连接方式变更而连不上数据库。
我的建议是:如果你用XAMPP,选择PHP 7.4到8.0之间的版本比较稳妥,MySQL用5.7或8.0都可以。DVWA官方在GitHub上维护的master分支对PHP 8.x的支持已经比较完善,但如果你下载的是某些第三方打包的旧版本,最好先看一眼它的README里写的环境要求。具体操作时,先确认XAMPP的PHP版本,再去DVWA的配置文件里核对,两边对上了再往下走,能省掉很多莫名其妙的报错。
3. 基于XAMPP的完整搭建实操
3.1 XAMPP的安装与初始配置
先从XAMPP官网下载对应操作系统的安装包。Windows用户直接下exe,macOS用户下dmg,Linux用户可以用run文件或者直接走包管理器。安装路径我建议不要放在C盘根目录或者带中文的路径下,比如C:\xampp或者/opt/lampp这种纯英文短路径最省心。我见过有人把XAMPP装在C:\用户\张三\我的软件\xampp下面,结果Apache启动时报路径解析错误,排查了半天才发现是中文路径的问题。
安装完成后打开XAMPP控制面板,你需要启动两个服务:Apache和MySQL。点击对应的Start按钮,如果按钮变成绿色背景的Stop,说明启动成功。这里有个细节:如果Apache启动失败,大概率是80端口被占用了。Windows上常见的原因是IIS或者某些国产软件占用了80端口,你可以点击Apache的Config按钮,把httpd.conf里的Listen 80改成Listen 8080,后面访问时用http://localhost:8080即可。
MySQL启动失败的情况相对少一些,如果遇到,先检查3306端口是否被其他MySQL实例占用。你可以在命令行执行netstat -ano | findstr 3306(Windows)或lsof -i :3306(macOS/Linux)来确认。如果有占用,要么停掉那个服务,要么把XAMPP的MySQL端口改成3307,同时记得后面配置DVWA时同步修改。
3.2 DVWA源码的获取与放置
DVWA的源码可以从它的官方GitHub仓库获取,直接下载zip包解压,或者用git clone命令拉取。我习惯用git clone,因为后续更新方便,一条git pull就能同步最新代码。
git clone https://github.com/digininja/DVWA.git下载完成后,把整个DVWA文件夹放到XAMPP的web根目录下。Windows上默认是C:\xampp\htdocs\,macOS上默认是/Applications/XAMPP/htdocs/,Linux上默认是/opt/lampp/htdocs/。放进去之后,文件夹结构应该是htdocs/DVWA/index.php这样的层级,不要多套一层目录,否则访问路径会变得很长。
放好之后,在浏览器里访问http://localhost/DVWA/,你应该能看到DVWA的登录页面。如果看到的是目录列表或者403错误,说明Apache没有正确解析PHP,或者目录权限有问题。Linux和macOS下需要确保htdocs目录及其子目录有可读可执行权限,可以用chmod -R 755 DVWA来设置。
3.3 数据库的创建与配置
DVWA的登录页面能打开,不代表就能直接用。它需要连接MySQL数据库,而数据库和对应的用户需要你手动创建。这一步是新手最容易卡住的地方,我详细拆解。
首先,DVWA的配置文件在config目录下,有一个config.inc.php.dist文件。你需要把它复制一份并重命名为config.inc.php。这个文件里定义了数据库连接信息,默认内容大概是这样的:
$_DVWA[ 'db_server' ] = '127.0.0.1'; $_DVWA[ 'db_database' ] = 'dvwa'; $_DVWA[ 'db_user' ] = 'dvwa'; $_DVWA[ 'db_password' ] = 'p@ssw0rd'; $_DVWA[ 'db_port' ] = '3306';这里有个关键点:DVWA默认要求数据库用户是dvwa,密码是p@ssw0rd,数据库名是dvwa。你可以选择在MySQL里创建这个用户并授权,也可以修改配置文件用root用户连接。我建议按照默认配置来创建独立用户,这样更贴近真实环境的最小权限原则。
打开phpMyAdmin(XAMPP自带,访问http://localhost/phpmyadmin/),登录后执行以下SQL语句:
CREATE DATABASE IF NOT EXISTS dvwa; CREATE USER 'dvwa'@'localhost' IDENTIFIED BY 'p@ssw0rd'; GRANT ALL PRIVILEGES ON dvwa.* TO 'dvwa'@'localhost'; FLUSH PRIVILEGES;如果你用的是MySQL 8.0,创建用户时可能会遇到密码策略限制,提示密码太简单。这时候要么换一个复杂点的密码并同步修改配置文件,要么临时调整密码策略。我一般选择前者,因为改密码策略在生产环境是不推荐的操作,养成好习惯从练习环境开始。
数据库创建好之后,回到DVWA的登录页面,用默认账号admin和密码password登录。登录成功后,你会看到左侧菜单里有一个“Setup DVWA”或者“Create / Reset Database”的按钮,点击它,DVWA会自动创建所需的表并填充初始数据。如果这一步报错,通常是数据库连接信息不对,回头检查config.inc.php里的配置和实际创建的数据库用户是否一致。
3.4 安全等级的切换与理解
DVWA最核心的设计就是四个安全等级:Low、Medium、High、Impossible。这个等级不是指靶场本身的安全性,而是指靶场中每个漏洞模块的防护强度。Low级别几乎没有任何防护,你可以用最直接的方式利用漏洞;Medium级别加入了一些基础的过滤和转义;High级别使用了更严格的防护措施;Impossible级别则是理论上安全的实现,用来对比学习正确的防御方式。
切换安全等级的方式很简单,登录后在左侧菜单点击“DVWA Security”,在下拉框里选择对应等级,然后点击Submit即可。我建议的学习路径是:先在一个模块里把Low级别的漏洞利用方式彻底搞懂,然后切到Medium,观察防护措施是什么,思考如何绕过,再切到High,最后看Impossible级别的源码,理解为什么那样写是安全的。这个对比学习的过程,比单纯看教程要深刻得多。
注意:每次切换安全等级后,部分模块可能需要重新提交表单才能生效。如果你发现切换后漏洞利用方式没变化,先刷新页面或者重新进入该模块再试。
4. 基于Docker的进阶部署方案
4.1 为什么值得再学一套Docker方案
XAMPP方案虽然简单,但它有一个硬伤:环境是全局的。你电脑上只能装一个XAMPP,PHP版本、MySQL版本都是固定的。如果你同时想练DVWA和另一个需要不同PHP版本的靶场,就会冲突。Docker方案通过容器隔离解决了这个问题,每个靶场跑在自己的容器里,互不干扰。
另外,Docker方案的启动速度极快,一条命令就能拉起整套环境,销毁也干净利落,不会在系统里留下各种残留文件。对于需要频繁重置靶场状态的人来说,Docker几乎是唯一的选择。你只需要把容器删掉重新跑一个,所有数据就回到初始状态了。
4.2 Docker与Docker Compose的安装
Docker的安装这里不展开太多,Windows和macOS用户直接下载Docker Desktop安装包,一路默认安装即可。Linux用户可以用官方脚本安装,但要注意安装后需要把当前用户加入docker组,否则每次执行docker命令都要加sudo。
sudo usermod -aG docker $USER执行完这条命令后需要重新登录终端才能生效。验证安装是否成功,运行docker --version和docker compose version,能正常输出版本号就说明环境就绪了。
4.3 编写DVWA的Docker Compose配置
DVWA官方并没有提供一个现成的Docker Compose文件,但社区里有不少维护良好的镜像。我一般选择vulnerables/web-dvwa这个镜像,它把Apache、PHP和DVWA源码都打包好了,只需要再配一个MySQL容器即可。
新建一个目录,比如~/dvwa-docker,在里面创建一个docker-compose.yml文件,内容如下:
version: '3.8' services: dvwa: image: vulnerables/web-dvwa container_name: dvwa-web ports: - "8080:80" environment: - DB_SERVER=dvwa-db - DB_DATABASE=dvwa - DB_USER=dvwa - DB_PASSWORD=p@ssw0rd depends_on: - dvwa-db restart: unless-stopped dvwa-db: image: mysql:5.7 container_name: dvwa-mysql environment: - MYSQL_ROOT_PASSWORD=rootpassword - MYSQL_DATABASE=dvwa - MYSQL_USER=dvwa - MYSQL_PASSWORD=p@ssw0rd volumes: - dvwa-db-data:/var/lib/mysql restart: unless-stopped volumes: dvwa-db-data:这份配置里有两个关键点需要解释。第一,depends_on只保证容器启动顺序,不保证MySQL服务已经就绪。DVWA容器启动时如果MySQL还没准备好,可能会连接失败。解决办法是等MySQL容器完全启动后,手动重启一下DVWA容器,或者在DVWA容器里加一个等待脚本。我通常的做法是等半分钟再访问,如果报错就重启DVWA容器,简单有效。
第二,volumes把MySQL的数据持久化了。这意味着你即使删掉容器,数据库里的数据还在。如果你想要一个完全干净的环境,需要同时删除volume:docker compose down -v。这个-v参数很关键,不加的话数据会一直留着。
4.4 启动与初始化
在docker-compose.yml所在目录执行:
docker compose up -d-d表示后台运行。执行完成后用docker compose ps查看容器状态,两个容器都显示Up就说明启动成功。然后浏览器访问http://localhost:8080,用admin/password登录,点击“Create / Reset Database”完成初始化。
Docker方案下如果遇到数据库连接错误,先检查两个容器的日志:docker compose logs dvwa和docker compose logs dvwa-db。常见原因是MySQL容器初始化时间较长,DVWA容器启动太快导致连接被拒。解决办法就是重启DVWA容器:docker compose restart dvwa。
5. 搭建过程中最容易踩的六个坑
5.1 PHP版本不兼容导致的致命错误
这是最高频的问题。DVWA的某些函数在PHP 8.0中被废弃或移除了,如果你用的XAMPP自带PHP 8.1或更高版本,访问DVWA时可能会看到类似Fatal error: Uncaught Error: Call to undefined function mysql_connect()的报错。这是因为旧版DVWA还在用mysql_*系列函数,而PHP 7.0之后这些函数已经被移除。
解决办法有两个:要么降级PHP到7.4,要么使用最新版DVWA源码。我建议用最新版源码,因为官方已经迁移到了mysqli和PDO。如果你下载的是某些第三方打包的“汉化版”或“整合版”,很可能用的是旧代码,这时候要么换源,要么手动改代码,后者工作量不小。
5.2 数据库连接被拒绝的排查思路
报错信息通常是Could not connect to the database。排查顺序我总结为三步:先确认MySQL服务是否在运行,再确认配置文件里的用户名密码和实际创建的是否一致,最后确认数据库用户是否有从localhost连接的权限。
第三步容易被忽略。MySQL的用户是区分host的,dvwa@localhost和dvwa@127.0.0.1是两个不同的用户。如果你的配置文件里写的是127.0.0.1,但创建用户时只写了localhost,就会连接失败。保险的做法是创建用户时host用%,或者同时创建localhost和127.0.0.1两个。
5.3 文件上传模块无法写入的权限问题
DVWA的文件上传漏洞模块需要把上传的文件保存到服务器磁盘上。在Linux和macOS下,如果Apache进程没有对hackable/uploads目录的写权限,上传就会失败。解决办法是给这个目录设置写权限:
chmod 777 hackable/uploads我知道777权限在安全角度是不推荐的,但在本地练习环境里,为了方便调试,这是最直接的办法。如果你在意权限管理,可以把目录的所有者改成Apache运行用户,比如chown www-data:www-data hackable/uploads,然后设置755权限。
5.4 reCAPTCHA密钥未配置的提示
登录DVWA后,某些页面顶部可能会显示一条红色提示,说reCAPTCHA key没有设置。这个提示不影响核心功能使用,但看着烦。如果你想去掉它,可以在config/config.inc.php里把$_DVWA[ 'recaptcha_public_key' ]和$_DVWA[ 'recaptcha_private_key' ]随便填两个非空值,提示就会消失。当然,如果你真的要用reCAPTCHA功能,需要去申请真实的密钥,但练习环境下没必要。
5.5 端口冲突的快速定位方法
Apache启动失败、MySQL启动失败、Docker容器启动失败,很大概率都是端口冲突。快速定位的方法是:Windows上用netstat -ano | findstr :端口号,macOS/Linux上用lsof -i :端口号。找到占用端口的进程PID后,用任务管理器或kill命令结束它,或者修改自己服务的端口。
我个人的习惯是,本地开发环境统一用8000以上的端口,避开80、443、3306这些常用端口,能减少很多冲突。DVWA用8080,phpMyAdmin用8081,MySQL用3307,这样即使电脑上装了其他Web服务也不会打架。
5.6 浏览器缓存导致的“改了没生效”
这个问题很隐蔽。你修改了DVWA的配置文件或者切换了安全等级,刷新页面却发现没变化。大概率是浏览器缓存了旧的PHP输出或者CSS/JS文件。解决办法是按Ctrl+F5(Windows)或Cmd+Shift+R(macOS)强制刷新,或者在开发者工具里勾选“Disable cache”。我养成的习惯是,每次修改配置后都开一个无痕窗口来验证,避免缓存干扰。
6. 搭好之后怎么用才不浪费这套环境
6.1 建议的学习顺序
DVWA的模块很多,一股脑全做一遍容易消化不良。我建议的顺序是:先做Brute Force(暴力破解),理解认证机制和速率限制的重要性;然后做Command Injection(命令注入),感受用户输入直接拼接进系统命令的后果;接着做SQL Injection(SQL注入),这是Web安全的核心漏洞类型,值得花最多时间;再往后是XSS(跨站脚本)、File Inclusion(文件包含)、File Upload(文件上传)、CSRF(跨站请求伪造)。每个模块都按照Low→Medium→High→Impossible的顺序走一遍。
6.2 用Burp Suite配合DVWA做抓包分析
光在浏览器里操作,很多细节看不到。我强烈建议把Burp Suite的代理挂上,拦截DVWA的请求和响应。这样你能看到提交的原始数据包长什么样,参数是怎么传的,服务器返回了什么。对于理解SQL注入的payload构造、XSS的弹窗触发条件,抓包分析比单纯看页面结果直观得多。
配置方法很简单:Burp Suite默认监听8080端口,浏览器代理设置为127.0.0.1:8080,然后访问DVWA即可。如果DVWA本身也跑在8080端口,需要先把Burp的监听端口改成别的,比如8090,避免冲突。
6.3 修改源码来加深理解
DVWA的源码是开放的,你可以直接修改它来验证自己的理解。比如在SQL Injection模块的Low级别,你可以打开对应的PHP文件,看到它是如何把用户输入直接拼接到SQL语句里的。然后你可以尝试自己写一个过滤函数,看看能不能挡住常见的注入payload。这种“攻击-防御-再攻击”的循环,是提升最快的方式。
我个人的经验是,每学完一个漏洞类型,就去Impossible级别的源码里看官方是怎么防御的,然后把防御代码抄到Low级别的文件里,再尝试用之前的payload去攻击,看是否被挡住。如果被挡住了,思考有没有绕过方法;如果没挡住,说明防御代码有漏洞,这本身就是一次很好的学习。
7. 关于环境重置与数据备份的实用技巧
练手过程中难免会把数据库搞乱,比如误删了表、改错了数据。这时候如果重新搭建一遍太浪费时间。DVWA本身提供了一个“Create / Reset Database”按钮,点击后会把数据库重置到初始状态。但要注意,这个操作会清空你之前的所有修改,包括上传的文件。如果你有想保留的数据,提前用phpMyAdmin导出SQL文件备份。
Docker方案下重置更简单,直接docker compose down -v删掉容器和数据卷,再docker compose up -d重新拉起,一分钟就能得到一个全新的环境。这也是我后来更倾向于Docker方案的原因之一。
另外,如果你在DVWA里上传了webshell或者测试文件,记得定期清理hackable/uploads目录,不然文件越积越多,磁盘空间会被慢慢吃掉。我一般会在每次练习结束后顺手清空这个目录,保持环境干净。
最后再分享一个小技巧:如果你同时想练多个靶场,可以用Docker Compose把DVWA和其他靶场编排在一起,通过不同的端口访问。这样一套Docker环境就能覆盖多种练习需求,比装多个XAMPP要清爽得多。