CTFer成长记录——CTF之Web专题·攻防世界—lottery

发布时间 2023-08-10 15:51:46作者: MiracleWolf

一、题目链接

https://adworld.xctf.org.cn/challenges/list?rwNmOdr=1691651594927

二、解法步骤

  打开网页,这是一个买彩票换flag的网站。题目附件提供了源码:

  在网站上探索一番,发现买flag需要9990000R,获得资金的方式就通过buy功能买彩票。

  那么我们随便输入一个数字,然后用bp抓包发送到repeater,看看这个彩票的值是不是固定的:

发现中奖号码是8693140,那么把原来的数值修改下,看看行不行:

  发现不行,这就说明中奖号码是随机生成的。常规方式行不通,就必须进行代码审计,看看这个buy模块是怎么写的:

  源代码中包含几个文件,猜测action:buy可能在api文件中:

function buy($req){
	require_registered();
	require_min_money(2);

	$money = $_SESSION['money'];//接受用户原有money
	$numbers = $req['numbers'];//接受输入的数字
	$win_numbers = random_win_nums();//生成随机中奖号码
	$same_count = 0;//中奖数字的个数
	for($i=0; $i<7; $i++){
		if($numbers[$i] == $win_numbers[$i]){ //这里是一个弱比较==,如果数组中的值都是true的话,比较永远都是正确的
			$same_count++;
		}
	}


   通过审计发现,存在弱比较,那么我们通过抓包,将输入的号码改成数组型,里面的元素全是true,就可以通过比较,得到奖金了:

  payload:"numbers":[true,true,true,true,true,true,true],这样是数组,之前的""是字符串。

  注意,如果中奖号码随机生成的数字中有0,那么true=0是会比较失败的,多尝试几次就能攒够钱买flag了。

  然后取account里面看:

  最后买下flag:

三、总结

  本题的目标是获取足够的钱得到flag,一般是通过抓包修改,如果不行,就需要更进一步进行代码审计等操作,找到漏洞进行利用,从而获取flag。