攻防世界—lottery

先大致的了解一下题目环境

看到题目后先尝试注册一个账号

发现直接跳转到购买(buy)界面

随意输入7个数据(框中提示输入7个数据)

发现余额居然涨了5块钱

再看看其他界面

Accunt

Claim Your Prize

在这里可以了解到我们只需要存够9990000$就能购买flag

这时候解题思路大概就出来了

首先我们要通过抽奖存钱

然后通过存下的钱来购买flag

所以我们要先知道抽中大奖(也就是7个全中)的逻辑是什么

(这个时候我也想到了为什么不能一直抽奖,抽够钱了也可以买flag,于是抽了一段时间后我出现了一个弹窗打消了我的念头)

所以还是老老实实找别的漏洞吧

但通过对buy页面的源代码分析我们似乎得不到任何线索

用dirsearch扫描后发现存在.git泄露

用GitHack获取.git文件

因为文件中内容比较多,所以就不一个文件一个文件的讲解了,这里只简单的概述一下每个文件大概完成了什么功能:

 目标页面构成如下:
 - index.php     -> 首页,显示游戏规则
 - register.php  -> 注册页面,用于注册用户后购买彩票
 - buy.php   -> 彩票抽奖页面,在此页面可以通过抽奖获得虚拟币
 - account.php   -> 用户账户页面,用于显示用户的账户余额
 - market.php    -> 领奖页面,通过虚拟币购买我们需要的 flag
 - logout.php    -> 登出页面,同时销毁用户 SESSION
  
 目标其他文件功能如下:
 - api.php       -> 所有的逻辑都通过调用此页面完成,包括注册用户,销毁用户,生成彩票随机数,购买 flag 等
 - check_register.php    -> 用于检查用户是否已经注册,如果未注册,则跳转到注册页面
 - config.php        -> 配置文件,里面包含了 flag
 - footer.php            -> 页脚
 - header.php        -> 页头

api.php的内容如下所示

<?php
require_once('config.php');
header('Content-Type: application/json');

function response($resp){
	die(json_encode($resp));
}

function response_error($msg){
	$result = ['status'=>'error'];
	$result['msg'] = $msg;
	response($result);
}

function require_keys($req, $keys){
	foreach ($keys as $key) {
		if(!array_key_exists($key, $req)){
			response_error('invalid request');
		}
	}
}

function require_registered(){
	if(!isset($_SESSION['name']) || !isset($_SESSION['money'])){
		response_error('register first');
	}
}

function require_min_money($min_money){
	if(!isset($_SESSION['money'])){
		response_error('register first');
	}
	$money = $_SESSION['money'];
	if($money < 0){
		$_SESSION = array();
		session_destroy();
		response_error('invalid negative money');
	}
	if($money < $min_money){
		response_error('you don\' have enough money');
	}
}


if($_SERVER["REQUEST_METHOD"] != 'POST' || !isset($_SERVER["CONTENT_TYPE"]) || $_SERVER["CONTENT_TYPE"] != 'application/json'){
	response_error('please post json data');
}

$data = json_decode(file_get_contents('php://input'), true);
if(json_last_error() != JSON_ERROR_NONE){
	response_error('invalid json');
}

require_keys($data, ['action']);

// my boss told me to use cryptographically secure algorithm 
function random_num(){
	do {
		$byte = openssl_random_pseudo_bytes(10, $cstrong);
		$num = ord($byte);
	} while ($num >= 250);

	if(!$cstrong){
		response_error('server need be checked, tell admin');
	}
	
	$num /= 25;
	return strval(floor($num));
}

function random_win_nums(){
	$result = '';
	for($i=0; $i<7; $i++){
		$result .= random_num();
	}
	return $result;
}


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]);
}

function flag($req){
	global $flag;
	global $flag_price;

	require_registered();
	$money = $_SESSION['money'];
	if($money < $flag_price){
		response_error('you don\' have enough money');
	} else {
		$money -= $flag_price;
		$_SESSION['money'] = $money;
		$msg = 'Here is your flag: ' . $flag;
		response(['status'=>'ok','msg'=>$msg, 'money'=>$money]);
	}
}

function register($req){
	$name = $req['name'];
	$_SESSION['name'] = $name;
	$_SESSION['money'] = 20;

	response(['status'=>'ok']);
}


switch ($data['action']) {
	case 'buy':
		require_keys($data, ['numbers']);
		buy($data);
		break;

	case 'flag':
		flag($data);
		break;

	case 'register':
		require_keys($data, ['name']);
		register($data);
		break;
	
	default:
		response_error('invalid request');
		break;
}

其中在关键在于这里存在一个弱比较漏洞

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]){    //通过 $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]);
}

到这里我们想要达到抽中大奖的思路大体成型了

