三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Kali Linux下DVWA靶场一键自动化部署脚本设计与实现

Kali Linux下DVWA靶场一键自动化部署脚本设计与实现

1. 项目概述:告别繁琐,拥抱自动化

如果你和我一样,常年混迹在网络安全的学习和实践圈子里,那么Kali Linux和DVWA这对“黄金搭档”你一定不陌生。Kali作为渗透测试的瑞士军刀,DVWA作为最经典的Web漏洞靶场,几乎是每个安全爱好者入门和练手的必经之路。但每次在新环境、新机器上部署DVWA,你是不是也经历过同样的痛苦?从安装LAMP环境(Apache、MySQL、PHP)开始,到配置数据库、修改PHP设置、调整文件权限,再到处理各种版本兼容性问题,一套流程下来,少说也得折腾个把小时,期间还可能遇到各种报错,让人心力交瘁。更别提对于刚接触Linux的新手来说,每一步都可能是一个“坑”。

这个项目的核心,就是为了彻底解决这个痛点。它不再是一个简单的教程,而是一个高度自动化的一键部署脚本。你只需要在Kali Linux终端里执行一条命令,泡杯咖啡的功夫,一个功能完整、配置妥当的DVWA靶场就会在你的本地环境里跑起来。这不仅仅是节省时间,更是将部署过程标准化、可靠化,让你能把宝贵的精力集中在真正的漏洞学习和渗透测试技术上,而不是浪费在重复的环境搭建上。无论你是正在学习Web安全的学生,还是需要频繁搭建测试环境的从业者,这个脚本都能成为你工具箱里一件提升效率的利器。

2. 脚本核心设计与思路拆解

2.1 为什么选择Shell脚本?

面对自动化部署的需求,我们有很多选择,比如Python、Ansible,甚至用Docker来封装。但最终选择用Shell(Bash)脚本来实现,是经过多方面权衡的。

首先,环境原生支持。Kali Linux默认使用Bash作为命令行解释器,这意味着脚本无需安装任何额外的解释器或依赖,开箱即用,最大限度地降低了使用门槛。其次,与系统管理任务高度契合。部署LAMP环境和Web应用,本质上是一系列的系统命令执行(如apt-get安装软件包)、文件操作(如复制、修改配置文件)和服务管理(如重启Apache)。Shell脚本在处理这些任务时语法直接、效率极高。再者,轻量且快速。一个精心编写的Shell脚本通常只有几十到几百行,执行起来几乎没有额外的性能开销,从下载到运行完成,整个过程非常迅速。

当然,Shell脚本也有其局限性,比如错误处理不如高级语言完善,复杂的逻辑判断写起来比较繁琐。但针对“在Kali上部署DVWA”这个单一、明确的任务,它的优点远大于缺点。我们的设计思路是:将手动部署的每一步分解为原子操作,然后用脚本命令将其串联,并加入充分的错误检测和用户交互,确保过程的健壮性。

2.2 整体工作流程设计

