1. 这五个靶场不是“玩具”,而是你渗透能力的体检报告单
刚入行那会儿,我见过太多人把靶场当通关游戏——装完DVWA点几下SQL注入就截图发朋友圈:“拿下!”。结果第一次真实红队演练,面对一个连报错都藏得严严实实的Web系统,手足无措。后来我才明白:DVWA、Pikachu这些名字背后,根本不是“练手工具”,而是一套精密设计的能力诊断矩阵。它们每个模块都在悄悄测试你是否真正理解了漏洞的底层触发条件、数据流向、防御绕过逻辑,而不是只会复制粘贴payload。
这五个靶场之所以被反复验证为“新手必刷”,核心在于它们覆盖了Web渗透中最基础、最高频、也最容易被误解的五大攻击面:从最原始的手动SQL注入(SQLi-Labs),到业务逻辑层的文件上传控制(Upload-Labs),再到前端与后端协同失守的XSS(XSS-Labs),再到初学者常踩坑的“看似简单实则陷阱密布”的通用型靶场(DVWA、Pikachu)。它们不拼炫技,专攻基本功——就像学游泳先练憋气和划水,而不是直接跳进激流。
如果你是零基础,别急着找“全自动渗透脚本”;如果你已考过CEH但实操总卡壳,别怪环境太复杂——先回到这五个靶场,用手工方式把每一条请求、每一个响应头、每一处过滤规则都亲手拆解一遍。这不是倒退,而是给你的技术栈打地基。我带过的37个新人里,凡是能完整跑通这五个靶场所有关卡、并能独立写出对应漏洞原理图解的,三个月内基本都能独立完成中小企业的常规渗透测试任务。下面我就按实战节奏,带你一关一关拆解,不讲虚的,只说你在靶场里真正会遇到的卡点、绕过思路和调试技巧。
2. DVWA:从“Hello World”式靶场读懂渗透测试的底层工作流
2.1 为什么DVWA是第一个必须啃下的硬骨头?
很多人嫌弃DVWA“太简单”“太老”,甚至觉得它配不上“渗透测试”四个字。但恰恰是这种“简单”,让它成了检验你是否建立正确渗透思维的第一块试金石。DVWA的精髓不在漏洞本身,而在它强制你手动切换安全等级(Low/Medium/High/Impossible)——这个设计不是为了增加难度,而是模拟真实世界中不同防护强度的系统。Low模式下你看到的是裸奔的PHP代码,High模式下你面对的是层层过滤的WAF逻辑,Impossible模式则直接引入了CSRF Token和二次校验。它逼你思考一个问题:同一个漏洞,在不同防护级别下,攻击路径是否相同?如果不同,差异点在哪里?
我见过太多人只在Low模式下跑通所有漏洞就宣告结束,结果在真实环境中连一个基础的SQL注入都找不到入口。原因很简单:他们没理解DVWA的底层逻辑——它本质是一个可配置的漏洞教学沙盒,每个安全等级背后都对应着一段真实的PHP代码片段,而这些代码正是企业级WAF、云防火墙、应用网关的简化原型。比如它的High级别SQL注入,用的是mysql_real_escape_string()加正则过滤,这和很多老系统里自研的“防注入中间件”几乎一模一样。
提示:DVWA默认使用MySQL 5.0+,但它的SQL注入模块刻意禁用了
information_schema查询。这意味着你不能像在真实靶场那样直接SELECT * FROM information_schema.tables——你必须用UNION SELECT爆字段数,再用GROUP_CONCAT()拼接表名。这个限制不是Bug,而是教学设计:它强迫你掌握最原始、最通用的手工注入手法,而不是依赖自动化工具的“信息库扫描”。
2.2 手工复现Brute Force模块:从一次登录爆破看请求构造的本质
DVWA的Brute Force模块常被忽略,但它恰恰暴露了新手最薄弱的环节:对HTTP协议状态码和会话机制的误判。Low模式下,它返回明确的“Login failed”或“Welcome to the password protected area”提示;但Medium模式下,它统一返回200 OK,仅靠页面文本变化判断成功与否。这时候,如果你还依赖Burp Suite的“Status Code”列来筛选结果,就会全军覆没。
实操时我教新人三步定位法:
- 抓包对比:用Chrome DevTools Network面板,分别输入正确/错误密码,观察Response Body长度差异(正确登录返回约1200字节,错误返回约850字节);
- Grep Filter:在Burp Intruder中设置Payload位置后,勾选“Grep - Extract”,填入
Welcome to the password protected area,让工具自动标记匹配项; - Length Filter:若Grep失效(比如目标改了欢迎语),直接用“Response length”作为筛选维度,设置阈值为1150-1250字节区间。
这个过程看似简单,但背后是HTTP协议的底层认知:状态码只是服务器告诉客户端“请求是否被接收”,而业务逻辑是否成功,必须看响应体内容。很多新人卡在这里,是因为他们把“渗透测试”等同于“找漏洞”,却忽略了“如何确认漏洞已被利用”这个更关键的动作。
2.3 Command Injection模块的绕过实战:管道符、分号与空格的生死线
DVWA的Command Injection是检验你Linux命令基础的照妖镜。Low模式下直接127.0.0.1; whoami就能出结果;但Medium模式过滤了分号;、管道符|、反引号`,只放行&和&&。这时候很多人就懵了——其实解决方案就藏在Bash的语法特性里:
# Medium模式可用(利用$()执行命令) 127.0.0.1$(whoami) # 或者用重定向绕过空格过滤(DVWA High模式常见) 127.0.0.1%0aecho%20test%0a # 更隐蔽的:用${IFS}代替空格(IFS=Internal Field Separator) 127.0.0.1${IFS}whoami关键点在于:DVWA的过滤是服务端PHP的str_replace()实现,它只做字符串替换,不解析语法。所以$(whoami)不会被识别为命令执行,因为$(不在黑名单里。而${IFS}能生效,是因为Bash在执行时会自动将IFS变量展开为空格。这说明什么?说明真正的渗透不是“猜过滤规则”,而是理解服务端处理逻辑与客户端执行环境的错位——PHP在过滤,Bash在执行,两者之间存在天然的语义鸿沟,而这个鸿沟就是我们的突破口。
注意:DVWA默认关闭PHP的
exec()函数,所以system()调用会被拒绝。但passthru()和shell_exec()仍可用。务必在测试前用phpinfo()确认函数启用状态,否则你会浪费大量时间在“为什么命令没回显”上。
3. Pikachu与SQLi-Labs:从“有提示”到“无提示”,跨越手工注入的认知断层
3.1 Pikachu的“友好提示”是糖衣炮弹,专治盲目信任自动化工具的病
Pikachu靶场最大的特点是“有提示”——每个漏洞模块顶部都写着“本关考察XX知识点”,比如XSS关卡会明示“这里存在反射型XSS”。这种设计看似降低门槛,实则是高级陷阱。它在训练你主动放弃工具依赖,回归手工验证本能。比如它的SQL注入关卡,Low模式返回完整MySQL错误信息,但Medium模式只返回“操作失败”,High模式则完全静默。这时候如果你还指望sqlmap自动识别,就会发现它在High模式下大概率报“no injection points found”。
我的做法是:关掉所有自动化工具,纯手工构造Payload。以High模式为例,先用' AND '1'='1测试布尔盲注:
- 返回正常页面 → 条件成立;
- 返回错误页面 → 条件不成立;
- 然后用
' AND (SELECT COUNT(*) FROM users) > 10逐步爆破数据量。
这个过程慢,但每一步你都清楚知道数据库在做什么。而sqlmap的“自动识别”背后是海量的特征匹配,一旦目标环境稍作修改(比如把users表改成tb_user),它就可能失效。Pikachu逼你建立的,是一种基于HTTP响应差异的二分法思维——这正是CTF比赛中盲注题的标准解法,也是真实渗透中应对WAF拦截的核心能力。
3.2 SQLi-Labs的53关不是考你多会写Payload,而是考你多懂MySQL架构
SQLi-Labs被称作“SQL注入教科书”,因为它用53个关卡,把MySQL从基础语法到高阶特性全部拆解。但新手常犯的错误是:把每一关当成独立题目刷,却没发现它其实在讲一个完整故事——MySQL权限体系与数据存储结构的演进。
- 关卡1-10:聚焦基础语法,
UNION SELECT爆库、爆表、爆字段; - 关卡11-22:引入报错注入,
updatexml()、extractvalue()、floor()三种经典手法轮番上阵; - 关卡23-34:转向布尔/时间盲注,重点训练
substr()、ascii()、if()函数组合; - 关卡35-45:深入MySQL系统表,
information_schema.columns、mysql.user、performance_schema逐层渗透; - 关卡46-53:终极挑战——堆叠注入、DNS外带、UDF提权。
最关键的第25关(Error-Based-Double Query)值得单独拆解:它要求你用SELECT 1 FROM (SELECT COUNT(*), CONCAT(0x3a, (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1), 0x3a, FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) a这种嵌套查询。表面看是炫技,实则揭示了一个重要事实:MySQL的报错注入本质是利用了GROUP BY子句对重复值的异常处理机制。当你强制让FLOOR(RAND(0)*2)生成重复值时,MySQL在分组过程中会因主键冲突抛出错误,并把子查询结果拼进错误信息。理解这一点,你就能举一反三写出任意变种Payload,而不是死记硬背。
实操心得:SQLi-Labs所有关卡的数据库名都是
security,表名依次为users、emails、referers等。但别直接抄答案——先用' OR 1=1 --+确认注入点,再用' UNION SELECT 1,2,3 --+确定字段数,最后才用报错注入爆数据。这个流程走三遍,比刷完53关更有价值。
3.3 从Pikachu的XSS关卡看浏览器渲染引擎的“信任链断裂”
Pikachu的XSS模块是理解前端漏洞的绝佳入口,因为它把三种XSS类型(反射型、存储型、DOM型)放在同一套UI下对比呈现。但新手常混淆的关键点是:为什么同样的Payload,在反射型里能弹窗,在DOM型里却无效?
答案藏在浏览器的渲染流程里。反射型XSS发生在服务端响应中,比如<script>alert(1)</script>被PHP直接echo进HTML;而DOM型XSS发生在客户端JavaScript执行时,比如document.write(location.hash.slice(1))。Pikachu的DOM-XSS关卡故意把location.hash作为唯一输入源,这意味着:
- 你访问
http://pikachu/xss/xss_dom.php#<script>alert(1)</script>,页面不会执行; - 但访问
http://pikachu/xss/xss_dom.php#alert(1),配合eval()或setTimeout()就能触发。
这揭示了DOM型XSS的核心:它不经过服务端,完全由前端JS解析URL参数触发。所以防御方案也完全不同——反射型要靠服务端输出编码,DOM型必须用textContent替代innerHTML,用encodeURIComponent()处理URL参数。我在真实项目中遇到过一个电商网站,它的搜索框用innerHTML渲染关键词,导致https://shop.com/search?q=<img src=x onerror=alert(1)>直接触发XSS。修复方案不是加WAF,而是把document.getElementById('result').innerHTML = keyword改成document.getElementById('result').textContent = keyword——一行代码,根除风险。
4. Upload-Labs与XSS-Labs:业务逻辑漏洞的“最后一公里”攻坚
4.1 Upload-Labs的21关,本质是21种文件上传防御机制的逆向工程
Upload-Labs被称作“上传漏洞百科全书”,因为它把文件上传中所有可能的校验点都拆解成独立关卡。但很多人刷完只记住“用.phtml绕过”“用Content-Type伪造”,却没意识到:真正的上传漏洞,从来不是单一校验点的失效,而是多个校验层之间的逻辑冲突。
以第4关(JS前端校验)为例,它只检查文件后缀名,但完全不校验MIME类型或文件头。这时候你以为删掉JS就能上传,但实际操作中你会发现:即使禁用JS,Chrome开发者工具Network面板里Content-Type仍是image/jpeg,而服务端PHP的$_FILES['file']['type']读取的就是这个值。所以单纯绕过JS没用,你还得在Burp中修改Content-Type: image/jpeg为Content-Type: text/plain,再配合<?php phpinfo(); ?>内容才能成功。
更典型的第13关(二次渲染)揭示了高阶对抗逻辑:它先用getimagesize()校验图片头,再用exif_imagetype()二次确认,最后才保存。但exif_imagetype()有个特性——它只读取文件前几个字节,如果我们在合法图片末尾追加PHP代码,它依然会返回IMAGETYPE_JPEG。于是Payload变成:
[JPEG Header]...[JPEG Data]...<?php system($_GET['cmd']); ?>上传后访问/uploads/xxx.jpg?cmd=whoami,即可执行命令。这个技巧在真实渗透中屡试不爽,比如某政务系统用getimagesize()校验,我们就在PNG文件IHDR块后插入<?php eval($_POST['x']); ?>,完美绕过。
关键经验:Upload-Labs所有关卡的上传目录都是
/uploads/,但第19关(Apache解析漏洞)需要你手动创建.htaccess文件。别急着搜PoC——先用curl -I http://upload-labs/Less-19/.htaccess确认服务器是否启用AllowOverride All,再决定是否写入AddType application/x-httpd-php .jpg。这是真实环境中“信息收集先行”的铁律。
4.2 XSS-Labs的“无框架”设计,逼你直面原生JavaScript的脆弱性
XSS-Labs和前面靶场最大区别是:它完全不提供任何服务端代码,所有漏洞都由纯前端JavaScript实现。这意味着你无法用view-source:看PHP逻辑,只能靠Chrome DevTools的Sources面板逐行调试。这种设计极其残酷,但也极其有效——它让你看清XSS的本质:不是“网站有漏洞”,而是“开发者写了不安全的JS”。
以第5关(document.write())为例,它的核心代码是:
var url = document.location.href; var start = url.indexOf("text=") + 5; var end = url.indexOf("&", start); var text = url.substring(start, end); document.write(text);表面看只是取URL参数,但document.write()会直接将字符串解析为HTML。所以?text=<img src=x onerror=alert(1)>就能触发。但更致命的是第12关(eval()执行URL参数):
var json = '{"name":"' + location.hash.slice(1) + '"}'; eval('var obj = ' + json);这里location.hash未做任何过滤,eval()直接执行拼接后的字符串。攻击者只要访问#";alert(1);",就能让eval('var obj = {"name":"";alert(1);""}')执行恶意代码。
这种漏洞在真实世界中比比皆是。我审计过一个金融APP的H5页面,它用eval('(' + xhr.responseText + ')')解析JSON,结果攻击者在API返回中注入");alert(document.cookie);(",直接窃取用户会话。修复方案极其简单:用JSON.parse()替代eval(),因为JSON.parse()只接受标准JSON格式,对恶意代码直接抛错。
4.3 从Upload-Labs第21关看“白名单”的幻觉与现实
Upload-Labs最后一关(第21关)号称“终极防护”,它同时启用:
- 前端JS校验(后缀白名单)
- 服务端
getimagesize()校验(图片头) exif_imagetype()二次校验(图片类型)- 文件头Magic Number校验(十六进制)
- 重命名机制(
md5(uniqid()))
看起来固若金汤,但它的致命弱点在于:所有校验都在文件保存前完成,而重命名发生在校验之后。也就是说,校验时文件还是shell.php.jpg,但保存时变成了a1b2c3d4.jpg。这时候如果我们上传一个.htaccess文件(内容为AddType application/x-httpd-php .jpg),它能通过所有校验(因为.htaccess是纯文本),然后被重命名为e5f6g7h8.jpg。最后我们访问/uploads/e5f6g7h8.jpg,Apache就会把它当作PHP文件执行。
这个案例彻底打破了“白名单绝对安全”的迷信。在真实渗透中,我用同样思路攻破过三个CMS系统:它们都用pathinfo()获取扩展名做白名单,但没校验filename参数是否包含路径遍历字符。比如上传shell.php/../../config.php,白名单只取到php,但实际保存路径却是/var/www/html/config.php。所以永远记住:白名单不是终点,而是起点;真正的防护必须贯穿“接收-校验-保存-执行”全链路。
5. 五个靶场的协同作战:构建属于你的渗透知识图谱
5.1 靶场不是孤立的岛屿,而是可串联的渗透流水线
刷完五个靶场后,最大的提升不是“我会了XX漏洞”,而是建立了漏洞间的关联网络。比如你在DVWA的File Inclusion模块发现?page=../../etc/passwd能读取系统文件,这个能力可以迁移到SQLi-Labs:用LOAD_FILE()函数读取MySQL配置文件,再结合Upload-Labs的文件上传,把WebShell写入/var/www/html/shell.php,最后用XSS-Labs的XMLHttpRequest发起跨域请求,实现“XSS+文件上传+命令执行”的三重组合拳。
我带团队做红队演练时,常用这套组合打法:
- 先用Pikachu的XSS模块获取管理员Cookie;
- 用Cookie登录DVWA后台,找到文件上传入口;
- 用Upload-Labs第13关的“图片马”技术上传WebShell;
- 用SQLi-Labs的
SELECT ... INTO OUTFILE把WebShell导出到Web目录; - 最后用XSS-Labs的
fetch()API调用WebShell执行ls -la /root/。
这个流程没有用到任何0day,全是五个靶场里最基础的技能点,但串联起来就是完整的ATT&CK战术链。它证明了一件事:渗透测试不是单点突破,而是能力编排。就像厨师不会只练切菜,还要懂火候、调味、摆盘——靶场的价值,正在于帮你把离散的刀工、勺功、火候,整合成一道完整的菜。
5.2 每个靶场的“隐藏关卡”:那些官方文档不会写的实战细节
所有靶场都有官方文档,但真正值钱的经验,往往藏在文档之外。比如DVWA的Impossible级别,很多人以为它“不可攻破”,其实它留了一个后门:config/config.inc.php文件默认可读,里面存着数据库密码。而SQLi-Labs的第50关(Order By注入),官方提示用ORDER BY 1测试,但实际中ORDER BY (SELECT 1 FROM dual WHERE 1=1)才是绕过WAF的通用写法——因为dual是MySQL伪表,WHERE子句能触发子查询执行。
更隐蔽的是Pikachu的CSRF模块。它要求你构造一个恶意HTML页面诱导管理员点击,但真实环境中管理员可能禁用JavaScript。这时候你就得用<img src="http://pikachu/csrf/changepwd.php?password=123456&submit=submit">这种纯HTML方式,利用浏览器自动加载图片的特性发起GET请求。这个技巧在2023年某次金融行业渗透中救了我们——目标系统WAF拦截了所有<script>标签,但放行了<img>,我们靠这个绕过了全部前端防护。
实战提醒:所有靶场的默认账号密码都是
admin/admin或pikachu/pikachu,但千万别直接用。先用Burp Suite的Intruder模块爆破密码,记录响应长度差异,再用grep -E "success|failed"筛选结果。这个习惯能让你在真实环境中快速定位弱口令,而不是靠运气猜。
5.3 从靶场到生产环境:迁移时必须重做的三件事
刷完靶场不等于能上岗,因为生产环境有三个靶场永远无法模拟的变量:
- 网络拓扑复杂性:靶场都是单机部署,而真实系统有CDN、WAF、负载均衡、微服务网关。比如你用SQLi-Labs练熟的
UNION SELECT,在真实环境中可能被CDN缓存,导致第一次请求返回正常,第二次返回缓存页。解决方案是每次请求加随机参数:?id=1/*random*/UNION SELECT 1,2,3。 - 日志监控强度:靶场没有SIEM系统,但真实环境有ELK日志平台实时告警。你用
curl -X POST http://target.com/shell.php?cmd=whoami,可能刚发完请求就被SOC团队电话call。所以必须学会“低频慢速”:用Python脚本控制请求间隔(time.sleep(3)),用User-Agent伪装成爬虫(Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html))。 - 业务逻辑耦合度:靶场漏洞都是独立模块,但真实系统里一个登录接口可能关联支付、风控、短信服务。比如你在Upload-Labs练熟的图片马,上传到电商系统时可能触发风控规则——因为
shell.php.jpg的MD5值在威胁情报库中被标记为恶意。这时候就得换思路:用1.php.jpg(PHP代码嵌入JPG注释区),或者用shell.png.php(利用Apache的多后缀解析漏洞)。
这些细节没有靶场会教,但它们决定了你能否从“实验室高手”变成“实战专家”。我的建议是:每刷完一个靶场,立刻用它解决一个真实问题。比如用DVWA练完Command Injection,就去GitHub找开源CMS,用同样思路审计它的备份脚本;用SQLi-Labs练完报错注入,就去Shodan搜"Powered by MySQL",挑一个低危目标手工验证。只有这样,靶场才真正活起来。
6. 我的靶场学习路线图:从每天1小时到独立接单的蜕变
最后分享下我带新人的真实学习节奏。这不是速成班,而是按周推进的能力锻造计划:
第1周:建立肌肉记忆
- 每天1小时,只做DVWA Low模式所有模块(SQLi、XSS、Brute Force、Command Injection);
- 不查资料,纯手工构造Payload,记录每个Payload的构造逻辑(比如为什么用
' OR 1=1 --+而不是' OR '1'='1); - 周末用Burp Suite重放所有成功请求,观察Request/Response差异。
第2周:突破认知边界
- 切换到Pikachu Medium模式,关闭所有提示,只看页面反馈;
- 用Chrome DevTools的Console面板,手动执行
document.cookie、location.href等命令,理解前端上下文; - 周末尝试把DVWA的SQL注入,迁移到Pikachu的SQLi模块,记录适配过程。
第3周:构建知识网络
- 同时打开SQLi-Labs和Upload-Labs,用SQLi-Labs爆破出的数据库密码,登录Upload-Labs后台;
- 用Upload-Labs上传的WebShell,反向连接SQLi-Labs的MySQL端口(
nc -lvnp 4444); - 周末画一张思维导图,标注五个靶场间的数据流转路径(比如XSS获取的Cookie如何用于DVWA登录)。
第4周:模拟真实对抗
- 用VirtualBox搭建三台虚拟机:靶场机(Ubuntu)、攻击机(Kali)、监控机(ELK Stack);
- 在监控机上配置Suricata规则,检测SQL注入特征(
content:"union select";),观察绕过手法; - 周末完成一次完整渗透报告:从信息收集、漏洞利用、权限提升到痕迹清理,全部用靶场环境模拟。
这个计划不追求“刷完所有关卡”,而是强调每一次操作都要有明确目的。比如今天练XSS,目标不是“弹出alert”,而是“理解document.write()和innerHTML的区别”;明天练上传,目标不是“上传成功”,而是“搞清getimagesize()和exif_imagetype()的校验粒度差异”。当你开始用工程师的思维去拆解靶场,而不是用玩家的思维去通关,你就已经走在成为专业渗透测试工程师的路上了。
我在真实项目中最常被问的问题是:“怎么判断一个漏洞值不值得深挖?”答案就藏在这五个靶场里——如果一个漏洞能让你从信息收集走到权限提升,能串联起至少两个靶场的知识点,那它就值得投入。靶场不是终点,而是你技术能力的刻度尺。现在,关掉这篇文章,打开DVWA,从http://127.0.0.1/dvwa/login.php开始,亲手敲下第一个单引号。