吾爱破解2025春节红包活动番外篇第三题

admin 2025年2月14日08:45:46评论9 views字数 5130阅读17分6秒阅读模式

字数 1187,阅读大约需 6 分钟

0x00 前言

番外篇第三题刚开始是有难度的,玩家会相互干扰,想要获取flag,还是需要靠一点运气的。后面修改了难度,分 IP 抽奖,互相不干扰了。难度就降低了不少。

0x01 分析

第三题是抽奖的,地址:https://2025challenge.52pojie.cn/lottery.html ,看一下题目。

吾爱破解2025春节红包活动番外篇第三题

抽奖算法也给出了

blockNumber=$(curl -s -H 'Content-type: application/json' --data-raw '{"body":{}}' 'https://api.upowerchain.com/apis/v1alpha1/statistics/overview' | jq -r '.blockHeight')
blockHash=$(curl -s -H 'Content-type: application/json' --data-raw '{"number":"'$blockNumber'"}' 'https://api.upowerchain.com/apis/v1alpha1/block/get' | jq -r '.data.blockHash')
userCount=10001
userIndex=$(python -c "print($blockHash % $userCount)")
echo $userIndex

以之前中奖的为例,blockNumber=29443498,可以看到

blockHash=0xed10c6b62d163279cfff03e39a8017e303a03d48a6a314d24c47596b998ae30b

参与抽奖人数是10071

吾爱破解2025春节红包活动番外篇第三题

那么我们可以通过计算,获取中奖人的序号

blockHash = 0xed10c6b62d163279cfff03e39a8017e303a03d48a6a314d24c47596b998ae30b
userCount=10071
print(blockHash % userCount)

验证结果是3000。

blockNumber 在每次开奖前也给出了,那么可以根据blockNumber请求API获取blockHash。知道blockHash后,如果可以控制参与抽奖的人数,那么获奖人员的编号也能够确定了。

所以之前的难度是比较大的,都是真人玩家,不好确定参与人数和位置。后面降低了难度,分IP抽奖,互不干扰。

另外需要注意的是,每次抽奖系统会自动添加 9980 个机器人,所以如果参与抽奖的话,编号是从9980开始的。因此需要找到中奖序号大于等于9980的,才能保证自己中奖。而且满10000人才开奖,所以还要添加虚假的UID,来凑人数。

0x02 解题

由于现在答题地址下线,所以以之前已开奖的来模拟答题。找到一个中奖序号大于等于9980的blockNumber。

吾爱破解2025春节红包活动番外篇第三题

这里的blockNumber为29439513,假如参与抽奖的人数是10000-10300,主要代码

async function findWinningUserCount(blockNumber) {
        try {
            // 获取指定区块的哈希
            const r = await fetch('https://api.upowerchain.com/apis/v1alpha1/block/get', {
                method'POST',
                headers: {'Content-Type''application/json'},
                bodyJSON.stringify({"number": blockNumber.toString()})
            });
            const data = await r.json();
            console.log("n=== API响应 ===");
            console.log(JSON.stringify(data, null2));
            
            if (!data || !data.data || !data.data.blockHash) {
                console.error("无效的API响应:", data);
                return null;
            }
            
            const hash = data.data.blockHash;
            const hashWithPrefix = hash.startsWith('0x') ? hash : '0x' + hash;
            console.log(`n区块哈希: ${hashWithPrefix}`);
            //从10000开始尝试不同的userCount
            for (let userCount = 10000; userCount <= 10300; userCount++) {
                const result = BigInt(hashWithPrefix) % BigInt(userCount);
                
                if(result >= 9980n) {
                    const position = Number(result - 9980n);
                    console.log(`n!!! FOUND WINNING COMBINATION !!!`);
                    console.log(`Block: ${blockNumber}`);
                    console.log(`Hash: ${hashWithPrefix}`);
                    console.log(`User Count: ${userCount}`);
                    console.log(`Absolute Position: ${result}`);
                    console.log(`Relative Position: ${position}n`);
                    return {position, userCount};
                }
            }
            
            console.log("n没有找到合适的参与人数组合");
            return null;
        } catch(e) {
            console.error(`n[错误] 检查区块 ${blockNumber} 失败:`);
            console.error("错误详情:", e);
            console.error("错误堆栈:", e.stack);
            return null;
        }
    }
const blockNumber = 29439513
const result = await findWinningUserCount(blockNumber);
吾爱破解2025春节红包活动番外篇第三题

根据计算的结果,答题人需要有10201个,中奖的序号是10067,实际位置是第87。剩余的位置都添加虚假的UID。

async function joinMultiple() {
    let timestamp = Math.floor(Date.now() / 1000);
    let code = await getVerifyCode(timestamp.toString() + "|");
    
    // 需要221个UID (10201 - 9980 = 221)
    const uids = [];
    
    // 生成52个UID,确保自己的UID在第87位
    for(let i = 0; i < 221; i++) {
        if(i === 87) {
            uids.push("你的UID");  // 中奖位置
        } else {
            uids.push((200000 + i).toString());  // 其他位置用虚假UID
        }
    }
    
    console.log(`n=== 开始提交抽奖请求 ===`);
    console.log(`时间戳: ${timestamp}`);
    console.log(`总UID数量: ${uids.length}`);
    console.log(`你的位置: 87n`);
    
    for(let uid of uids) {
        try {
            let response = await fetch('https://2025challenge.52pojie.cn/api/lottery/join', {
                method'POST',
                headers: {'Content-Type''application/json'},
                bodyJSON.stringify({
                    "timestamp": timestamp,
                    "uid": uid,
                    "verify_code": code
                })
            });
            const textResponse = await response.text();
            try {
                console.log(`UID ${uid}:`JSON.parse(textResponse));
            } catch(e) {
                console.log(`UID ${uid}:`, textResponse);
            }
            await new Promise(r => setTimeout(r, 100));  // 添加延迟避免请求过快
        } catch(e) {
            console.error(`Error submitting UID ${uid}:`, e.message);
        }
    }
    
    console.log("n=== 提交完成 ===");
}

joinMultiple();

然后就等开奖即可。这里之所以和实际不一样,是因为参与人数不一样也会导致中奖的序号不一样的。

例如我们将参与人数变动一下,范围为10230-10300,得出的中奖序号是一样的。

吾爱破解2025春节红包活动番外篇第三题

0x03总结

这道题的解题思路比较清晰:通过分析抽奖算法,发现中奖序号是由区块哈希值对参与总人数取模得到的。系统会自动添加 9980 个机器人账号,真实玩家的序号从 9980 开始。在后期分 IP 抽奖的调整下,不同 IP 之间互不干扰,这让解题变得更加可控。

解题步骤主要是:首先通过 API 获取指定区块的哈希值,然后遍历可能的参与总人数(比如 10000-10300),找到一个合适的总人数,使得计算出的中奖序号大于等于 9980。确定好参与总人数后,计算出自己需要在机器人之后的第几个位置(中奖序号减去 9980),然后将自己的 UID 放在这个位置,其他位置用虚假 UID 填充。最后等待开奖即可获得 flag。

原文始发于微信公众号(猎户攻防实验室):吾爱破解2025春节红包活动番外篇第三题

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月14日08:45:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   吾爱破解2025春节红包活动番外篇第三题http://cn-sec.com/archives/3739151.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息