twitter协议分析x-client-transaction-id

最近在爬取twitter推出的grok3时发现接口对x-client-transaction-id做了校验,遂对生成代码逆向了一波,具体步骤包含了(ps:官方加密代码有两个版本一个是chrome86版本,一个是最新版本,本次逆向为旧版本,新版本会在下一期发出)

1 入口

首先我们全局搜索x-client-transaction-id,可以清晰的看到o.headers["x-client-transaction-id"] = d.sent就是生成的结果,在此处下断可以看到d是一个对象,它的arg/sent/_sent都是目标结果,逆着call stack往上推,最终在这个函数不断循环

function n(t, r, e, n, o, i, a{
    try {
        var u = t[i](a)
          , c = u.value
    } catch (l) {
        return void e(l)
    }
    u.done ? r(c) : Promise.resolve(c).then(n, o)
}

Promise.resolve(c).then(n, o)会将c转换为一个Promise,并为其注册一个回调函数.then(n, o),如果成功则调用n函数失败调用o函数。u = t[i](a)这段代码中t是一个生成器,会不断的从中取出Promise来获取其返回值。如果不理清这一段代码那么后面的定位将及其困难,因为你会发现断点一直在此处来回调用。
既然我们已经知道了现在有n个Promise放在生成器管道中,那我们就只需要追踪其中一个,进入到生成器代码中,找到var l = h(r, e, n);这个变量就是生成Promise的位置,展开l的arg属性是一个Promise,我们进到源码位置(ondemand.s文件)打上断点,发现arguments就是请求接口名加上请求方式,如此可以猜到加密入参可能包含这两个参数,在继续往下走 又回到了ondemand.s文件,此时就需要注意加密入口可能就在这个文件,代码都是混淆后的,极其难看,但也要硬着头皮大致看一下,然后我们会发现一个熟悉的return n.t15 = n.sent,sent属性就是我们上面提到的,发现这段代码包含在switch case语句中,是通过n对象的next属性来决定跳到哪里,我们打下断点,断下来后发现结果就在此处。

2 补js环境

找到了入口就成功了一半,接下来我们把ondemand.s文件整个copy下来放到nodejs环境中。由于在浏览器中有完整的环境所以转到nodejs后我们还需要把浏览器的环境也补齐。这里引入jsdom库,它是用于在 Node.js 中模拟浏览器的子集功能,以便在无真实浏览器环境下运行前端代码和脚本,在运行代码以前先把这一步做了。解决完这些还不够,浏览器中不同的js脚本之间互相引用,在执行到我们这一步之前已经做了太多工作,我们不可能把这些错综复杂的关系都补上,所以现在我们直接运行这段js代码,根据报错来补充环境。

2.1 入口函数暴露

观察这段代码的入口发现是放在一个很深的嵌套函数中,那怎么在最外部能调用到呢?首先这个代码是一个webpak,可以直接把主要函数体拿出来放入我们自定义的一个函数__dd中,然后再观察入口函数发现它其实是通过一层一层的函数中return出来的,那这就简单了我们直接把最外层的函数return出来即可。

var __obj = __dd[0][358387]({id: 358387, exports: {}, loaded: false}, new Object(), function () {
    console.info(arguments);
});

这样我们就拿到了目标函数,其接受两个参数第一个为接口名,第二个为请求方式,我们运行一下发现返回的还是一个函数,该函数接受一个对象,此时很多小伙伴可能已经不知道咋办了,这个对象该如何去造。此时我们就需要同步去浏览器执行该代码,查看该函数传入的对象并保存到我们的nodejs代码中。其实这种方式是我们补环境的核心,有时候发现我们计算出来的结果和浏览器中不一致就经常会使用这种方式来定位问题。对象造好后,我们直接执行

var __result = __obj()("/2/grok/add_response.json", "POST")({delegate:null, done:false, method:"next", next:0, prev:3});

2.2 jsdom添加HTML内容

执行到这一步我们迎来了第一个问题:TypeError: Cannot read properties of undefined (reading 'childNodes'),可以清晰的看出这一步是在操作html,但是我们在nodejs环境中怎么能操作html呢?答案是可以的,在我们创建jsdom对象时可以给其传入一个模拟的html文本,我们回到浏览器刷新页面将返回的html整体复制过来注入到jsdom
const dom = new JSDOM('<!DOCTYPE html><html...然后在执行就发现没有触发该错误了。
a = nu[O("O@a6", 0, 0, -it)](pu)打断点,我们发现该函数返回的是一个Uint8数组,该数组值非常重要,我们计算出来的值无法请求通接口原因之一就是它造成的

  • 进入函数内部 Gu(Lu(iu(tu(0, 1556, 0, "sWuS") + vu(663, 0, "^Q]f"))[0], tu(0, 1428, 0, "S(!W") + "nt")),这个代码的混淆方式是通过 tuvu函数来加密字符串的,我们手动还原一下: Gu(Lu(iu("[name^=tw]")[0], "content"))
    iu函数中使用css选择器提取html中 name^=tw的元素值即 twitter-site-verification元素的值。取到值后进入Gu函数生成uin8数组
Gu = function(n) {
  return new fu(atob(n)[ju(948, "YJOw", 808, 963, 902)]("")[tu(0, 1383, 0, "OIXL")]((function(n) {
    return n[tu(0, 1530, 0, "9I@S") + Qu(-416, 0, 0, 0, "O@a6")](0)
  })))
}
// 还原之后
Gu = function(n) {
    return new fu(atob(n)["split"]("")["map"]((function(n) {
        return n["charCodeAt"](0)
    })))
}
  • SVG计算:通过还原后可以知道这段代码读取了SVG元素的值,然后进行处理提取该字符串中的所有数字存入一个数组中
Ku = function(n, t) {
  return Wu = Wu || Lu(Ju(iu(n))[t[5] % 4][ju(1104, "h^1P", 1124, 1169, 1180) + Fu("U#NX", 1018, 1120, 1240, 1094)][0][Qu(-309, 0, 0, 0, ")]6W") + Fu("YP6T", 947, 1056, 1052, 1037)][1], "d")[tu(0, 1571, 0, "S(!W") + ju(894, "cAs@", 843, 784, 1013)](9)[vu(441, 0, "ky]N")]("C")[Fu("!&pV", 1133, 1181, 1278, 1110)]((function(n) {
    return n[vu(517, 0, "U#NX") + "ce"](/[^\d]+/g, " ")[vu(486, 0, "9B[1")]()[Fu("10I8", 1001, 1015, 951, 902)](" ")[Qu(-316, 0, 0, 0, "^ShB")](ou)
  }))
}
// 还原之后
Ku = function(n, t) {
  return Wu = Wu || Lu(Ju(iu(n))[t[5] % 4]["childNodes"][0]["childNodes"][1], "d")["substring"](9)["split"]("C")["map"]((function(n) {
    return n["replace"](/[^\d]+/g, " ")["trim"]()["split"](" ")["map"](ou)
        }
    ))
}

从这里我们可以体会到还原之后代码可读性提高了很多,稍后会继续介绍代码还原操作。

3 Animate实现

我们补环境到这里已经基本完成,我们直接运行代码发现可以拿到计算得到的结果,但是这个值并不能过接口监测,这是为什么呢?而且程序也没有报错,在这个代码中一定有缺少的某些环境并没有以报错的形式体现出来。我们通过nodejs环境和浏览器环境step by step调试,最终发现是由于jsdom缺少animate函数导致最终生成的结果为假结果。

3.1 源码解析

首先定位到入口并反混淆后:var O = n["animate"](nu["aPbXX"](Mu, t), 4096);,其中nu["aPbXX"]函数会返回三个值分别是color、transform、easing,这三个值的计算和之前计算的SVG的值对应,计算后的结果会通过animate函数进行渲染,生成动画,紧接着会马上暂停动画,通过回溯一个固定时间点来计算该时间点的颜色以及旋转角度,最终生成类似{matrix:'matrix(0.986112,0.166080,-0.166080,0.986112,0,0)',color:'rgb(34, 94, 214)'}

3.2 实现Animate

入参:

{
    color: ["#2060d5", "#532aef"],
    transform: ["rotate(0deg)", "rotate(316deg)"],
    easing: "cubic-bezier(0.53,0.85,0.93,-0.89)"}

结果:

{
  matrix: "matrix(0.986112, 0.166080, -0.166080, 0.986112, 0, 0)",
  color: "rgb(34, 94, 214)"
}

easing描述的是贝塞尔缓动函数的四个入参,其用于将动画的线性进度值t∈[0,1]\\映射到非线性进度值,以实现更自然的加速、减速效果,也就是说颜色的渐变以及角度的转换都需要遵循这一规律。如此我们便可以自实现或通过三方库实现动画并提取关键帧的模态,如此我们便可以通过纯代码伪造来过掉其检测点

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8429757097d24c9a953f680cab14d944.jpeg#pic_center)
03-11
<think>嗯,用户想了解如何配置和使用yum源。首先,我需要回忆一下关于yum源的基本知识。记得yum源是软件仓库,用来管理RPM包的安装和依赖关系。配置yum源通常涉及编辑.repo文件,这些文件位于/etc/yum.repos.d/目录下。还有可能涉及到本地源和网络源的配置。 根据用户提供的引用内容,引用[2]提到yum的配置文件分为main和repository部分,main在/etc/yum.conf,而repository在/etc/yum.repos.d/里的各个文件。所以配置的时候需要关注这两个部分。用户可能遇到的问题包括如何创建新的源文件,如何指向本地或网络路径,以及如何处理GPG检查。 用户的问题可能包括步骤不清晰,比如如何挂载ISO镜像来配置本地源。引用[3]中提到了创建local.repo文件,并指定baseurl为file:///路径。这时候需要确保挂载点正确,并且权限设置没问题。另外,可能需要禁用默认的网络源,避免冲突。 用户还可能关心如何测试配置后的yum源是否生效,比如运行yum clean all和yum makecache。此外,常见问题如无法找到包,可能和baseurl的配置错误有关,或者网络源不可达。需要检查URL是否正确,网络连接是否正常。 可能还需要解释不同的源类型,比如本地、网络(如阿里云、清华源),以及如何备份原有的配置文件,避免出错后恢复。引用[1]提到可以将默认文件移到/opt下或重命名,这样可以禁用默认源,避免干扰。 总结下来,回答的结构应该分步骤,包括备份、创建repo文件、配置内容、清理缓存,然后验证。同时,常见问题部分需要列出可能的问题和解决方法,如GPG检查、路径错误等。还要注意使用正确的格式,行内变量用$符号,独立公式用$$,不过这里可能数学公式不多,但需要确保LaTeX正确。</think>### 如何配置和使用yum源? #### 一、yum源的核心配置方法 1. **备份默认源** 操作前建议备份系统原有源配置: ```bash mv /etc/yum.repos.d/*.repo /opt/backup/ # 将默认源文件移动到备份目录 ``` 这是为了防止原有配置与新配置产生冲突[^1]。 2. **本地yum源配置** - **挂载镜像文件** 将CentOS镜像文件挂载到指定目录: ```bash mount -o loop /path/to/CentOS-ISO /mnt/cdrom ``` - **创建配置文件** 新建`/etc/yum.repos.d/local.repo`并写入: ```ini [local-base] name=Local-CentOS-Base baseurl=file:///mnt/cdrom gpgcheck=0 enabled=1 ``` 关键参数说明: - `baseurl`:本地路径使用`file://`协议头[^3] - `gpgcheck=0`表示跳过数字签名验证 3. **网络yum源配置** 以阿里云源为例,创建`/etc/yum.repos.d/aliyun.repo`: ```ini [aliyun-base] name=Aliyun-CentOS-Base baseurl=https://mirrors.aliyun.com/centos/$releasever/os/$basearch/ gpgcheck=1 gpgkey=https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 enabled=1 ``` 注意:`$releasever`和`$basearch`会自动解析为系统版本和架构[^2] #### 二、关键操作命令 1. **清理缓存并更新** ```bash yum clean all # 清除旧缓存 yum makecache # 生成新缓存 yum repolist all # 验证源状态 ``` 2. **典型使用场景** ```bash yum install httpd -y # 安装软件包 yum update # 更新所有软件 yum search python3 # 搜索软件包 ``` #### 三、常见问题排查 | 问题现象 | 解决方案 | |---------|----------| | `Could not resolve host` | 检查网络连接和`baseurl`地址 | | `Package not found` | 确认仓库是否包含该软件包版本 | | GPG签名校验失败 | 设置`gpgcheck=0`或导入正确密钥 | #### 四、进阶配置技巧 1. **多源优先级控制** 安装`yum-plugin-priorities`插件,在`.repo`文件中添加: ```ini priority=1 # 数字越小优先级越高 ``` 2. **仓库分组管理** 通过`[epel]`、`[docker]`等独立仓库配置实现分类管理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值