超星考试pos参数破译

查看 56|回复 3
作者:李恒道   
FBI WARNING
这里的超星考试指本人的原创单机游戏【超级星星V.666】单词大考验关卡
并非通俗意义超星
请勿联想
感谢
感谢@涛之雨 大佬在我失业之后为我积极推荐工作,经过大佬的内推成功进入了美团送外卖
正文
点击考试预览可以追到AST部分这里可以看到是ob混淆+字符串转义


图片.png (105.5 KB, 下载次数: 0)
下载附件
2023-5-28 21:54 上传

我们先解决字符串转义部分
直接利用babel的最小化就可以将字符串转义压缩成正常字符串[JavaScript] 纯文本查看 复制代码const parser = require("@babel/parser");
const generator = require("@babel/generator").default;
const code_js = fs.readFileSync("./chaoxing_exam.js", {
  encoding: "utf-8",
});
const ast = parser.parse(code_js)
let code = generator(ast, {
  minified: true,
  jsescOption: { minimal: true },
}).code;
fs.writeFile("./convert1.js", code, (err) => {});
然后查看一下结果


图片.png (193.44 KB, 下载次数: 0)
下载附件
2023-5-28 21:55 上传

然后解字符串,这里是_0x56bc
直接抬手一个转义,因为没有多层,所以只处理_0x56bc即可
老规矩,复制_0x56bc到nodejs作为解密函数
首先测试一下,发现卡死了,多半是正则爆破,搜索Reg找了
[JavaScript] 纯文本查看 复制代码      _0x4337b4["prototype"]["RvZSqA"] = function () {
        var _0x403f16 = new RegExp(this["MTxJBI"] + this["FMdsHI"]);
        var _0x55e9af = _0x403f16["test"](this["ZxBleI"]["toString"]())
          ? --this["pNCgln"][1]
          : --this["pNCgln"][0];
        return this["AfmIcA"](_0x55e9af);
      };
      _0x4337b4["prototype"]["AfmIcA"] = function (_0x172353) {
        if (!Boolean(~_0x172353)) {
          return _0x172353;
        }
        return this["ebdBfN"](this["GRlANK"]);
      };
      _0x4337b4["prototype"]["ebdBfN"] = function (_0xa7fe72) {
        for (
          var _0x5f3bbf = 0, _0x1ed88a = this["pNCgln"]["length"];
          _0x5f3bbf
应该是正则下面的三元运算符在捣乱,我们跑一下发现是false,所以直接强制改成true内的--this["pNCgln"][1]
[JavaScript] 纯文本查看 复制代码     _0x4337b4["prototype"]["RvZSqA"] = function () {
        var _0x403f16 = new RegExp(this["MTxJBI"] + this["FMdsHI"]);
        var _0x55e9af = --this["pNCgln"][1]
        return this["AfmIcA"](_0x55e9af);
      };
在运行发现还是存在内存爆破
向上找到了字符串混淆内存在分支污染和内存爆破


图片.png (56.84 KB, 下载次数: 0)
下载附件
2023-5-28 21:56 上传

直接将第一个设为false,第二个设为true
再运行crp函数


图片.png (5.28 KB, 下载次数: 0)
下载附件
2023-5-28 21:56 上传

解密成功
然后直接开始解字符串混淆
[JavaScript] 纯文本查看 复制代码const fuck_js = fs.readFileSync("./convert2.js", {
  encoding: "utf-8",
});
const ast = parser.parse(fuck_js);
traverse(ast, {
  CallExpression(path) {
    if (path.node.callee.name === "_0x56bc") {
      let loc1 = path.node.arguments[0].value;
      let loc2 = path.node.arguments[1]?.value;
      let str_node = types.stringLiteral(_0x56bc(loc1, loc2));
      path.replaceInline(str_node);
    }
  },
});
let code = generator(ast, {
  minified: true,
  jsescOption: { minimal: true },
}).code;
fs.writeFile("./convert3.js", code, (err) => {});
已经具备基本的可读了


图片.png (131.72 KB, 下载次数: 0)
下载附件
2023-5-28 21:57 上传

接下来就是硬干了
我们目标比较简单


图片.png (163.36 KB, 下载次数: 0)
下载附件
2023-5-28 21:57 上传

分析这些数据吧
value像是鼠标的数据,我们先看value,确实是鼠标的相对页面键值
[JavaScript] 纯文本查看 复制代码    var scrollLeft =
        document["documentElement"]["scrollLeft"] ||
        document["body"]["scrollLeft"],
      scrollTop =
        document["documentElement"]["scrollTop"] ||
        document["body"]["scrollTop"];
    (mouseMap["x"] =
      winEvent["pageX"] || winEvent["clientX"] + scrollLeft),
      (mouseMap["y"] =
        winEvent["pageY"] || winEvent["clientY"] + scrollTop),
    var value =
      "(" +
      Math["ceil"](mouseMap["x"]) +
      "|" +
      Math["ceil"](mouseMap["y"]) +
      ")";
接下来看qid,取自页面的questionId数据
[JavaScript] 纯文本查看 复制代码 _0x210627 = document["getElementById"]("questionId"),
(qid = _0x210627["value"])
看rd,随机数
[JavaScript] 纯文本查看 复制代码var rd = Math["random"](),
接下来只剩enc和_edt了,先看enc
里面是一个闭包
看大概应该是一个转义字符代码,懒得搞了,直接抽离


图片.png (259.71 KB, 下载次数: 0)
下载附件
2023-5-28 21:58 上传

[JavaScript] 纯文本查看 复制代码function getEncData(posData, userId, questionId, randomNum, rd) {
  let userIdAndQuestionIdAndRandom =
    userId + "_" + questionId + "|" + randomNum;
  if (
    null == userIdAndQuestionIdAndRandom ||
    userIdAndQuestionIdAndRandom["length"]
官方数据


图片.png (72.68 KB, 下载次数: 0)
下载附件
2023-5-28 21:58 上传

抽离代码


图片.png (95.08 KB, 下载次数: 0)
下载附件
2023-5-28 21:59 上传

代码生成成功,然后看最后的_edt,来源是      "&_edt=" +
(_0x408603 + randomNumA),其中randomNumA是一个生成的随机数
[JavaScript] 纯文本查看 复制代码  function _0xe7b063() {
    if ("ySLJF" !== "ySLJF") {
      (function () {
        return ![];
      })
        ["constructor"]("debu" + "gger")
        ["apply"]("stateObject");
    } else {
      return Math["floor"](10 * Math["random"]());
    }
  }
而另外一个603的变量则是时间
[JavaScript] 纯文本查看 复制代码_0x408603 = "" + new Date()["getTime"](),
至此全部破译完毕
结语
撒花

下载次数, 代码

Rangon   

good
Stubborn6   

感谢分享
Asra   

学到了,感谢分享
您需要登录后才可以回帖 登录 | 立即注册

返回顶部