Lottery

靶场环境是类似买彩票,猜数字,flag 需要钱买。

网站存在 git 源码泄露,利用 GitHack 将源码 dump 下来,找找利用点。

在 api.php 中定义了一个 buy 函数,代码如下:

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
function buy($req){
require_registered();
require_min_money(2);

$money = $_SESSION['money'];
$numbers = $req['numbers'];
$win_numbers = random_win_nums();
$same_count = 0;
for($i=0; $i<7; $i++){
if($numbers[$i] == $win_numbers[$i]){
$same_count++;
}
}
switch ($same_count) {
case 2:
$prize = 5;
break;
case 3:
$prize = 20;
break;
case 4:
$prize = 300;
break;
case 5:
$prize = 1800;
break;
case 6:
$prize = 200000;
break;
case 7:
$prize = 5000000;
break;
default:
$prize = 0;
break;
}
$money += $prize - 2;
$_SESSION['money'] = $money;
response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
}

可以看到判断数字是否相等的条件语句使用的是 == 而不是 === 。因为 php 的弱语言性质,所以 “1”,true,1 都是相等的,而该参数的传递使用的是 json ,json 是支持布尔型的,所以抓包把传递的参数改掉就可以了,然后刷钱买 flag。

NewsCenter

进环境是新闻搜索,猜测是sql 注入,手工注了半天,没反应。太菜了,上神器 sqlmap 跑一下。

burp 抓包,把请求头保存成文件。

可以看到是存在注入的,就直接跑表找 flag 就 ok了。

Mfw

环境打开是一个网站的样子,about 里面,说用了 git,考虑有没有 git 源码泄露。

可以看到存在源码泄露。直接 dump 下来,看看都有什么。

有一个 flag 文件,但是里面是空的。

只有 index.php 中有 部分 php 代码:

1
2
3
4
5
6
7
8
9
10
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];}
else {
$page = "home";}
$file = "templates/" . $page . ".php";
// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");

先来看看用到的都是什么函数:

insert

PHP 4、PHP 5、 PHP 7

isset():检测变量是否设置。存在并且值不是 NULL 则返回 TRUE,否则返回 FALSE。

assert

PHP5

assert( mixed $assertion[, string $description] ) : bool

PHP7

assert( mixed $assertion[, Throwable $exception] ) : bool

assert() 会检查指定的assertion并在结果为 **FALSE** 时采取适当的行动。 如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。
assertion 是字符串的优势是当禁用断言时它的开销会更小,并且在断言失败时消息会包含 assertion 表达式。
这意味着如果你传入了 boolean 的条件作为 assertion,这个条件将不会显示为断言函数的参数;在调用你定义的 assert_options() 处理函数时,条件会转换为字符串,而布尔值 FALSE 会被转换成空字符串。

strpos

strpos() 函数查找字符串在另一字符串中第一次出现的位置。对大小写敏感。

然后分析一下代码:

1
2
3
4
$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
assert("file_exists('$file')") or die("That file doesn't exist!");
“)system('ls')//

file 变量由接收来的 page 值 ,与 templates 和 php 后缀进行拼接,传入 assert 函数。

strpos 函数检查 file 中第一次出现 .. 的位置,有就退出。

assert 函数既然能在找不到 assertion 传来的变量时把字符串当做 php 代码执行,那我们就可以尝试构造 pay’load 执行执行命令,来获取 flag。

payload :test%27)%20or%20system(%27cat%20templates/flag.php%27);//