先建立一个整体画面。你在浏览器输入网址、按下回车,一秒后页面出现。这一秒里发生了什么?
你的浏览器(客户端) 网站服务器 数据库
│ │ │
│ ①发送请求"给我首页" ───→│ │
│ │ ②向数据库要数据 →│
│ │ ←③返回数据 │
│ ←④返回网页 HTML ────────│ │
│ │ │
│ ⑤浏览器把 HTML 渲染成你看到的页面
三个角色的生活类比——点外卖:
记住一个关键事实:你浏览器里看到的网页,本质上都是服务器发给你的一串文本(HTML 代码),浏览器把它"翻译"成了好看的页面。你随时可以看这串文本——按 F12 或右键"查看网页源代码"。攻击者能"看见"的东西,和你能看见的完全一样:网页上的一切对所有人都是公开的,包括 HTML 注释、隐藏字段、JS 代码。第 3.11 关(敏感信息泄露)学的就是这个道理。
IP 地址 = 电脑在网络上的"门牌号"。形如 192.168.1.100。每个联网设备都有一个。
127.0.0.1 是一个特殊的 IP,永远指向你自己的电脑,也叫 localhost。访问 http://127.0.0.1/pikachu/ 就是访问你自己电脑上装的靶场——这正是我们在本机练习时所有网址的写法。端口 = 同一栋楼(同一个 IP)里的"房间号"。服务器上可以同时跑很多服务,靠端口区分:
| 端口 | 常见用途 |
|---|---|
| 80 | 网站默认端口(HTTP) |
| 443 | 加密网站(HTTPS) |
| 8080 | 备用网站端口、代理工具常用 |
| 3306 | MySQL 数据库 |
网址里没写端口时,默认访问 80。所以 http://127.0.0.1/pikachu/ 实际是 http://127.0.0.1:80/pikachu/。如果 PHPStudy 里 Apache 端口改成 8080,就要写 http://127.0.0.1:8080/pikachu/——这就是排障表里那条"端口 80 被占用"的由来。
文件路径 = 文件在电脑里的位置。Windows 用反斜杠 \,形如:
D:\phpstudy_pro\WWW\pikachu\index.php
│ │ └── 文件名
│ └── 网站根目录(放网页的地方)
└── 盘符(D 盘)
相对路径 = 不写盘符、从"当前位置"出发的路径。两个特殊符号:
. 表示当前目录.. 表示上一级目录(父目录)举例:你站在 D:\phpstudy_pro\WWW\pikachu\vul\fileinclude\ 这个目录里(Pikachu 的"文件包含"关卡就站在这):
.. → 回到 vul 目录..\.. → 回到 pikachu 目录..\..\..\..\.. → 一路往上,直到 D:\(盘符根目录)"目录穿越"攻击就是利用这一点:网站的"读取文件"功能如果不检查,你传 ..\..\..\..\windows\win.ini,网站就一路往上爬出网站目录,读到了 Windows 系统自己的配置文件。后面文件包含(3.6)、文件下载(3.8)、目录遍历(3.10)三个模块全是这个套路。多写几个 .. 不会出错——已经到根目录了再多写也没事,所以教程里的 payload 常写 4 个 .. 保险。
Linux/macOS 系统用正斜杠/,根目录就是/,系统账号文件是/etc/passwd。所以同样一道"读系统文件"的题,Windows 同学读c:\windows\win.ini,Mac 同学读/etc/passwd。两种写法在相应关卡都会给出。
浏览器和服务器之间只靠"请求-响应"对话,这种对话规则叫 HTTP 协议。一次网页访问 = 浏览器发一个"请求"、服务器回一个"响应":
请求(Request):浏览器发给服务器的话
POST /pikachu/vul/burteforce/bf_form.php HTTP/1.1 ← 第一行:方式 + 路径 + 协议版本
Host: 127.0.0.1 ← 请求头:发给哪台主机
User-Agent: Mozilla/5.0 ... ← 请求头:我的浏览器型号
Cookie: PHPSESSID=xxxxxxxx ← 请求头:我的身份凭证(见 0.5)
Content-Type: application/x-www-form-urlencoded ← 请求头:请求体的格式
username=admin&password=123456&submit=Login ← 请求体(POST 的数据放在这)
响应(Response):服务器的回答
HTTP/1.1 200 OK ← 状态码 200 = 一切正常
Set-Cookie: PHPSESSID=yyyyyyyy ← 响应头:服务器发来"号码牌"
Content-Type: text/html ← 响应头:下面内容是 HTML
<html>...页面内容...</html> ← 响应体(真正的网页内容)
两个必须分清的概念:GET 和 POST
| GET | POST | |
|---|---|---|
| 数据在哪 | URL 里(?id=1) | 请求体里(表单提交) |
| 生活类比 | 明信片(内容写在地址栏,谁都能看见) | 密封信(内容在信封里) |
| 你能直接改吗 | 能,直接改地址栏 | 不能,要用 Burp 改 |
状态码 = 服务器回答的"第一句话",常见四个:
200:正常,你要的东西在这302:去别处(跳转,比如没登录就被送到登录页)404:没找到这个页面500:服务器自己出错了(SQL 注入里最爱看到 500/报错页,说明我们的输入把程序弄崩了——这反而是好消息,见 3.4 模块)只要记住三件事:
问题:HTTP 协议本身是"无记忆"的——服务器每次收到请求都不知道你是谁。那"已登录"状态是怎么保持的?
答案:用"号码牌"机制,生活类比——银行取号:
对应到网站:
PHPSESSID=xxxxxxxx,这叫 Cookie所以:
document.cookie网页 = 三样东西的组合。生活类比——盖房子:
| 技术 | 角色 | 类比 |
|---|---|---|
| HTML | 结构 | 毛坯房:墙、门、窗在哪 |
| CSS | 样式 | 装修:颜色、大小、布局 |
| JavaScript(JS) | 行为 | 电路和机关:点按钮弹窗、提交表单 |
XSS 模块(3.2)主要和 HTML、JS 打交道,你需要懂几个概念:
标签:HTML 用尖括号标签描述内容。<script>代码</script> 表示"这是一段 JS 代码,浏览器请执行它";<img src=图片地址> 表示"显示一张图片"。
属性:标签的附加说明。<img src=x onerror=alert(1)> 里的 onerror 就是一个属性,意思是"如果图片加载失败,就执行后面的 JS 代码 alert(1)"。攻击者故意给一个不存在的图片地址 src=x,让加载必然失败,从而触发 onerror 里的代码——这就是 XSS 最常用的 payload 形式。
JS 能干什么:弹窗(alert(1))、读当前网站的 Cookie(document.cookie)、跳转页面等。XSS 的本质就是让受害者浏览器执行攻击者的 JS。
事件:用户在页面上的动作(点击、鼠标移入、图片加载失败)都叫事件,HTML 用 onXXX 属性绑定 JS 代码。常见攻击面:onerror、onload、onclick。
为什么要 URL 编码:URL 里有些字符有特殊含义,直接写会被浏览器处理掉。比如 < 要写成 %3C、> 写成 %3E、空格写成 %20。你在地址栏输入 payload 没反应时,很可能是特殊字符没编码——这也是为什么教程里推荐在 Burp 里改参数(Burp 里写原文即可,它帮你处理)。
数据库 = 存数据的仓库,组织成"表"。生活类比——Excel 表格:
pikachu)member 表存用户信息)SQL = 操作数据库的"命令语言"。数据库不像 Excel 靠鼠标点,而是靠命令查。本手册 SQL 注入模块(3.4)用到的语法就这几条,十分钟掌握:
-- 查数据:从 member 表查所有列,条件是 id 等于 1
select * from member where id=1;
-- 条件组合:and(并且)、or(或者)
-- or 1=1 是"或者 1 等于 1"——1=1 永远成立,所以整个条件永远成立 → 查出所有行!
select * from member where id=1 or 1=1;
-- 注释:-- 或 # 后面的内容被数据库忽略("干掉后面的代码"就用它)
select * from member where id=1; -- 我是注释,不执行
-- union:把两条查询结果拼在一起
select id from member where id=1 union select 1,2,3;
SQL 注入的本质:网站程序把用户输入直接拼进 SQL 语句。你输入的内容本来应该是"数据",却因为拼接,变成了"代码的一部分"。生活类比——餐厅点菜:
服务员问"您点什么菜?" 正常情况下你回答"宫保鸡丁"。但如果你回答:"宫保鸡丁,顺便把菜单上所有菜都上一遍",服务员一字不差地把这句话报给厨房,厨房真的把所有菜全做了——因为服务员没有区分"点菜内容"和"额外指令"。
网站程序就是那个"一字不差转述的服务员",攻击者就是那个"在点菜里夹带指令的顾客"。防御(参数化查询)就是让服务员把你说的话只当菜名,绝不执行其中的指令。
| 术语 | 一句话解释 |
|---|---|
| 靶场 | 专门用来练习攻击的"沙盒"网站,打坏了也没关系(Pikachu 就是靶场) |
| 漏洞 | 程序里能被攻击者利用的缺陷 |
| payload | 攻击者构造的那段"带毒输入"(比如 <script>alert(1)</script>) |
| 注入点 | 用户输入能进入 SQL/命令/HTML 的位置 |
| 编码 | 把字符换一种写法,绕过过滤(< 写成 %3C) |
| webshell | 传到服务器上的"遥控器"脚本,执行它就能远程控制服务器 |
| 一句话木马 | 只有一行代码的 webshell:<?php @eval($_POST['cmd']); ?> |
| 蚁剑(AntSword) | 连接一句话木马的图形化工具(3.7 文件上传关用) |
| 抓包 | 用工具(Burp)拦截并查看浏览器和服务器之间的请求 |
| 重放 | 把抓到的请求原样再发一次(Burp 的 Repeater 功能) |
| 爆破 | 用字典自动尝试大量密码(Burp 的 Intruder 功能) |
| 白盒 / 黑盒 | 看得见源码测试 / 看不见源码盲测(靶场练习都是白盒,源码全给你看) |
| 提权 | 从低权限用户变成管理员 |
目标:把靶场跑起来。跟着做,每步做完有"验证动作",看到验证动作里的现象才说明做对了,再进下一步。
https://www.xp.cn,点击下载 Windows 版 phpStudy V8.1(软件全名"小皮面板")D:\phpstudy_pro。注意:不要装到含中文的路径(如 D:\软件\),否则后面容易出奇怪问题验证动作:面板主界面能看到 Apache 和 MySQL 两个服务条目(可能显示"未启动",没关系,先看到它们)。
先解释为什么:Pikachu 是很多年前用 PHP 老语法写的,用了 mysql_connect() 等旧函数。PHP 7 以上删掉了这些函数,直接跑会报:
Fatal error: Uncaught Error: Call to undefined function mysql_connect()
所以必须用 PHP 5.x。操作:
验证动作:主界面 Apache 和 MySQL 都是绿色"已启动"状态;Apache 那一行显示的 PHP 版本是 5.6.x。
https://github.com/zhuifengshaonianhanlu/pikachu,点绿色 Code → Download ZIP 下载(如果网络访问 GitHub 困难,找老师要提前下载好的 zip 包)pikachu-master 文件夹,把它重命名为 pikachupikachu 文件夹放进网站根目录:D:\phpstudy_pro\WWW\验证动作:确认文件 D:\phpstudy_pro\WWW\pikachu\index.php 存在。打开 pikachu 文件夹应该能看到 index.php、inc、vul 等一堆文件和文件夹。
allow_url_fopen 和 allow_url_include,把等号右边都改成 On:allow_url_fopen = On
allow_url_include = On
验证动作:面板 Apache 重启后仍显示绿色"已启动"。(这一步不做的话,第 3.6.2 关"远程文件包含"永远打不通——到时候再来配也行,但提前配好省事。)
http://127.0.0.1/pikachu/pikachu 的库和若干表)验证动作:看到顶部完整导航栏 + 左侧是黄色皮肤样式。点导航里的"暴力破解"能进入模块页面,说明部署成功。
https://www.xp.cn 下载 macOS 版小皮面板~/phpstudy/www(面板里可查),把 pikachu 文件夹放进去allow_url_include = On,重启 Apachehttp://127.0.0.1/pikachu/ 初始化装了 Docker Desktop 的话,可用容器:
docker run -d --name pikachu-php -p 8080:80 -v "$HOME/Desktop/pikachu:/var/www/html" php:5.6-apache
docker run -d --name pikachu-mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root mysql:5.7
容器网络要互通(同一自定义 network),适合对 Docker 熟悉的同学。
平台差异提示:部分关卡读取系统文件时路径不同—— - Windows:c:\windows\win.ini- macOS / Linux:/etc/passwd练习时按自己的系统选对应的 payload,两种写法在相应关卡都会给出。
| 账号 | 密码 | 角色 | 用在哪 |
|---|---|---|---|
| admin | 123456 | 管理员 | 暴力破解、XSS 盲打后台、http header 注入等需登录关卡 |
| pikachu | 000000 | 普通用户 | 垂直越权演示(低权限账号) |
| test | test | 测试账号 | 备用 |
| vince / allen / kobe / grady / kevin / lucy / lili | 均为 123456 | 普通用户组 | CSRF、水平越权等需要"多账号"的关卡 |
| 现象 | 原因 | 解决 |
|---|---|---|
| 打开 127.0.0.1 显示 Apache 默认页 | pikachu 没放对目录 | 确认路径 WWW\pikachu\index.php 存在 |
| 打开 127.0.0.1 显示"无法访问" | Apache 没启动 | 面板启动 Apache |
报 mysql_connect undefined | PHP 版本 ≥7 | 切回 PHP 5.6/5.4 并重启 Apache |
| 端口 80 被占用(Apache 启动失败) | 迅雷/QQ/IIS/系统服务占 80 | 面板把 Apache 端口改成 8080,访问 http://127.0.0.1:8080/pikachu |
| 初始化时报数据库连接失败 | MySQL 没启动 | 面板启动 MySQL |
| 远程文件包含关卡没反应 | allow_url_include 没开 | php.ini 改 On 并重启 Apache |
| 文件上传关上传失败 | upload 目录不可写 | 检查 pikachu\pkxss\ 下 upload 目录权限(Windows 一般没问题,Mac/Linux 需 chmod -R 777 upload) |
| 时间盲注 sleep 不生效 | PHP 脚本超时过短 | 默认 30s 足够,确认 MySQL 正常即可 |
| 登录页验证码不显示 | PHP GD 扩展未开 | php.ini 开启 extension=gd |
| 页面提示"数据库连接失败"但 MySQL 是绿的 | 端口/密码配置不对 | 检查 inc/config.inc.php 里的数据库配置 |
四样工具:浏览器 F12(内置免费)、Burp Suite(抓包改包,免费社区版)、中国蚁剑(文件上传关用)、Python(token 关脚本用)。每样都配了"第一个练习",做完即会。
任何网页按 F12(Mac 是 Command+Option+I)打开开发者工具,四个常用面板:
| 面板 | 用途 | 你会怎么用它 |
|---|---|---|
| Elements | 看/改网页源代码 | 改 input 的 maxlength 限制(3.2.1 关)、找注释里的隐藏信息(3.11 关) |
| Console | 执行 JS、看报错 | 输入 alert(1) 弹窗——XSS 最基础原理 |
| Network | 看每个请求的细节 | 看请求方法、参数、Cookie、响应(点开一条请求看 Headers) |
| Application | 看/改 Cookie 和本地存储 | 看自己的 PHPSESSID、手动改 Cookie |
第一个练习(10 分钟):
alert(1) 回车,观察弹窗——这就是 XSS 最基础的原理,后面整章 XSS 都在干这件事Burp 是什么:抓包工具。"抓包"=把浏览器和服务器之间来回的请求拦截下来,你可以看、改、重发。暴力破解(爆破)、SQL 注入改参数、CSRF 改包,全都靠它。它是零基础自学最重要的一件工具,这一节请完整做一遍。
https://portswigger.net/burp/communitydownload,下载 Community 社区版(免费够用)启动 Burp 后:
127.0.0.1:8080(Proxy → Options 里看)Burp 在 127.0.0.1:8080 开了个"检查站",要让浏览器把请求先送检查站,需要给浏览器设代理:
方法一(推荐):SwitchyOmega 插件
127.0.0.1 端口 8080方法二:系统代理
127.0.0.1 端口 8080 → 保存http://127.0.0.1/pikachu/验证动作:history 里能看到 GET /pikachu/ 这条请求。点开它,你能看到请求头、响应内容——恭喜,抓包成功。此时浏览器页面可能"一直转圈":那是因为请求被 Burp 拦住了,去 Burp 点 Forward(放行)就好。
抓 HTTPS 网站(如百度)会报证书错误:浏览器访问 http://burp → 下载 CA 证书 → 浏览器设置里导入并信任。本靶场全是 HTTP,不装证书也能正常抓,可以先跳过。
蚁剑是什么:图形化"遥控器"。当你在文件上传关把一句话木马传到服务器后,用蚁剑连接它,就能像操作自己电脑一样执行命令、看文件。
https://github.com/AntSwordProject/antSword(Release 里下载 antSword.zip 加载器版本,另按页面说明下载核心源码 antSword-4.x.zip)http://127.0.0.1/pikachu/unsafeupload/uploads/evil.php)→ 连接密码填木马里 $_POST['cmd'] 的 cmd → 添加whoami)验证动作:文件管理界面能看到服务器目录结构(你的 Windows 目录)。连不上先检查:URL 拼对没、木马文件上传成功没、PHP 版本是不是 5.6。
第 3.1.4 关"token 防爆破"需要一个 Python 脚本,先装好环境:
https://www.python.org/downloads/,安装时勾选 "Add Python to PATH"(关键,不勾装完没法在命令行用)python --version 回车验证动作:显示 Python 3.x.x 版本号。
pip install requests
test.py 文件(用记事本,另存为时选"所有文件"再写 .py 后缀),在 CMD 里 cd 到文件所在目录,运行 python test.py。注意:保存 .py 文件的路径不要有中文和空格,否则命令行可能找不到文件。
每关统一按「过关标准 → 类比故事 → 原理白话 → 看源码 → 详细步骤 → 卡住了 → 防御 → 想一想」八段式编写。先看"过关标准"知道终点,卡住先翻"卡住了"。全部关卡只在本地靶场练习,严禁对非授权系统测试。
我爱换客网 · 红队成长之路 | 靶场内容仅供本地环境学习,请勿对未授权目标使用 | 靶场目录