上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖
楼主: rogerxavier - 

哥哥救命,这个sign加密是wasm的怎么破

[复制链接]

该用户从未签到

1

主题

1

回帖

4

积分

助理工程师

积分
4
发表于 昨天 15:15 | 显示全部楼层 | 阅读模式
悬赏20油猫币未解决

先上代码

// ==UserScript==
// @name         solcat
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Simulate a POST request to the Solcat API
// @author       Your Name
// @match        https://solcat.game/*
// @match        https://api.solcat.game/*
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// @run-at       document-start
// @connect      api.solcat.game
// ==/UserScript==

 const payload = {
        event: "update",
        score: 204,
        coins: 80,
        gameSpeed: 1.112620234488441,
        usingResurrectionPowerUp: 0
    };
(function() {
    'use strict';

    // 保存原始的fetch函数
    let oldFetch = window.fetch;
     // 示例调用

    // 劫持fetch函数
    function hookFetch(...args) {
        return new Promise((resolve, reject) => {
            // 检查请求的URL是否匹配
            if (args.length > 0) {
                let url = args[0] instanceof Request ? args[0].url : args[0];
                console.log("触发了fetch请求:", url);

                //检测是否是get score fetch
                if(url === 'https://api.solcat.game/v1/game/'+unsafeWindow.sessionId){
                    console.log('获取到get score,下面打印参数');
                    console.log(args);
                    console.log(args[1].headers);
                    debugger;
                    // 调用函数
                    sendGameUpdateRequest(payload,args[1].headers);
                    // 不调用oldFetch,直接resolve
                    resolve(new Response(null, { status: 200, statusText: 'OK', url })); // 或者根据需要构造一个假的响应

                }

                // 检查是否有onProgress回调
                if (args[1] && args[1].onProgress) {
                    console.log("检测到onProgress回调");
                }
            }

            // 调用原始的fetch函数
            oldFetch.apply(window, args).then((response) => {
                // 打印响应的URL
                console.log("响应来自:", response.url);

                // 克隆响应对象以便可以多次读取
                let clonedResponse = response.clone();

                // 检查响应是否可读(状态码200-299)
                if (response.ok) {
                    clonedResponse.json().then((result) => {
                        console.log("返回数据:", result);
                        // 检查返回数据中是否有sessionId
                        if (result.data && result.data.sessionId) {
                            // 将sessionId记录到window对象下
                            unsafeWindow.sessionId = result.data.sessionId; // 记录sessionId
                            console.log("已记录sessionId:", unsafeWindow.sessionId);
                        }

                    }).catch((error) => {
                        console.log("解析JSON失败:", error);
                    });
                }
                // 将原始响应传递给resolve
                resolve(response);

            }).catch((error) => {
                // 将错误传递给reject
                console.log("fetch请求失败:", error);
                reject(error);
            });

        });
    }

    // 替换全局的fetch函数
    unsafeWindow.fetch = hookFetch; // 使用unsafeWindow确保在页面上下文中执行

    function sendGameUpdateRequest(payload,headers) {
        const url = "https://api.solcat.game/v1/game/"+unsafeWindow.sessionId;

        GM_xmlhttpRequest({
            method: "POST",
            url: url,
            headers: headers,
            data: JSON.stringify(payload),
            onload: function(response) {
                if (response.status === 200) {
                    const responseData = JSON.parse(response.responseText);
                    console.log("伪造getscore Response Data:", responseData);
                } else {
                    console.log("伪造getscore Request failed with status:", response.status);
                }
            },
            onerror: function(err) {
                console.log("Request error:", err);
            }
        });
    }

})();

这是一个solcat的游戏(类似神庙逃亡)的hook代码,每隔一段时间拾取金币会向v1/game/+sessionid的地址发送一个更新分数和金币的请求,类似这样的payload=》

{
    "event": "update",
    "score": 38,
    "coins": 4,
    "gameSpeed": 1.112620234489441,
    "usingResurrectionPowerUp": 0
}

,通过上述代码hook发现每次update的时候请求头中的sign都会变,不更新sign就会403,追踪到

function _JS_WebRequest_SetRequestHeader(requestId, header, value) {
            var requestOptions = wr.requests[requestId];
            if (!requestOptions) {
                return
            }
            var _header = UTF8ToString(header);
            var _value = UTF8ToString(value);
            requestOptions.init.headers[_header] = _value
        }

这个函数似乎是修改header中的sign的,但是看调用栈sign的算法好像和wasm有关 ,

"df": _JS_WebRequest_SetRequestHeader,     =》 framework.js中
df   call $a.df,     =》 wasm文件中

哥哥这个要怎么fetch这个wasm文件https://solcat.game/pc_v_4/Build/wasm来还原sign的算法呀

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5966

    回帖

    6763

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6763

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 昨天 18:06 | 显示全部楼层
    wasm的目前基本只是靠模拟
    可以侵入网页的特定部分来获得计算函数
    直接投数据得签名就好
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    1

    回帖

    4

    积分

    助理工程师

    积分
    4
    发表于 昨天 18:50 | 显示全部楼层
    可是哥哥这个算法好像是访问webassembly的内存视图HEAPU8,从里面获取的sign的信息,这个要怎么访问hook呀
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5966

    回帖

    6763

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6763

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 3 小时前 | 显示全部楼层
    rogerxavier 发表于 2024-11-22 18:50
    可是哥哥这个算法好像是访问webassembly的内存视图HEAPU8,从里面获取的sign的信息,这个要怎么访问hook呀
    ...

    明天我有空看一下
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表