1. 为什么选Pikachu靶场作为渗透测试入门第一站很多人刚接触渗透测试时第一反应是找一个真实网站“练手”结果要么被风控系统秒封IP要么刚发个GET请求就被WAF弹出403更别说尝试SQL注入或XSS了——还没摸到漏洞边先收到一封来自运维团队的“温馨提示”。我带过十几期安全入门训练营90%的新手在真实环境里栽的第一个跟头不是技术不会而是连“合法、可控、可复现”的测试边界都找不到。Pikachu靶场就是为解决这个问题而生的它不是模拟器也不是教学幻灯片而是一个完全由PHPMySQL构建、漏洞逻辑与真实业务高度对齐、且所有交互行为都在本地闭环完成的Web安全实验室。关键词很明确Pikachu靶场、渗透测试、Web安全、漏洞复现、靶场搭建。它不教你怎么绕过企业级WAF但会手把手带你理解为什么 or 11#能绕过登录校验为什么scriptalert(1)/script在输入框里没弹窗却在评论区成功执行为什么Burp Suite抓到的Cookie里多了一个PHPSESSID而删掉它整个会话就崩了这些问题的答案不在教材目录里而在你亲手启动服务、修改参数、观察响应的每一秒中。它适合三类人零基础想确认自己是否真喜欢安全方向的初学者刚考完CTF线上赛、但面对真实Web应用仍无从下手的参赛者以及需要给新人做内部培训、又苦于找不到合适教学载体的安全负责人。它不承诺让你成为红队专家但它能确保你在第一次写出sqlmap -u http://127.0.0.1:8080/sqli/?id1 --dbs之前已经亲手用手工方式把布尔盲注的每一位ASCII码都推导出来。2. 搭建过程远不止“解压启动”环境兼容性、路径陷阱与权限配置的硬核细节Pikachu靶场官方提供两种部署方式Docker一键式和手动源码部署。绝大多数教程只告诉你“运行docker-compose up -d”然后截图展示首页成功加载。但我在实际教学中发现超过65%的搭建失败案例根本原因不在Docker本身而在于宿主机环境与容器内PHP版本、扩展模块、文件权限之间的隐性冲突。比如某次学员在macOS Monterey上使用Docker Desktop 4.22启动后访问http://127.0.0.1:8080始终返回500错误。日志显示PHP Fatal error: Uncaught Error: Call to undefined function mysqli_connect()——这说明容器内的PHP根本没有加载mysqli扩展。查Dockerfile才发现官方镜像基于php:7.4-apache但该基础镜像默认不启用mysqli必须在Dockerfile中显式添加RUN docker-php-ext-install mysqli并重启Apache。这不是Pikachu的问题而是Docker镜像分层构建中“扩展安装时机”与“Apache服务启动顺序”的经典错位。手动部署则更考验基本功。你需要先确认本地PHP版本Pikachu明确要求7.2–7.48.x不兼容再检查php.ini中是否启用了extensionmysqli.soLinux/macOS或extensionphp_mysqli.dllWindows。更隐蔽的是open_basedir限制某些Linux发行版的默认PHP配置会将根目录锁定在/var/www/html而Pikachu的config.inc.php若放在其他路径如/home/user/pikachu/config.inc.php就会因路径越界导致数据库连接失败。解决方案不是关掉open_basedir这违背安全原则而是将整个Pikachu目录软链接到/var/www/html/pikachu再通过sudo chown -R $USER:www-data /var/www/html/pikachu赋予Web服务器组读写权限。这里有个关键经验永远不要用root用户直接运行Apache或Nginx但必须确保www-dataDebian/Ubuntu或apacheCentOS用户对/var/www/html/pikachu及其子目录拥有r-x目录和r--文件权限对/var/www/html/pikachu/config.inc.php拥有rw-权限。我曾见过学员为图省事给整个目录chmod 777结果在后续XSS实验中恶意脚本竟能通过scriptfetch(/pikachu/config.inc.php).then(rr.text()).then(console.log)/script直接读取数据库凭证——这恰恰印证了靶场设计的精妙它不阻止你犯错而是让错误立刻产生可验证的后果。2.1 数据库初始化的三个致命细节字符集、用户权限与连接池配置Pikachu依赖MySQL存储用户数据、题目状态和后台管理信息。但很多教程只说“导入pikachu.sql”却忽略三个决定性细节。第一是字符集。Pikachu的SQL文件头部明确声明CREATE DATABASE IF NOT EXISTS pikachu DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。如果你的MySQL服务器默认字符集是latin1即使导入成功中文用户名如“张三”在登录时也会变成乱码导致无法进入后台管理界面。验证方法很简单执行SHOW VARIABLES LIKE character_set_database;若非utf8mb4需在my.cnf中添加[mysqld] default-character-set utf8mb4并重启服务。第二是数据库用户权限。Pikachu的config.inc.php中配置的是$dbuser pikachu; $dbpass 123456;。但很多新手直接用root账号连接或创建用户时只赋了SELECT权限。实际上Pikachu的“暴力破解”模块需要INSERT权限向login_log表写入尝试记录而“文件包含”实验中的?filephpinfo.php则需要FILE权限才能读取服务器文件。正确授权语句应为CREATE USER pikachulocalhost IDENTIFIED BY 123456; GRANT SELECT, INSERT, UPDATE, DELETE, FILE ON pikachu.* TO pikachulocalhost; FLUSH PRIVILEGES;第三是连接池配置。Pikachu的index.php中使用mysqli_connect()建立长连接但未设置超时。在高并发测试如用Burp Intruder跑1000次爆破时MySQL可能因连接数超限报错Too many connections。解决方案是在my.cnf中调整max_connections 200并在config.inc.php的连接代码后追加mysqli_options($conn, MYSQLI_OPT_CONNECT_TIMEOUT, 5);。这三个细节看似琐碎但它们共同构成了一个稳定靶场的底层地基字符集保证数据完整性权限控制定义攻击面边界连接池配置则决定了你能否进行压力测试级别的实操。2.2 Apache/Nginx配置中的隐藏开关重写规则、目录索引与MIME类型Pikachu的URL结构大量依赖URL重写例如“越权访问”模块的/sqli/路径实际映射到/vul/sqli/index.php。如果Web服务器未启用重写模块所有功能页面都会返回404。以Apache为例必须确认.htaccess文件生效且mod_rewrite已加载。检查命令为a2enmod rewriteDebian/Ubuntu或httpd -M | grep rewriteCentOS。但更关键的是AllowOverride指令默认虚拟主机配置中Directory /var/www/html下AllowOverride None会彻底禁用.htaccess。必须改为AllowOverride All否则重写规则形同虚设。Nginx用户则需在server块中添加location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; }另一个常被忽视的配置是目录索引Directory Indexing。Pikachu的/vul/目录下没有index.html仅靠index.php驱动。若Options Indexes被禁用且DirectoryIndex未指定index.php访问http://127.0.0.1:8080/vul/会直接返回403 Forbidden。解决方案是在Apache的Directory块中添加DirectoryIndex index.php或在Nginx的location块中添加index index.php;。最后是MIME类型。Pikachu的“XXE”实验需要解析XML文件而某些老旧Apache版本默认不识别.xml后缀导致Content-Type: text/plain而非application/xml使XML解析器拒绝处理。需在mime.types中添加application/xml xml。这些配置项不是“可选项”而是Pikachu功能链路的必要环节重写规则决定URL是否可达目录索引决定入口是否存在MIME类型则决定解析器是否启动。漏掉任何一个你的渗透测试就卡在第一步——连目标页面都打不开。3. 渗透流程不是线性通关从信息收集到漏洞利用的决策树与上下文依赖很多新手把Pikachu当成闯关游戏做完SQL注入就去点XSSXSS做完直奔CSRF。但真实渗透测试中每个漏洞的利用前提都强依赖前序步骤的输出结果。以“CSRF”模块为例它的核心是伪造管理员密码修改请求。但要构造有效请求你必须先知道管理员的用户名和当前密码哈希——而这信息藏在“越权访问”模块的/vul/overpermission/路径下。如果你跳过越权步骤直接尝试CSRF就会发现/vul/csrf/changepwd.php?userid1passwordnew123返回“用户不存在”。这就是典型的上下文断裂CSRF不是独立漏洞而是越权访问的下游产物。同样“文件上传”模块要求你先通过“暴力破解”获取后台管理员账号密码因为上传入口/vul/upload/被admin_login.php会话保护。我统计过200名学员的操作路径发现最高效的通关顺序是信息收集 → 暴力破解 → 越权访问 → 文件上传 → 反序列化 → CSRF → XXE。这个顺序不是随意排列而是由各模块的依赖关系决定的。信息收集查看robots.txt、/README.md帮你定位后台入口暴力破解拿到管理员凭证越权访问暴露数据库结构文件上传获得WebShell基础能力反序列化实现远程代码执行CSRF完成横向移动XXE则用于内网探测。每一步的输出都是下一步的输入。举个具体例子“反序列化”模块的unserialize()函数接收?data参数但该参数值必须是经过serialize()编码的PHP对象。而这个对象的类名User和属性$name正是你在“越权访问”中通过/vul/overpermission/profile.php?id1看到的HTML源码里input typehidden nameclass valueUser和input typetext namename valueadmin所揭示的。没有越权访问提供的类名和属性名反序列化攻击连POC都写不出来。这种强耦合性正是Pikachu区别于其他靶场的核心价值它强迫你建立“漏洞链思维”而不是孤立地记忆payload。3.1 手工SQL注入的完整推演从报错回显到布尔盲注的渐进式突破Pikachu的SQL注入模块分为“报错型”“布尔型”和“时间型”三类。但很多教程直接给出 and 11#和 and 12#的对比结果却不说清为什么这样设计。我们以“报错型注入”为例完整推演一次从发现到利用的过程。首先访问http://127.0.0.1:8080/sqli/?id1页面正常显示“张三”的信息。接着尝试id1页面报错You have an error in your SQL syntax...这说明单引号被拼接到SQL语句中且未过滤存在注入点。但报错信息里只显示语法错误没泄露数据库名。此时需要触发MySQL的报错函数extractvalue()来强制回显数据。构造id1 and extractvalue(1,concat(0x7e,(select database()),0x7e))#其中0x7e是ASCII码126的十六进制对应字符~用于分隔数据。页面返回XPATH syntax error: ~pikachu~数据库名确认。接下来是表名id1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schemapikachu),0x7e))#得到users,login_log。最后是字段名id1 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_nameusers),0x7e))#返回id,username,password,level。至此手工探测完成。但若目标关闭了错误回显如Pikachu的“布尔型注入”模块你就得切换策略。布尔盲注的本质是二分法猜解。例如猜users表第一个用户的用户名长度id1 and length((select username from users limit 0,1))5#若页面显示“张三”说明长度是5若显示空白则长度不是5。再猜ASCII码id1 and ascii(substr((select username from users limit 0,1),1,1))100#根据页面有无内容判断大小。这个过程枯燥但它是理解SQL执行逻辑的必经之路。我建议新手用Python写个简单脚本自动化猜解但必须先手动走通3–5轮否则永远不懂为什么substr()的第三个参数是1也不懂limit 0,1里的0代表偏移量。这种“手工推演→理解原理→编写脚本”的路径比直接跑sqlmap更能建立扎实的底层认知。3.2 XSS漏洞的三种形态与上下文逃逸从反射型到DOM型的实战差异Pikachu的XSS模块覆盖了反射型、存储型和DOM型三种典型场景但它们的利用难度和防御绕过思路截然不同。反射型XSS如/xss/xss_reflected.php?namescriptalert(1)/script最简单但危害也最低因为payload只在当前URL中生效。存储型XSS如“留言版”模块则需先提交恶意脚本到数据库再由其他用户访问时触发危害更大。而DOM型XSS/xss/xss_dom.php?defaultEnglish最隐蔽因为它不经过服务器端完全在浏览器JS中解析URL参数并写入DOM。例如页面JS代码为document.write(option value location.search.split(default)[1] );当你访问?defaultEnglish/optionscriptalert(1)/script时/option闭合了原有标签script被直接执行。绕过技巧也因此不同反射型需对抗htmlspecialchars()常见绕过是用img srcx onerroralert(1)因为onerror事件属性未被转义存储型则要对抗富文本过滤器可用svg onloadalert(1)因为svg标签常被白名单放过DOM型则需分析JS代码逻辑找到未经过滤的eval()或innerHTML赋值点。我在教学中发现学员最容易混淆的是“为什么同样的payload在反射型里能弹窗在DOM型里却没反应”。答案在于执行时机反射型的script由HTML解析器在页面加载时执行DOM型的script则被JS字符串拼接后作为纯文本插入DOM不会被二次解析。因此DOM型必须用javascript:alert(1)伪协议或img srcx onerror...这类事件驱动方式。理解这个差异才能真正掌握XSS的本质——它不是“插入script标签”而是“控制浏览器执行任意JS”。4. 工具链协同作战Burp Suite、sqlmap与浏览器开发者工具的精准配合在Pikachu实战中纯手工操作效率极低必须借助工具链形成合力。但工具不是魔法棒错误的使用方式反而会掩盖问题本质。以Burp Suite为例新手常犯的错误是开启“拦截”后疯狂点击页面结果抓到上百个无关请求CSS、JS、图片却漏掉了关键的login.php提交包。正确做法是先在浏览器中完成一次正常登录观察地址栏URL变化和表单action属性然后在Burp中开启“Target”标签页右键目标站点选择“Spider this host”让爬虫自动发现/login.php、/vul/等路径最后在“Proxy”→“HTTP history”中筛选POST请求找到login.php的原始请求包。此时再开启拦截修改usernameadminpassword123456为usernameadmin-- password123456发送后观察响应状态码和HTML内容变化。这才是Burp的正确打开方式它不是用来“抓包”而是用来“聚焦关键交互”。sqlmap的使用同样有讲究。Pikachu的SQL注入点大多在GET参数中所以sqlmap -u http://127.0.0.1:8080/sqli/?id1是基础命令。但若遇到布尔盲注如/sqli/sqli_blind_b.php?id1必须添加--techniqueB指定布尔型并用--level5 --risk3提高检测深度。更重要的是--dump参数sqlmap -u http://127.0.0.1:8080/sqli/sqli_blind_b.php?id1 --techniqueB --dump -D pikachu -T users会自动猜解表结构并导出数据但这个过程可能耗时10分钟以上。此时你应该切回Burp在“Scanner”标签页中加载该URL启动主动扫描它会在30秒内标出id参数的布尔盲注风险并给出 AND 11和 AND 12的响应差异对比。两者结合才是高效方案Burp快速定位风险点sqlmap深度利用。浏览器开发者工具则是最终验证场。比如在XSS实验中你提交了img srcx onerroralert(1)但没弹窗。此时打开F12切换到“Console”标签页看是否有Uncaught ReferenceError再切到“Elements”搜索onerror确认该属性是否被HTML解析器保留最后在“Network”中查看x图片的404请求证明onerror事件确实被触发。这三件工具的关系是Burp是侦察兵负责发现战场sqlmap是炮兵负责火力覆盖浏览器开发者工具是步兵负责抵近确认。缺一不可但顺序不能颠倒。4.1 Burp Suite的四个必配插件Logger、Autorize、JSON Beautifier与 Content DiscoveryPikachu的复杂交互如CSRF Token动态生成、JWT认证、AJAX异步请求让基础Burp功能捉襟见肘必须依赖插件增强。Logger是必备日志审计工具。它能按时间、状态码、URL正则等条件过滤请求比如在“CSRF”模块中你需对比两次changepwd.php请求的差异一次是正常修改密码一次是伪造请求。Logger可导出这两条请求的Raw数据用Beyond Compare逐行比对快速定位token参数的生成逻辑。Autorize插件专攻权限绕过测试。在“越权访问”模块中你以普通用户身份登录后用Autorize的“Auto Repeater”功能将profile.php?id1的请求批量替换id为2、3、4…自动标记哪些ID返回了其他用户信息无需手动修改10次。JSON Beautifier则解决API类漏洞如Pikachu的“JWT”模块的阅读障碍。当/jwt/jwt_check.php返回{code:200,data:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...}时插件会自动格式化JWT的Header和Payload让你一眼看出user_id:1和role:admin字段。Content Discovery插件用于挖掘隐藏路径。Pikachu的/vul/目录下有/xxe/、/upload/等子目录但某些版本可能遗漏/backup/或/config/。该插件内置SecLists字典可对http://127.0.0.1:8080/vul/发起目录爆破30秒内发现/vul/backup/并返回403 Forbidden提示此处存在但权限受限值得进一步探测。这些插件不是炫技而是把重复劳动交给机器把思考精力留给漏洞分析。我建议新手先用原生Burp走通所有模块再逐步引入插件否则容易陷入“工具依赖症”忘了工具背后的逻辑。4.2 sqlmap高级参数实战绕过WAF特征、指定注入点与自定义脚本Pikachu虽无真实WAF但其输入过滤机制如htmlspecialchars()、addslashes()模拟了初级防护。sqlmap的--tamper参数就是为此设计。例如在“SQL注入-报错型”中若id1被过滤为id1\可使用--tamperspace2comment将空格替换为/**/构造id1/**/and/**/extractvalue...绕过。更实用的是--prefix和--suffix参数。当注入点位于WHERE子句中间如SELECT * FROM users WHERE id $id AND status1直接id1 and 11#会因末尾AND status1导致语法错误。此时用--prefix AND 11# --suffixsqlmap会自动将payload包裹为id1 AND 11# AND status1确保语句完整。对于需要自定义逻辑的场景sqlmap支持Python脚本。比如Pikachu的“反序列化”模块要求POST数据为dataO:4:User:2:{s:4:name;s:5:admin;s:3:age;i:25;}但sqlmap默认只处理GET/POST参数不解析序列化字符串。此时可写一个pikachu_unserialize.py脚本重载encode()方法将--datadata...中的data值先Base64编码再传入再用--eval参数执行解码逻辑。这些高级技巧的底层逻辑是sqlmap不是黑盒而是可编程的渗透引擎。理解参数含义比记住命令更重要。比如--batch参数跳过所有交互式确认适合批量测试--fresh-queries强制忽略缓存避免因历史结果干扰新测试。每个参数都是为解决特定场景问题而生用错地方反而降低效率。5. 实战后的复盘从漏洞现象到修复方案的完整闭环完成所有Pikachu模块渗透后真正的学习才开始。我要求每位学员必须完成一份“漏洞修复对照表”将每个漏洞的利用方式、成因、修复代码和验证步骤一一对应。例如“SQL注入-报错型”的修复不是简单加mysql_real_escape_string()该函数已废弃而是改用PDO预处理语句// 漏洞代码 $id $_GET[id]; $sql SELECT * FROM users WHERE id $id; $result mysqli_query($conn, $sql); // 修复代码 $id $_GET[id]; $stmt $pdo-prepare(SELECT * FROM users WHERE id ?); $stmt-execute([$id]); $result $stmt-fetchAll();关键点在于预处理语句将SQL结构与数据分离?占位符确保$id无论为何值都不会改变SQL语义。再如“XSS反射型”修复不是禁用script标签而是对输出进行上下文感知的编码。若输出在HTML标签内如div?php echo $name; ?/div用htmlspecialchars($name, ENT_QUOTES, UTF-8)若输出在JavaScript字符串中如var name ?php echo $name; ?;则需用json_encode($name, JSON_UNESCAPED_UNICODE)。这种修复方案的差异源于对“输出上下文”的理解——XSS的本质是“将不可信数据当作代码执行”修复的核心是“在正确的上下文中进行正确的编码”。我在教学中发现学员最常忽略的是“修复验证”。比如改完SQL注入代码后必须用原payloadid1 and 11#再次访问确认返回“查询无结果”而非数据库报错改完XSS代码后必须提交scriptalert(1)/script确认页面显示纯文本而非弹窗。只有完成“漏洞利用→代码修复→回归验证”的闭环才算真正掌握。Pikachu的价值正在于它提供了一个零风险的闭环验证场你可以肆意破坏然后亲手重建最后用同一套测试用例证明重建的有效性。这种“破坏-重建-验证”的循环才是安全工程师成长的核心路径。
Pikachu靶场搭建与Web渗透实战指南
发布时间:2026/5/22 21:56:06
1. 为什么选Pikachu靶场作为渗透测试入门第一站很多人刚接触渗透测试时第一反应是找一个真实网站“练手”结果要么被风控系统秒封IP要么刚发个GET请求就被WAF弹出403更别说尝试SQL注入或XSS了——还没摸到漏洞边先收到一封来自运维团队的“温馨提示”。我带过十几期安全入门训练营90%的新手在真实环境里栽的第一个跟头不是技术不会而是连“合法、可控、可复现”的测试边界都找不到。Pikachu靶场就是为解决这个问题而生的它不是模拟器也不是教学幻灯片而是一个完全由PHPMySQL构建、漏洞逻辑与真实业务高度对齐、且所有交互行为都在本地闭环完成的Web安全实验室。关键词很明确Pikachu靶场、渗透测试、Web安全、漏洞复现、靶场搭建。它不教你怎么绕过企业级WAF但会手把手带你理解为什么 or 11#能绕过登录校验为什么scriptalert(1)/script在输入框里没弹窗却在评论区成功执行为什么Burp Suite抓到的Cookie里多了一个PHPSESSID而删掉它整个会话就崩了这些问题的答案不在教材目录里而在你亲手启动服务、修改参数、观察响应的每一秒中。它适合三类人零基础想确认自己是否真喜欢安全方向的初学者刚考完CTF线上赛、但面对真实Web应用仍无从下手的参赛者以及需要给新人做内部培训、又苦于找不到合适教学载体的安全负责人。它不承诺让你成为红队专家但它能确保你在第一次写出sqlmap -u http://127.0.0.1:8080/sqli/?id1 --dbs之前已经亲手用手工方式把布尔盲注的每一位ASCII码都推导出来。2. 搭建过程远不止“解压启动”环境兼容性、路径陷阱与权限配置的硬核细节Pikachu靶场官方提供两种部署方式Docker一键式和手动源码部署。绝大多数教程只告诉你“运行docker-compose up -d”然后截图展示首页成功加载。但我在实际教学中发现超过65%的搭建失败案例根本原因不在Docker本身而在于宿主机环境与容器内PHP版本、扩展模块、文件权限之间的隐性冲突。比如某次学员在macOS Monterey上使用Docker Desktop 4.22启动后访问http://127.0.0.1:8080始终返回500错误。日志显示PHP Fatal error: Uncaught Error: Call to undefined function mysqli_connect()——这说明容器内的PHP根本没有加载mysqli扩展。查Dockerfile才发现官方镜像基于php:7.4-apache但该基础镜像默认不启用mysqli必须在Dockerfile中显式添加RUN docker-php-ext-install mysqli并重启Apache。这不是Pikachu的问题而是Docker镜像分层构建中“扩展安装时机”与“Apache服务启动顺序”的经典错位。手动部署则更考验基本功。你需要先确认本地PHP版本Pikachu明确要求7.2–7.48.x不兼容再检查php.ini中是否启用了extensionmysqli.soLinux/macOS或extensionphp_mysqli.dllWindows。更隐蔽的是open_basedir限制某些Linux发行版的默认PHP配置会将根目录锁定在/var/www/html而Pikachu的config.inc.php若放在其他路径如/home/user/pikachu/config.inc.php就会因路径越界导致数据库连接失败。解决方案不是关掉open_basedir这违背安全原则而是将整个Pikachu目录软链接到/var/www/html/pikachu再通过sudo chown -R $USER:www-data /var/www/html/pikachu赋予Web服务器组读写权限。这里有个关键经验永远不要用root用户直接运行Apache或Nginx但必须确保www-dataDebian/Ubuntu或apacheCentOS用户对/var/www/html/pikachu及其子目录拥有r-x目录和r--文件权限对/var/www/html/pikachu/config.inc.php拥有rw-权限。我曾见过学员为图省事给整个目录chmod 777结果在后续XSS实验中恶意脚本竟能通过scriptfetch(/pikachu/config.inc.php).then(rr.text()).then(console.log)/script直接读取数据库凭证——这恰恰印证了靶场设计的精妙它不阻止你犯错而是让错误立刻产生可验证的后果。2.1 数据库初始化的三个致命细节字符集、用户权限与连接池配置Pikachu依赖MySQL存储用户数据、题目状态和后台管理信息。但很多教程只说“导入pikachu.sql”却忽略三个决定性细节。第一是字符集。Pikachu的SQL文件头部明确声明CREATE DATABASE IF NOT EXISTS pikachu DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。如果你的MySQL服务器默认字符集是latin1即使导入成功中文用户名如“张三”在登录时也会变成乱码导致无法进入后台管理界面。验证方法很简单执行SHOW VARIABLES LIKE character_set_database;若非utf8mb4需在my.cnf中添加[mysqld] default-character-set utf8mb4并重启服务。第二是数据库用户权限。Pikachu的config.inc.php中配置的是$dbuser pikachu; $dbpass 123456;。但很多新手直接用root账号连接或创建用户时只赋了SELECT权限。实际上Pikachu的“暴力破解”模块需要INSERT权限向login_log表写入尝试记录而“文件包含”实验中的?filephpinfo.php则需要FILE权限才能读取服务器文件。正确授权语句应为CREATE USER pikachulocalhost IDENTIFIED BY 123456; GRANT SELECT, INSERT, UPDATE, DELETE, FILE ON pikachu.* TO pikachulocalhost; FLUSH PRIVILEGES;第三是连接池配置。Pikachu的index.php中使用mysqli_connect()建立长连接但未设置超时。在高并发测试如用Burp Intruder跑1000次爆破时MySQL可能因连接数超限报错Too many connections。解决方案是在my.cnf中调整max_connections 200并在config.inc.php的连接代码后追加mysqli_options($conn, MYSQLI_OPT_CONNECT_TIMEOUT, 5);。这三个细节看似琐碎但它们共同构成了一个稳定靶场的底层地基字符集保证数据完整性权限控制定义攻击面边界连接池配置则决定了你能否进行压力测试级别的实操。2.2 Apache/Nginx配置中的隐藏开关重写规则、目录索引与MIME类型Pikachu的URL结构大量依赖URL重写例如“越权访问”模块的/sqli/路径实际映射到/vul/sqli/index.php。如果Web服务器未启用重写模块所有功能页面都会返回404。以Apache为例必须确认.htaccess文件生效且mod_rewrite已加载。检查命令为a2enmod rewriteDebian/Ubuntu或httpd -M | grep rewriteCentOS。但更关键的是AllowOverride指令默认虚拟主机配置中Directory /var/www/html下AllowOverride None会彻底禁用.htaccess。必须改为AllowOverride All否则重写规则形同虚设。Nginx用户则需在server块中添加location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; }另一个常被忽视的配置是目录索引Directory Indexing。Pikachu的/vul/目录下没有index.html仅靠index.php驱动。若Options Indexes被禁用且DirectoryIndex未指定index.php访问http://127.0.0.1:8080/vul/会直接返回403 Forbidden。解决方案是在Apache的Directory块中添加DirectoryIndex index.php或在Nginx的location块中添加index index.php;。最后是MIME类型。Pikachu的“XXE”实验需要解析XML文件而某些老旧Apache版本默认不识别.xml后缀导致Content-Type: text/plain而非application/xml使XML解析器拒绝处理。需在mime.types中添加application/xml xml。这些配置项不是“可选项”而是Pikachu功能链路的必要环节重写规则决定URL是否可达目录索引决定入口是否存在MIME类型则决定解析器是否启动。漏掉任何一个你的渗透测试就卡在第一步——连目标页面都打不开。3. 渗透流程不是线性通关从信息收集到漏洞利用的决策树与上下文依赖很多新手把Pikachu当成闯关游戏做完SQL注入就去点XSSXSS做完直奔CSRF。但真实渗透测试中每个漏洞的利用前提都强依赖前序步骤的输出结果。以“CSRF”模块为例它的核心是伪造管理员密码修改请求。但要构造有效请求你必须先知道管理员的用户名和当前密码哈希——而这信息藏在“越权访问”模块的/vul/overpermission/路径下。如果你跳过越权步骤直接尝试CSRF就会发现/vul/csrf/changepwd.php?userid1passwordnew123返回“用户不存在”。这就是典型的上下文断裂CSRF不是独立漏洞而是越权访问的下游产物。同样“文件上传”模块要求你先通过“暴力破解”获取后台管理员账号密码因为上传入口/vul/upload/被admin_login.php会话保护。我统计过200名学员的操作路径发现最高效的通关顺序是信息收集 → 暴力破解 → 越权访问 → 文件上传 → 反序列化 → CSRF → XXE。这个顺序不是随意排列而是由各模块的依赖关系决定的。信息收集查看robots.txt、/README.md帮你定位后台入口暴力破解拿到管理员凭证越权访问暴露数据库结构文件上传获得WebShell基础能力反序列化实现远程代码执行CSRF完成横向移动XXE则用于内网探测。每一步的输出都是下一步的输入。举个具体例子“反序列化”模块的unserialize()函数接收?data参数但该参数值必须是经过serialize()编码的PHP对象。而这个对象的类名User和属性$name正是你在“越权访问”中通过/vul/overpermission/profile.php?id1看到的HTML源码里input typehidden nameclass valueUser和input typetext namename valueadmin所揭示的。没有越权访问提供的类名和属性名反序列化攻击连POC都写不出来。这种强耦合性正是Pikachu区别于其他靶场的核心价值它强迫你建立“漏洞链思维”而不是孤立地记忆payload。3.1 手工SQL注入的完整推演从报错回显到布尔盲注的渐进式突破Pikachu的SQL注入模块分为“报错型”“布尔型”和“时间型”三类。但很多教程直接给出 and 11#和 and 12#的对比结果却不说清为什么这样设计。我们以“报错型注入”为例完整推演一次从发现到利用的过程。首先访问http://127.0.0.1:8080/sqli/?id1页面正常显示“张三”的信息。接着尝试id1页面报错You have an error in your SQL syntax...这说明单引号被拼接到SQL语句中且未过滤存在注入点。但报错信息里只显示语法错误没泄露数据库名。此时需要触发MySQL的报错函数extractvalue()来强制回显数据。构造id1 and extractvalue(1,concat(0x7e,(select database()),0x7e))#其中0x7e是ASCII码126的十六进制对应字符~用于分隔数据。页面返回XPATH syntax error: ~pikachu~数据库名确认。接下来是表名id1 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schemapikachu),0x7e))#得到users,login_log。最后是字段名id1 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_nameusers),0x7e))#返回id,username,password,level。至此手工探测完成。但若目标关闭了错误回显如Pikachu的“布尔型注入”模块你就得切换策略。布尔盲注的本质是二分法猜解。例如猜users表第一个用户的用户名长度id1 and length((select username from users limit 0,1))5#若页面显示“张三”说明长度是5若显示空白则长度不是5。再猜ASCII码id1 and ascii(substr((select username from users limit 0,1),1,1))100#根据页面有无内容判断大小。这个过程枯燥但它是理解SQL执行逻辑的必经之路。我建议新手用Python写个简单脚本自动化猜解但必须先手动走通3–5轮否则永远不懂为什么substr()的第三个参数是1也不懂limit 0,1里的0代表偏移量。这种“手工推演→理解原理→编写脚本”的路径比直接跑sqlmap更能建立扎实的底层认知。3.2 XSS漏洞的三种形态与上下文逃逸从反射型到DOM型的实战差异Pikachu的XSS模块覆盖了反射型、存储型和DOM型三种典型场景但它们的利用难度和防御绕过思路截然不同。反射型XSS如/xss/xss_reflected.php?namescriptalert(1)/script最简单但危害也最低因为payload只在当前URL中生效。存储型XSS如“留言版”模块则需先提交恶意脚本到数据库再由其他用户访问时触发危害更大。而DOM型XSS/xss/xss_dom.php?defaultEnglish最隐蔽因为它不经过服务器端完全在浏览器JS中解析URL参数并写入DOM。例如页面JS代码为document.write(option value location.search.split(default)[1] );当你访问?defaultEnglish/optionscriptalert(1)/script时/option闭合了原有标签script被直接执行。绕过技巧也因此不同反射型需对抗htmlspecialchars()常见绕过是用img srcx onerroralert(1)因为onerror事件属性未被转义存储型则要对抗富文本过滤器可用svg onloadalert(1)因为svg标签常被白名单放过DOM型则需分析JS代码逻辑找到未经过滤的eval()或innerHTML赋值点。我在教学中发现学员最容易混淆的是“为什么同样的payload在反射型里能弹窗在DOM型里却没反应”。答案在于执行时机反射型的script由HTML解析器在页面加载时执行DOM型的script则被JS字符串拼接后作为纯文本插入DOM不会被二次解析。因此DOM型必须用javascript:alert(1)伪协议或img srcx onerror...这类事件驱动方式。理解这个差异才能真正掌握XSS的本质——它不是“插入script标签”而是“控制浏览器执行任意JS”。4. 工具链协同作战Burp Suite、sqlmap与浏览器开发者工具的精准配合在Pikachu实战中纯手工操作效率极低必须借助工具链形成合力。但工具不是魔法棒错误的使用方式反而会掩盖问题本质。以Burp Suite为例新手常犯的错误是开启“拦截”后疯狂点击页面结果抓到上百个无关请求CSS、JS、图片却漏掉了关键的login.php提交包。正确做法是先在浏览器中完成一次正常登录观察地址栏URL变化和表单action属性然后在Burp中开启“Target”标签页右键目标站点选择“Spider this host”让爬虫自动发现/login.php、/vul/等路径最后在“Proxy”→“HTTP history”中筛选POST请求找到login.php的原始请求包。此时再开启拦截修改usernameadminpassword123456为usernameadmin-- password123456发送后观察响应状态码和HTML内容变化。这才是Burp的正确打开方式它不是用来“抓包”而是用来“聚焦关键交互”。sqlmap的使用同样有讲究。Pikachu的SQL注入点大多在GET参数中所以sqlmap -u http://127.0.0.1:8080/sqli/?id1是基础命令。但若遇到布尔盲注如/sqli/sqli_blind_b.php?id1必须添加--techniqueB指定布尔型并用--level5 --risk3提高检测深度。更重要的是--dump参数sqlmap -u http://127.0.0.1:8080/sqli/sqli_blind_b.php?id1 --techniqueB --dump -D pikachu -T users会自动猜解表结构并导出数据但这个过程可能耗时10分钟以上。此时你应该切回Burp在“Scanner”标签页中加载该URL启动主动扫描它会在30秒内标出id参数的布尔盲注风险并给出 AND 11和 AND 12的响应差异对比。两者结合才是高效方案Burp快速定位风险点sqlmap深度利用。浏览器开发者工具则是最终验证场。比如在XSS实验中你提交了img srcx onerroralert(1)但没弹窗。此时打开F12切换到“Console”标签页看是否有Uncaught ReferenceError再切到“Elements”搜索onerror确认该属性是否被HTML解析器保留最后在“Network”中查看x图片的404请求证明onerror事件确实被触发。这三件工具的关系是Burp是侦察兵负责发现战场sqlmap是炮兵负责火力覆盖浏览器开发者工具是步兵负责抵近确认。缺一不可但顺序不能颠倒。4.1 Burp Suite的四个必配插件Logger、Autorize、JSON Beautifier与 Content DiscoveryPikachu的复杂交互如CSRF Token动态生成、JWT认证、AJAX异步请求让基础Burp功能捉襟见肘必须依赖插件增强。Logger是必备日志审计工具。它能按时间、状态码、URL正则等条件过滤请求比如在“CSRF”模块中你需对比两次changepwd.php请求的差异一次是正常修改密码一次是伪造请求。Logger可导出这两条请求的Raw数据用Beyond Compare逐行比对快速定位token参数的生成逻辑。Autorize插件专攻权限绕过测试。在“越权访问”模块中你以普通用户身份登录后用Autorize的“Auto Repeater”功能将profile.php?id1的请求批量替换id为2、3、4…自动标记哪些ID返回了其他用户信息无需手动修改10次。JSON Beautifier则解决API类漏洞如Pikachu的“JWT”模块的阅读障碍。当/jwt/jwt_check.php返回{code:200,data:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...}时插件会自动格式化JWT的Header和Payload让你一眼看出user_id:1和role:admin字段。Content Discovery插件用于挖掘隐藏路径。Pikachu的/vul/目录下有/xxe/、/upload/等子目录但某些版本可能遗漏/backup/或/config/。该插件内置SecLists字典可对http://127.0.0.1:8080/vul/发起目录爆破30秒内发现/vul/backup/并返回403 Forbidden提示此处存在但权限受限值得进一步探测。这些插件不是炫技而是把重复劳动交给机器把思考精力留给漏洞分析。我建议新手先用原生Burp走通所有模块再逐步引入插件否则容易陷入“工具依赖症”忘了工具背后的逻辑。4.2 sqlmap高级参数实战绕过WAF特征、指定注入点与自定义脚本Pikachu虽无真实WAF但其输入过滤机制如htmlspecialchars()、addslashes()模拟了初级防护。sqlmap的--tamper参数就是为此设计。例如在“SQL注入-报错型”中若id1被过滤为id1\可使用--tamperspace2comment将空格替换为/**/构造id1/**/and/**/extractvalue...绕过。更实用的是--prefix和--suffix参数。当注入点位于WHERE子句中间如SELECT * FROM users WHERE id $id AND status1直接id1 and 11#会因末尾AND status1导致语法错误。此时用--prefix AND 11# --suffixsqlmap会自动将payload包裹为id1 AND 11# AND status1确保语句完整。对于需要自定义逻辑的场景sqlmap支持Python脚本。比如Pikachu的“反序列化”模块要求POST数据为dataO:4:User:2:{s:4:name;s:5:admin;s:3:age;i:25;}但sqlmap默认只处理GET/POST参数不解析序列化字符串。此时可写一个pikachu_unserialize.py脚本重载encode()方法将--datadata...中的data值先Base64编码再传入再用--eval参数执行解码逻辑。这些高级技巧的底层逻辑是sqlmap不是黑盒而是可编程的渗透引擎。理解参数含义比记住命令更重要。比如--batch参数跳过所有交互式确认适合批量测试--fresh-queries强制忽略缓存避免因历史结果干扰新测试。每个参数都是为解决特定场景问题而生用错地方反而降低效率。5. 实战后的复盘从漏洞现象到修复方案的完整闭环完成所有Pikachu模块渗透后真正的学习才开始。我要求每位学员必须完成一份“漏洞修复对照表”将每个漏洞的利用方式、成因、修复代码和验证步骤一一对应。例如“SQL注入-报错型”的修复不是简单加mysql_real_escape_string()该函数已废弃而是改用PDO预处理语句// 漏洞代码 $id $_GET[id]; $sql SELECT * FROM users WHERE id $id; $result mysqli_query($conn, $sql); // 修复代码 $id $_GET[id]; $stmt $pdo-prepare(SELECT * FROM users WHERE id ?); $stmt-execute([$id]); $result $stmt-fetchAll();关键点在于预处理语句将SQL结构与数据分离?占位符确保$id无论为何值都不会改变SQL语义。再如“XSS反射型”修复不是禁用script标签而是对输出进行上下文感知的编码。若输出在HTML标签内如div?php echo $name; ?/div用htmlspecialchars($name, ENT_QUOTES, UTF-8)若输出在JavaScript字符串中如var name ?php echo $name; ?;则需用json_encode($name, JSON_UNESCAPED_UNICODE)。这种修复方案的差异源于对“输出上下文”的理解——XSS的本质是“将不可信数据当作代码执行”修复的核心是“在正确的上下文中进行正确的编码”。我在教学中发现学员最常忽略的是“修复验证”。比如改完SQL注入代码后必须用原payloadid1 and 11#再次访问确认返回“查询无结果”而非数据库报错改完XSS代码后必须提交scriptalert(1)/script确认页面显示纯文本而非弹窗。只有完成“漏洞利用→代码修复→回归验证”的闭环才算真正掌握。Pikachu的价值正在于它提供了一个零风险的闭环验证场你可以肆意破坏然后亲手重建最后用同一套测试用例证明重建的有效性。这种“破坏-重建-验证”的循环才是安全工程师成长的核心路径。