国赛之大宝剑

前言

因为之前对验证码验证逻辑错误,一直很好奇怎么产生的,巧了,这次的国赛,遇到了这方面的题。

正文

题目考点

  1. php弱比较
  2. 验证码验证逻辑错误
  3. 弱口令爆破

题目分析

购买彩票,有一定概率获取金币

彩票购买页面如下:

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
<?php
include_once('check_login.php');
header('Content-Type: application/json');
function get_win_num(){
$win_nums = "";
for($j=0;$j<6;$j++){
$win_nums .= random_int(0,9);
}
return $win_nums;
}
$data = json_decode(file_get_contents('php://input'), true);
function buy($data){
check_login();
$money = $_SESSION['money'];
if($money < 5){
die("钱数低于最低要求!");
}
$numbers = $data['numbers'];
$win_nums = get_win_num();
$same_counter = 0;

for($i=0; $i<6; $i++){
if($numbers[$i] == $win_nums[$i]){
$same_counter++;
}
}

if($same_counter == 2){
$win_money = 10;
}elseif ($same_counter == 3) {
$win_money = 50;
}elseif ($same_counter == 4) {
$win_money = 500;
}elseif ($same_counter == 5) {
$win_money = 2000;
}elseif ($same_counter == 6) {
$win_money = 50000;
}else {
$win_money = 0;
}

$money -= 5;
$money += $win_money;
$_SESSION['money'] = $money;
$response_text = array('status'=>'ok','numbers'=>$numbers, 'win_nums'=>$win_nums, 'money'=>$money, 'win_money'=>$win_money, 'same_counter'=> $same_counter, 'data' => $data);
$date = json_encode($response_text);
echo $date;
}
buy($data);
?>

漏洞代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if($same_counter == 2){
$win_money = 10;
}elseif ($same_counter == 3) {
$win_money = 50;
}elseif ($same_counter == 4) {
$win_money = 500;
}elseif ($same_counter == 5) {
$win_money = 2000;
}elseif ($same_counter == 6) {
$win_money = 50000;
}else {
$win_money = 0;
}
}

这里采用==符号,利用true==任何数字绕过

所以只需要post:{"numbers":[true,true,true,true,true,true]}

来到管理员登录页面:

发现需要有验证码,虽然有hint:密码是5位数字。

接着填写正确验证码,利用burp抓包,repeater,go

然后修改密码,再次go

发现验证码可以重复使用。

那么直接利用burp爆破密码。

因为赛区最后放了源码,所以正好从代码层面学习一波。

下面看看验证码部分的验证逻辑,哪里出现了问题。

login.html页面

填写账号、密码、验证码后,页面会跳转到login.php

并且发现在当login.html页面刷新或者点击验证码图片,验证码会重新从verifycode.php加载。

继续跟进verifycode.php页面。

验证码截取time()函数生成后四位数字。

然后存入session文件中

再看看login.php页面:

首先整个页面没有涉及访问verifycode.php页面,也就是说,存在session文件中的验证码$_SESSION['img_number']没有改变。当然正常访问的话,密码错误,会回到login.html页面,验证码也刷新了,但是利用burp抓包爆破密码的话,并不会重新跳转到login.html页面。

可以在爆破的时候,刷新浏览器器上的login.html页面,然后看看爆破的数据包也立即出现验证码错误。

解题流程

购买彩票 ,修改数据

重复几次,购买大宝剑,获取后台地址。然后爆破弱密码。

得到密码

最后

加油……..