要抽中大奖,需构造用户号码与之弱匹配让 7 个位置的号码均满足 $numbers[$i] == $win_numbers[$i]

在这里我们先补充一下弱比较漏洞的知识

弱等于 ==

在比较前会先把两种字符串类型转成相同的再进行比较。简单的说,它不会比较变量类型只比较值

达成条件

1.若一个数字和一个字符串进行比较或者进行运算

PHP 会把字符串转换成数字再进行比较。若字符串以数字开头,则取开头数字作为转换结果(例如 “aaa” 是不能转换为数字的字符串,而 “123” 或 “123aa” 就是可以转换为数字的字符串),而对于不能转换为数字的字符串或 null,则转换为0;

2.布尔值 true 和任意字符串都弱相等

3.数字和“e“开头加上数字的字符串(例如”1e123”)会当作科学计数法去比较次方

同时留意0eXXXXX类型的字符串,类型转换机制会把它识别为一个科学计数法表示的数字“0”,所以无论0e后面是什么,0 的多少次方结果还是 0

这里我们利用的就是第二个特性(布尔值 true 和任意字符串都弱相等

打开burp,抓取抽奖时的包

(因为我们修改的是抽奖的逻辑,在进行抽奖的时候达到7个球都判断为ture,故修改的是抽奖时的包)(记得先登录)

点击buy抓取抽奖时的包

(意外发现这个文件刚好也是我们刚刚分析的文件,所以大家也可以在一开始通过抓包寻找抽奖时调用的是哪个php文件,然后再回头分析抽奖的逻辑)

修改number的值,这里我们可以利用列表来统一化为ture

多点几次就够钱买了(所以我的flag怎么这么抽象)

基于阶梯碳交易的含 P2G-CCS 耦合和燃气掺氢的虚拟电厂优化调度(Matlab代码实现)内容概要:本文围绕“基于阶梯碳交易的含P2G-CCS耦合和燃气掺氢的虚拟电厂优化调度”展开研究,提出了一种综合考虑碳交易机制、电转气与碳捕集封存(P2G-CCS)技术以及天然气管道掺氢利用的虚拟电厂优化调度模型。通过构建阶梯式碳交易成本函数,激励低碳运行,结合P2G技术将富余可再生能源转化为氢气或甲烷进行存储与利用,同时引入CCS技术降低碳排放,并探索燃气系统掺氢输送的可行性,提升能源系统灵活性与低碳水平。采用Matlab进行建模与求解,验证了该模型在降低系统运行成本、减少碳排放和提高可再生能源消纳能力方面的有效性。; 适合人群:具备电力系统、能源系统优化背景,熟悉Matlab编程和优化建模的研究生、科研人员及能源领域工程技术人员。; 使用场景及目标:①研究高比例可再生能源接入背景下虚拟电厂的低碳优化调度策略;②探索P2G-CCS与燃气掺氢技术在综合能源系统中的协同效益;③实现阶梯碳交易机制下的经济性与环保性联合优化。; 阅读建议:建议读者结合Matlab代码深入理解模型构建过程,重点关注目标函数设计、约束条件设置及求解方法的选择,同时可尝试调整碳交易阶梯参数、P2G效率或掺氢比例等关键变量,开展敏感性分析以深化对系统运行特性的认知。
内容概要:本文档是Geant4协作组织发布的面向应用开发者的权威手册,系统介绍了Geant4——一种用于模拟粒子与物质相互作用的蒙特卡洛仿真工具包的核心概念与使用方法。内容涵盖从基础入门(如定义主程序、构建探测器几何结构、设置材料与粒子)到高级功能(如物理过程建模、轨迹跟踪、可视化、数据分析及多线程控制)的完整开发流程。重点讲解了用户动作类、探测器响应、电磁场处理、击中与数字化、偏差技术、并行几何与评分机制等关键模块,并提供了丰富的代码示例与命令接口说明,帮助开发者构建完整的仿真应用程序。; 适合人群:具备C++编程基础和基本粒子物理知识,从事高能物理、核科学、医学物理或辐射探测等领域研究的研发人员、研究生及工程技术人员;尤其适合需要定制化仿真系统的应用开发者。; 使用场景及目标:① 构建粒子探测器的几何模型并配置材料属性;② 定义粒子源与物理过程,实现事件生成与轨迹追踪;③ 利用可视化工具调试几何结构与分析数据;④ 实现敏感探测器、击中处理与数字化流程;⑤ 应用评分与分析工具进行结果统计与输出。; 阅读建议:建议结合Geant4安装包中的示例程序(如B1、RE系列)同步实践,优先掌握核心类(G4RunManager、用户动作类、G4UImanager)的作用机制,重视可视化调试与几何检查功能的使用,逐步深入理解状态机管理、多线程架构与自定义物理列表的设计逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值