Hackergame 2021 - 数值溢出 [卖瓜]

一、题目

题干描述的比较奇怪,看到浮点数也不知道是什么意思,没见过这种题型

点进去看

 题目的意思是让我们用6和9构造出20,但是很容易看出来,6s+9t = 20这个方程是没有整数解的,因为20不是3的倍数

这里正常方法肯定是不行的,估计会有骚操作

二、解题

F12检查元素

 试试把 min 的值改为负数,提交了一个负数上去

 

 后台不认,那么肯定是有检测机制的

再试试输入小数

 小数也不行

 我做出这题的灵感来源于室友,他告诉我,当在9斤的瓜那里输一个很大的数时,提交上去会变成一个负数,如下:

 而这个负数其实非常特殊,因为它正好是long long int 的最小值

正常情况下是不可能出现负数的

也就是说,我们如果输入一个很大的值,会造成溢出,这个地方就可以做工作了

用这个-9223372036854775808除以9,将得到的数取整输入进去,不会造成溢出,但是将这个数再+1就会造成溢出了,对6同理

我们选择用9乘以大数造成溢出,再用6加回来,直到6s+9t = 20-(-得到的负数)有整数解

 直接操作

第一步:9乘大数溢出

 第二步:6乘那个上面在计算器得到的取整后的数

 

得到-2了,那么下一次可以选择构造出-4,或者用6再梅开二度

第三步:6梅开二度

可以看到这里再减去一个 9223372036854775808时,就刚刚好会出现-4,也就是我们需要的24

第四步:9乘以大数溢出

 第五步:6*4加回去补上-4

 拿到flag

 三、总结

1. 这种题型确实挺新奇的,不过尝试的次数会很多很多,我在寝室里骂了出题人一个下午

2. 实际上这题对猜后台代码的能力有一定要求,看看官方给出的wp

function action()
{
    check_last_action();
    $bottle_6 = intval($_POST['b6']);
    $bottle_9 = intval($_POST['b9']);
    if ($bottle_6 < 0 || $bottle_9 < 0) {
        die('操作无效:不能放负数个瓜。点击<a href="/">这里</a>回到主页。');
    }
    $_SESSION['pool'] += intval($bottle_6 * 6 + $bottle_9 * 9);
    header('Location: /');
}

根据 PHP 文档 Integer 整型,PHP 在运算结果超出 int 范围时,会返回 float 类型,进一步使用函数 intval() 来把 float 转为 int 时,如果这个 float 超出了 int 范围(定义在 PHP_INT_MAX),结果是未定义的,在其评论中有一条 Be aware of float to int cast overflow 列举了一些溢出后的转换结果,选手也可以自己尝试。在尝试的过程中,只要能产生一个模 3 余 2 的重量(如 2, -1 等)都可以很容易凑到 20。

其实我在试的时候是出现了科学计数法表示的大数,当时想着通过这个来突破,但是也不行,一加回去又变成0了,后来看到官方wp后才知道,一旦这个数小于-9223372036854775808,就会变成后台定义的科学计数法表示,这是个坑

3. 果然是中科大,能想到个出这种题,不过也不算纯web,多少是沾点数论和编程了

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值