【CISCN 2023 华北】ez_date
Contents
[CISCN 2023 华北]ez_date
思路
-
源码
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
<?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']));
-
is_array($this->a)||is_array($this->b)
:这里不能使用数组绕过 -
($this->a !== $this->b) && (md5($this->a) === md5($this->b)) && (sha1($this->a)=== sha1($this->b))
:需要绕过===- 解决:
a=1
和b='1'
可以绕过
- 解决:
-
读取文件的名字绕过
1 2 3 4
$content=date($this->file); $uuid=uniqid().'.txt'; file_put_contents($uuid,$content); $data=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($uuid));
-
date()
该方法会检测传入的字符串中是否有特定的格式化字符,如Y(年份)、m(月份)、d(天)、H(时)、i(分钟)、s(秒)等
检测存在则会将格式化字符替换为当前时间的对应部分,否则将字符进行原样输出,同时可用转义字符将格式化字符原样输出
-
uniqid()
生成一个时间戳,将生成的时间戳拼接.txt给$uuid
-
preg_replace('/((\s)*(\n)+(\s)*)/i',''
- 开头的
/
和i
前的\
表示正则表达式语法的开始和结束 (\s)*
:匹配零个或多个空白字符(空格、制表符等)(\n)+
:匹配一个或多个换行符(\s)*
:再次匹配零个或多个空白字符i
:修饰符,表示不区分大小写
- 开头的
-
file_get_contents()
path 必需。规定要读取的文件。 include_path 可选。如果您还想在 include_path(在 php.ini 中)中搜索文件的话,请设置该参数为 ‘1’。 context 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。若使用 NULL,则忽略。 start 可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 中新增的。 max_length 可选。规定读取的字节数。该参数是 PHP 5.1 中新增的。
我们要读flag文件那猜测最常见在/flag,我们可以看一下那个date格式化把flag搞成啥样。
因为如果不会被替换的部分会直接原样输出。
1 2 3 4
<?php $a='/flag'; print(date($a)); ?>
输出结果为:/fWednesdayam10
说明f、l、a、g都被替换,因此使用转义符防止被替换
即
/f\l\a\g
-
Payload
|
|
|
|
总结
- php反序列化
- md5绕过
- 文件读取