题目描述

来源:XCTF 4th-QCTF-2018

Solution

打开网页,发现要我们买彩票,我们买一个试试:

1.png

2.png

你可以来到 Account 观察自己的余额,每买一次彩票会少 2 美元。

3.png

点击 Claim Your Prize,题目告诉我们要赚够 9990000 美元才能买到 Flag:

4.png

我们用 dirsearch 扫一下目录,可以发现有 git 源码文件:

5.png

6.png

我们使用 GitHack 扫描 URL,把泄露的文件都下载下来:

7.png

下载完后 GitHack 会以 IP 为名字在当前目录创建一个文件夹,里面内容是这样的:

8.png

打开其中的 api.php 文件审计代码,注意到这里有个 buy() 函数,这个是我们在网页买彩票会调用的函数。其中我们看到 numbers 这个变量是我们能操作的,函数会以数组的形式提取每位数字。同时这个变量在和随机生成的 win_numbers 变量比较时使用的是 ==,也就是说可以用弱类型来绕过。

  1. function buy($req){
  2. require_registered();
  3. require_min_money(2);
  4. $money = $_SESSION['money'];
  5. $numbers = $req['numbers'];
  6. $win_numbers = random_win_nums();
  7. $same_count = 0;
  8. for($i = 0; $i < 7; $i++){
  9. if($numbers[$i] == $win_numbers[$i]){
  10. $same_count++;
  11. }
  12. }
  13. switch ($same_count) {
  14. case 2:
  15. $prize = 5;
  16. break;
  17. case 3:
  18. $prize = 20;
  19. break;
  20. case 4:
  21. $prize = 300;
  22. break;
  23. case 5:
  24. $prize = 1800;
  25. break;
  26. case 6:
  27. $prize = 200000;
  28. break;
  29. case 7:
  30. $prize = 5000000;
  31. break;
  32. default:
  33. $prize = 0;
  34. break;
  35. }
  36. $money += $prize - 2;
  37. $_SESSION['money'] = $money;
  38. response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
  39. }

用 Brupsuite 抓包,购买彩票时会用 POST 请求传参:

9.png

我们把它发送到 Repeater,修改numbers变量为:[true,true,true,true,true,true,true]

10.png

利用重放器把钱刷够后就可以去买 Flag 了:

11.png