脚本的设计遵循一个清晰的线性流程,但同时为关键步骤准备了“逃生舱口”和回滚机制。下图描绘了脚本的核心执行脉络:

  1. 环境预检与初始化:这是脚本安全运行的基石。它会首先检查当前用户是否具有sudo权限(因为安装软件和修改系统配置需要),检查系统是否为Kali Linux(避免在错误系统上运行),并确保有可用的网络连接。同时,它会创建一个临时工作目录,并设置脚本退出时的清理任务,确保即使中途失败,也不会留下垃圾文件。

  2. 依赖环境自动化部署:这是最核心、最易出错的部分。脚本将按顺序执行:

    • 更新软件源:执行sudo apt update,确保能获取到最新的软件包列表。
    • 安装LAMP栈:通过apt install命令一次性安装Apache2、MySQL Server(或MariaDB)、PHP以及PHP连接MySQL所需的模块(如php-mysql)。这里的关键在于指定正确的软件包版本,以兼容DVWA的需求。
    • 配置MySQL数据库:自动运行mysql_secure_installation的简化版,为MySQL的root用户设置密码(可由用户输入或使用脚本默认的安全密码),并移除测试数据库和匿名用户。
    • 配置PHP环境:自动修改php.ini配置文件,开启DVWA所需的allow_url_include等选项,并调整一些安全设置以匹配靶场环境。
  3. DVWA应用部署与配置

    • 下载与解压:从DVWA的官方GitHub仓库下载最新稳定版的源码压缩包,或者使用内置的备份源,确保下载成功率。然后将其解压到Apache的Web根目录(通常是/var/www/html/)下。
    • 文件权限设置:将DVWA目录的所有者改为Apache运行的用户(如www-data),并赋予适当的读写权限,特别是对hackable/uploads/config/等目录。
    • 数据库初始化:使用MySQL命令行,自动创建名为dvwa的数据库,并导入DVWA自带的SQL文件来创建数据表。
    • 配置文件生成:复制DVWA的配置文件模板(config/config.inc.php.dist)为正式配置文件(config/config.inc.php),并自动将上一步设置的数据库密码、数据库名等信息写入该文件。
  4. 服务启动与最终验证

    • 重启Apache2和MySQL服务,使所有配置生效。
    • 执行最终检查,可能包括检查服务状态、检查配置文件是否存在、甚至用curl命令尝试访问本地DVWA登录页,并给出明确的访问URL(通常是http://127.0.0.1/dvwa/)和默认登录凭证(admin/password)。

整个流程中,脚本会在每个关键步骤后检查命令的返回值($?),一旦失败,会打印明确的错误信息并尝试安全退出,而不是继续执行导致更混乱的状态。

3. 脚本关键代码解析与实操要点

3.1 安全与兼容性检查模块

脚本的开头绝不是直接开干,而是做好充分的“体检”。这是区分一个鲁棒性强的脚本和“玩具脚本”的关键。

#!/bin/bash # 颜色定义,用于输出高亮 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color echo -e "${GREEN}[*] 开始DVWA一键部署脚本${NC}" # 1. 检查sudo权限 if [[ $EUID -ne 0 ]]; then echo -e "${RED}[!] 错误:此脚本需要root权限。请使用 'sudo' 执行。${NC}" exit 1 fi # 2. 检查是否为Kali Linux (通过检查 /etc/os-release) if ! grep -qi "kali" /etc/os-release; then echo -e "${YELLOW}[!] 警告:此脚本专为Kali Linux设计。在其他系统上运行可能导致意外行为。${NC}" read -p "是否继续?(y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi # 3. 检查网络连通性 echo -e "[*] 检查网络连接..." if ! ping -c 1 -W 2 8.8.8.8 &> /dev/null; then echo -e "${YELLOW}[!] 警告:无法连接到互联网。部分安装步骤可能需要网络。${NC}" fi

要点解析:

  • #!/bin/bash:指定解释器,确保脚本在Bash环境下运行。
  • 颜色变量:使用ANSI转义码让输出信息更易读,成功用绿色,错误用红色,警告用黄色。
  • $EUID检查EUID代表有效用户ID,0即为root。这是检查sudo权限的可靠方法。
  • /etc/os-release检查:这是检查Linux发行版的标准方法,比检查/etc/issue更可靠。
  • 网络检查:尝试ping一个可靠的外部IP(如Google的DNS 8.8.8.8)。这里用了-c 1(只发1个包)和-W 2(等待2秒),是为了快速失败,不阻塞太长时间。
  • 交互式确认:当在不兼容的系统上运行时,给出警告并让用户确认,避免误操作。

3.2 智能依赖安装与配置

安装软件包时,最怕遇到已经安装过但版本不对,或者源不可用的情况。

# 更新软件包列表 echo -e "[*] 更新软件包列表..." if ! apt-get update; then echo -e "${RED}[!] 更新软件包列表失败,请检查网络或软件源配置。${NC}" exit 1 fi # 定义需要安装的软件包 PACKAGES="apache2 mariadb-server php php-mysql php-gd php-curl php-pear php-dev libapache2-mod-php" echo -e "[*] 安装依赖软件包:$PACKAGES ..." # 使用 -y 参数避免交互式确认,使用 -qq 减少输出噪音(但保留错误) if ! apt-get install -y -qq $PACKAGES; then echo -e "${RED}[!] 软件包安装失败。${NC}" # 这里可以尝试更具体的错误处理,比如提示哪个包失败了 exit 1 fi

要点解析:

  • 软件包选择:我们选择了mariadb-server而非mysql-server,因为在新版Kali/Debian中,MariaDB是默认的MySQL替代品,完全兼容。php-gdphp-curl等是DVWA某些功能(如Captcha)可能需要的扩展。
  • 静默安装-qq参数让apt-get的输出非常安静,只显示错误信息。这能让脚本输出更整洁。结合-y自动确认,实现完全非交互安装。
  • 错误处理:每个apt命令后面都跟着if ! ... then检查其退出状态。如果失败,打印错误并退出,防止后续步骤在残缺的环境上运行。

3.3 数据库安全初始化

自动化设置数据库密码是难点,因为mysql_secure_installation原本是交互式的。我们需要用非交互方式完成。

# 设置MySQL root密码 DB_PASSWORD="P@ssw0rd123" # 建议的默认强密码,用户可修改 echo -e "[*] 设置MySQL root密码为: $DB_PASSWORD" mysql -u root <<-EOF ALTER USER 'root'@'localhost' IDENTIFIED BY '$DB_PASSWORD'; DELETE FROM mysql.user WHERE User=''; DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); DROP DATABASE IF EXISTS test; DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'; FLUSH PRIVILEGES; EOF if [ $? -ne 0 ]; then echo -e "${YELLOW}[!] 数据库初始化可能存在问题(例如,MySQL服务未启动或已有密码)。尝试继续...${NC}" # 这里不直接退出,因为可能只是密码已设置 fi

要点解析:

  • Here Document (<<-EOF):这是一种向命令(如mysql)传递多行输入的标准方法。<<-EOF中的-允许缩进,让脚本更美观。
  • SQL命令序列
    • ALTER USER ...:修改root用户的密码。这是MySQL 5.7+和MariaDB 10.4+推荐的方式。
    • 后续的DELETEDROP命令移除了匿名用户和测试数据库,这是基本的安全加固。
    • FLUSH PRIVILEGES:使权限更改立即生效。
  • 错误处理策略:如果MySQL已经有密码,上述命令会失败。脚本选择打印警告而非直接退出,因为这不影响后续为DVWA创建新数据库和用户。更完善的脚本可以尝试检测MySQL状态并采用不同策略。

3.4 PHP配置的精准修改

DVWA需要修改PHP配置以允许包含远程URL(用于文件包含漏洞)和关闭某些安全限制。

PHP_INI_PATH="/etc/php/$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')/apache2/php.ini" echo -e "[*] 检测到PHP配置文件:$PHP_INI_PATH" # 备份原配置文件 cp "$PHP_INI_PATH" "${PHP_INI_PATH}.backup_$(date +%Y%m%d_%H%M%S)" echo -e "[*] 已备份原配置文件。" # 使用sed进行非交互式修改 sed -i "s/^allow_url_include = .*/allow_url_include = On/" "$PHP_INI_PATH" sed -i "s/^display_errors = .*/display_errors = On/" "$PHP_INI_PATH" sed -i "s/^safe_mode = .*/safe_mode = Off/" "$PHP_INI_PATH" # 注意:PHP 5.4+已移除safe_mode # 验证修改 if grep -q "^allow_url_include = On" "$PHP_INI_PATH"; then echo -e "${GREEN}[+] PHP配置修改成功。${NC}" else echo -e "${YELLOW}[!] PHP配置修改可能未生效,请手动检查。${NC}" fi

要点解析:

  • 动态定位php.ini:不同PHP版本路径不同。php -r命令执行一行PHP代码来获取主次版本号,从而拼出正确的路径,提高了脚本的兼容性。
  • 先备份,后操作:修改系统配置文件前先备份,这是必须遵守的黄金法则。备份文件名包含时间戳,便于追溯。
  • 使用sed -i-i参数表示直接原地修改文件。^allow_url_include = .*这个正则表达式匹配以allow_url_include =开头的整行,并将其替换为allow_url_include = On。这种方式比用echo追加更精确,避免重复修改。
  • 关于safe_mode:这是一个历史遗留选项,在现代PHP中已不存在。脚本中包含它是为了兼容旧教程或旧版本DVWA,实际在新环境中会被忽略。更专业的做法是根据PHP版本动态决定修改哪些选项。

4. 完整部署流程与核心环节实现

4.1 从零到一的完整执行实录

假设你已经将脚本保存为install_dvwa.sh,并赋予了执行权限(chmod +x install_dvwa.sh)。以下是在一个全新的Kali Linux虚拟机中的完整执行过程。

首先,打开终端,切换到脚本所在目录。

# 1. 使用sudo执行脚本 sudo ./install_dvwa.sh # 2. 脚本开始运行,输出如下(示例): [*] 开始DVWA一键部署脚本 [*] 检查网络连接... [*] 更新软件包列表... 获取:1 http://kali.download/kali kali-rolling InRelease [29.6 kB] ... (更新过程输出) [*] 安装依赖软件包:apache2 mariadb-server php php-mysql... 正在读取软件包列表... 完成 正在分析软件包的依赖关系树... 完成 ... (安装过程输出,由于使用了-qq,输出很简洁) [*] 设置MySQL root密码为: P@ssw0rd123 [*] 检测到PHP配置文件:/etc/php/8.2/apache2/php.ini [*] 已备份原配置文件。 [+] PHP配置修改成功。 [*] 下载DVWA源码... --2024-05-20 10:00:00-- https://github.com/digininja/DVWA/archive/master.zip 正在解析主机 github.com (github.com)... 20.205.243.166 正在连接 github.com (github.com)|20.205.243.166|:443... 已连接。 ... (下载进度) [*] 解压并部署到Web目录... [*] 设置文件权限... [*] 创建DVWA数据库并导入结构... [*] 生成DVWA配置文件... [+] DVWA配置文件已生成。 [*] 重启Apache2与MySQL服务... [+] 服务重启成功。 [+] ======================================== [+] DVWA 部署成功! [+] 访问地址: http://127.0.0.1/dvwa/ [+] 或: http://your_kali_ip/dvwa/ [+] 默认登录凭证: [+] 用户名: admin [+] 密码: password [+] 数据库root密码已设置为: P@ssw0rd123 (请妥善保存) [+] ========================================

整个过程大约持续3-8分钟,具体取决于你的网络速度和机器性能。脚本执行完毕后,你可以立即打开浏览器,输入http://127.0.0.1/dvwa/进行访问。

4.2 DVWA初始化配置与数据库连接

第一次访问DVWA时,页面会显示一个红色警告:“Database Setup”。点击页面中的“Create / Reset Database”按钮。脚本已经完成了所有后台工作,所以这个按钮点击后应该会立刻成功,页面刷新并显示绿色的“Setup Successful”消息。

背后的原理是:脚本已经完成了以下工作,使得前端按钮点击能成功:

  1. 创建数据库和用户:在MySQL中执行了CREATE DATABASE dvwa;CREATE USER 'dvwa'@'localhost' IDENTIFIED BY 'p@ssw0rd';以及授权命令GRANT ALL ON dvwa.* TO 'dvwa'@'localhost';
  2. 生成了正确的config.inc.php:脚本将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';
  3. 点击按钮的触发动作:当你点击“Create / Reset Database”按钮时,DVWA前端会请求一个PHP脚本(setup.php)。该脚本读取上面生成的配置文件,连接到MySQL数据库,执行/dvwa/sql/目录下的SQL文件(主要是创建数据表并插入初始数据,如admin用户)。因为脚本已经提前创建好了数据库和用户,并赋予了权限,所以这个过程会一帆风顺。

如果点击按钮后仍然报错(如“Access denied for user ‘dvwa’@’localhost’”),那说明脚本的数据库配置环节可能失败了。这时你需要手动检查MySQL服务状态、数据库用户权限以及config.inc.php文件内容。

5. 常见问题与排查技巧实录

即使有自动化脚本,由于系统环境的细微差异,你仍可能遇到一些问题。下面是我在多次使用和测试中总结出的最常见问题及其解决方法。

5.1 数据库连接失败

这是最常见的问题,症状是访问DVWA首页或点击“Create / Reset Database”时,页面提示数据库连接错误。

排查步骤:

  1. 检查MySQL/MariaDB服务状态

    sudo systemctl status mariadb # 或 sudo systemctl status mysql

    确保状态是active (running)。如果不是,启动它:sudo systemctl start mariadb

  2. 验证数据库和用户是否存在

    # 使用脚本设置的root密码登录MySQL sudo mysql -u root -pP@ssw0rd123 # 在MySQL提示符下执行: SHOW DATABASES; -- 查看是否有'dvwa'数据库 USE mysql; SELECT User, Host FROM user; -- 查看是否有'dvwa'@'localhost'用户 exit;

    如果数据库或用户不存在,你需要手动创建。可以参考脚本中的SQL命令重新执行。

  3. 检查DVWA配置文件

    cat /var/www/html/dvwa/config/config.inc.php

    确认db_password等字段的值与你在MySQL中设置的一致。特别注意密码中是否有特殊字符,在配置文件和命令行中可能需要转义。

  4. 检查MySQL的认证插件问题(常见于MySQL 8.0+): 较新版本的MySQL可能使用了caching_sha2_password认证插件,而旧版PHP驱动可能不支持。可以尝试将DVWA用户的认证方式改回旧的mysql_native_password

    ALTER USER 'dvwa'@'localhost' IDENTIFIED WITH mysql_native_password BY 'p@ssw0rd'; FLUSH PRIVILEGES;

5.2 PHP配置未生效或Apache报错

症状可能是某些漏洞模块(如“File Inclusion”)无法正常工作,或者页面显示PHP代码而非执行结果。

排查步骤:

  1. 确认修改的php.ini是否正确

    # 查看Apache实际加载的php.ini路径 php --ini | grep "Loaded Configuration File" # 确认allow_url_include设置 grep "allow_url_include" /etc/php/*/apache2/php.ini

    确保你修改的是Apache使用的php.ini(通常在/etc/php/X.Y/apache2/下),而不是CLI版本的。

  2. 检查Apache是否加载了PHP模块

    sudo apache2ctl -M | grep php

    应该能看到类似php8_module (shared)的输出。如果没有,需要启用它:sudo a2enmod php8.2(版本号根据你的PHP版本调整),然后重启Apache。

  3. 检查文件权限

    ls -la /var/www/html/dvwa/

    config.inc.php文件应该对Web服务器用户(如www-data)可读。整个dvwa目录及其子文件的所有者最好是www-data,或者至少www-data用户有读取和执行权限。你可以用以下命令修复:

    sudo chown -R www-data:www-data /var/www/html/dvwa/ sudo find /var/www/html/dvwa/ -type d -exec chmod 755 {} \; sudo find /var/www/html/dvwa/ -type f -exec chmod 644 {} \; # 对上传目录等需要写权限的目录单独设置 sudo chmod 777 /var/www/html/dvwa/hackable/uploads/ sudo chmod 777 /var/www/html/dvwa/external/phpids/0.6/lib/IDS/tmp/phpids_log.txt

    注意:在生产环境中,chmod 777是极不安全的。但在本地学习用的漏洞靶场中,为了方便,可以暂时这样设置。更好的做法是保持目录所有者为www-data,并设置适当的组权限。

5.3 脚本执行中途失败

脚本可能在某个步骤(如apt install)报错退出。

排查步骤:

  1. 查看详细的错误信息:脚本通常会打印出失败的命令和错误码。仔细阅读最后几行输出。
  2. 检查网络和软件源apt update失败通常是因为网络问题或软件源配置错误。可以尝试ping 8.8.8.8测试网络,或检查/etc/apt/sources.list文件。
  3. 手动执行失败的命令:根据脚本输出的错误信息,尝试在终端手动执行失败的那条命令(例如sudo apt install apache2),这通常会给出更详细的错误提示。
  4. 检查系统资源:在虚拟机中,可能因为磁盘空间不足或内存不足导致安装失败。使用df -hfree -h命令检查。
  5. 分段执行脚本:如果脚本较长,你可以尝试将其拆分成几个部分,或者使用bash -x install_dvwa.sh来调试执行,它会打印出每一行执行的命令,方便定位问题。

5.4 安全警告与配置调整

部署成功后,DVWA首页的安全级别默认为“impossible”。为了练习漏洞,你需要将其改为“low”。

  1. 登录:使用admin/password登录。
  2. 调整安全等级:在左侧导航栏找到 “DVWA Security”,将安全级别从 “Impossible” 下拉选择为 “Low”,然后点击 “Submit”。
  3. 理解不同等级
    • Low:完全没有安全防护,用于理解漏洞原理。
    • Medium:有基础防护,但可被绕过,用于练习绕过技巧。
    • High:有较强防护,需要更高级的技巧。
    • Impossible:理论上无法攻破的正确修复方案,用于学习安全编码。

一个重要的实操心得:每次重启Kali虚拟机后,Apache和MySQL服务可能不会自动启动。你可以手动启动,或者将其设置为开机自启:

sudo systemctl enable apache2 mariadb sudo systemctl start apache2 mariadb

这个一键部署脚本的价值,远不止是节省了初次搭建的几十分钟。它更重要的意义在于提供了一种可复现、可验证的环境搭建方式。无论是为了教学、实验,还是在自己多台设备上同步环境,你都可以依赖这个脚本快速得到一个干净、一致的起点。它把繁琐的、容易出错的配置工作固化成了可靠的代码,让你能更专注在安全技术本身的学习和探索上。

← 返回列表