1
2
3
4
5
知识点:
git 源码泄露
json 数据传递
代码审计
//由于经常碰到这种攒钱 买东西的题目,所以记录下来,留个思路。

打开题目,是一个买彩票的小游戏,每个用户初始金额为 $20 买一次彩票 $2,可以自己输入 7 位数字,当输入的数字与系统随机给出的数字一致则获得一定的金额,钱可以用来购买 flag 需要 $9990000

1557639222377

1557639084108

想了一下没有别的思路,扫描了后台,看看有没有别的突破口。

http://111.198.29.45:40735/robots.txt 中发现了提示 .git

1557639574145

git 源码泄露,用工具把源码 down 下来

1557639649240

接着就是代码审计

代码中随机数的生成很严格,无法预测。但是在 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]);
}

在比较数字是否相同时,使用的是弱比较 $numbers[$i] == $win_numbers[$i] 没有检测数据类型,而且在系统在传递数据时使用的是 json 格式 支持布尔型数据。

所以我们只要传递 7 个 true ,当系统比较时,只要生成的随机数中有大于 1 的数字即可比较成功。

1557640275261

多发送几次,再刷新界面,就发现用户的钱已经能够买到 flag 了

1557640337670

flag 到手

1557640353674