<?php highlight_file(__FILE__); if ($_GET["secret"] != hash("md4", $_GET["secret"])) { die('乐<br>'); } if (!preg_match('/http/i', $_GET['file'])) { if (preg_match('/^i_am_bloodhound$/', $_GET['name']) && $_GET['name'] !== 'i_am_bloodhound') { $file = $_GET["file"]; echo "我是布洛特亨德尔!<br>"; } } else { die("?"); } if ((string)$_GET['s1'] !== (string)$_GET['s2'] && md5($_GET['s1']) === md5($_GET['s2'])) { echo "众神之父赐予我视野<br>"; } else { die("众神之父赐予我重伤倒地<br>"); } if ($_REQUEST) { foreach ($_REQUEST as $value) { if (preg_match('/[a-zA-Z]/i', $value)) die('众神之父不喜欢英文<br>'); } } if (file_get_contents($file) !== 'phoniex_kit') { die("我重伤倒地"); } var_dump(file_get_contents("/flag"));
这是个md4绕过
PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,
所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
故我们传一个0e251288019
第一个if正则匹配传个file=http就行
第二个if是字符串比较,网上说可以加换行符%0A绕过
这是一个md5强碰撞,我们需要找到两个md5值相等的散列
互联网很强大,说来就来
s1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 &s2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
但是呢,由于这里使用了$REQUEST,根据php中的解释,它可以接受$GET ,$POST 值,并在一定条件下也能接受COOKIE值,
但是它会优先接受$POST传值,所以我们将之前做传的值都用POST传一遍数字。
file_get_contents()是用来将文件的内容读入到一个字符串中的首选方法,并且这个函数是可以绕过的
绕过方式有多种:
使用php://input伪协议绕过 将要GET的参数?xxx=php://input 用post方法传入想要file_get_contents()函数返回的值 用data://伪协议绕过 将url改为:?xxx=data://text/plain;base64,想要file_get_contents()函数返回的值的base64编码 或者将url改为:?xxx=data:text/plain,(url编码的内容)
于是我们开始尝试,发现data://伪协议可行。
最终完整的payload
得到flag