[CISCN 2023 华北]ez_date
题目:
<?php
error_reporting(0);
highlight_file(__FILE__);
class date{
public $a;
public $b;
public $file;
public function __wakeup()
{
if(is_array($this->a)||is_array($this->b)){
die('no array');
}
if( ($this->a !== $this->b) && (md5($this->a) === md5($this->b)) && (sha1($this->a)=== sha1($this->b)) ){
$content=date($this->file);
$uuid=uniqid().'.txt';
file_put_contents($uuid,$content);
$data=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($uuid));
echo file_get_contents($data);
}
else{
die();
}
}
}
unserialize(base64_decode($_GET['code']));
-
unserialize调用__wakeup()
-
if(is_array($this->a)||is_array($this->b)) #禁用了数组绕过 #这里直接让a=1,b='1',就可以绕过三个条件,这俩md5和sha1都是一样的
-
$content=date($this->file); # $content接受经过被date函数格式化后的变量file # date()的说明: # 该方法会检测传入的字符串中是否有特定的格式化字符,如Y(年份)、m(月份)、d(天)、H(时)、i(分钟)、s(秒)等 # 检测存在则会将格式化字符替换为当前时间的对应部分,否则将字符进行原样输出,同时可用转义字符将格式化字符原样输出
-
$uuid=uniqid().'.txt'; # uniqid()生成一个时间戳,将生成的时间戳拼接.txt给$uuid
-
$data=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($uuid));
- 开头的“/”和i前的“\”表示正则表达式语法的开始和结束
- (\s)* :匹配零个或多个空白字符(空格、制表符等)
- (\n)+ :匹配一个或多个换行符
- (\s)* :再次匹配零个或多个空白字符
- i :修饰符,表示不区分大小写
正则表达式会将上述空白字符和换行符都替换为空字符串。
-
file_put_contents($uuid,$content);
说明:
file_put_contents($uuid, $content);
是 PHP 中的一个函数调用,用于将一个字符串(内容)写入到一个文件中。这个函数简化了文件打开、写入和关闭的过程。这里是这个函数的基本解释和参数说明:file_put_contents($filename, $data, $flags = 0, $context = null)
$filename
($uuid
在此例中):你希望写入内容的文件路径和名称。在这个例子中,$uuid
应该是一个包含唯一标识符(由uniqid()
生成)加上.txt
扩展名的字符串,用于创建或覆盖一个具有唯一名称的文件。$data
($content
在此例中):你要写入文件的数据,可以是任何字符串。$flags
:这是一个可选参数,用于指定如何写入数据,比如FILE_APPEND
可以用于在文件末尾追加内容而不是覆盖。默认是0
,表示覆盖模式写入。$context
:也是一个可选参数,通常用于提供特定的上下文选项,比如HTTP、FTP等上下文。在大多数情况下,这个参数不需要设置。
所以,
file_put_contents($uuid, $content);
这行代码的作用是把变量$content
中存储的字符串数据写入到一个新创建的、以其UUID为名字(加上.txt
后缀)的文件中。如果文件已存在,它将被覆盖;如果要追加内容而不是覆盖,可以传递FILE_APPEND
作为第三个参数。 -
<?php $c='/flag'; print(date($c)); ?>
运行一下得到
/fThursdaypm11
,date()
会把特定字符格式化为当前时间戳,比如这里,把l
换成了星期四Thursday
a
换成了pmg
换成了时间11==解决方法:==转义字符\绕过:
/f\l\a\g
get方式把base64编码后的序列化字符串用code传进去就拿到flag了