
百家网站(上上上)
更新: 2025/2/24 字数: 0 字 时长: 0 分钟
本章节将展示针对100家网站进行逆向的过程。
有道翻译
题目难度:简单
有道翻译网站地址:https://fanyi.youdao.com/
有道翻译是网易公司开发的一款翻译软件,其最大特色在于翻译引擎是基于搜索引擎,网络释义的,也就是说它所翻译的词释义都是来自网络。
首先我们输入一个词“逆向”,通过Chrome自带的开发者工具抓取数据包,在Network(网络部分)的Fetch/XHR选项筛选出返回内容的数据包,在Response部分可以看到返回的结果。
切换到header部分,比较两次相同内容的请求,发现Request Headers参数没有什么变化,但POST有三个参数有变化:
salt: 16303966363048
sign: a5ede67eabd2c6a8b06975b09e2c5a6b
lts: 1630396636304
可以看到 salt
和 lts
参数差不多,有爬虫经验的人,第一直觉就是时间戳,因为这个两个参数随着时间在不断的变大,而且数值和时间戳类似,确保万一取数值的前10位进行验证一下:
看来时间戳猜想基本正确,**一般来说,网络上使用时间戳都会精确到毫秒。这里可以进行下一步确定,lts
参数是精确到毫秒的13位时间戳,salt
参数就是13位时间戳加1个未知参数。**现在我们未知参数就剩下 sign
参数和 salt
最后一位参数。我们全局搜索一下 salt
的名称:
发现就在一个js文件中出现了 salt
的名称,点击进入,跳转到Sources选项中查看 fanyi.min.js
文件,文件中所有的代码都在一行,点击下方的 {}
按钮进行代码格式化:
出现了 fanyi.min.js:formatted
这就是将 fanyi.min.js
文件中js代码格式化后的结果:
继续在文件中搜索 salt
名称,共有12处匹配,经过比对,在8979行找到了和POST参数最为接近的代码:
点击8988行处打上断点,点击翻译,代码运行卡在断点处,里面显示许多我们要使用的参数及来源:
通过观察可得出 salt
、sign
、lts
、bv
参数与js代码中的 r
参数关系密切,查看 r
参数就在上方面,构造也很简单,就是一个 v
类调用了 generateSaltSign()
方法传入了参数 n
,即翻译的内容“逆向”。选中方法名称,提示来自于8383行,点击位置跳转。:
在8393行打上断点,点击翻译,断点卡住,绝大部分的参数都显示了内容,再将未知参数在Console控制台直接打印出来,所有的参数基本都豁然开朗了:
到这里就可以对参数做一个总结了:
r = {
ts: 时间戳,
bv: 浏览器user-agent的md5哈希,
salt: 时间戳 + 0到9随机取整,
sign: "fanyideskweb" + (查询的内容) + (字符串类型的时间戳 + 0到9随机取整) + "Y2FYu%TNSbMCxc3t2u^XT"的md5哈希
}
i: 动态值(查询的内容)
from: 默认值“AUTO”(被翻译的语言类型)
to: 默认值“AUTO”(翻译结果的语言类型)
smartresult: 固定值“dict”
client: 固定值“fanyideskweb”
salt: r参数.salt
sign: r参数.sign
lts: r参数.ts
bv: r参数.bv
doctype: 固定值“json”
version: 固定值“2.1”
keyfrom: 固定值“fanyi.web”
action: 固定值“FY_BY_CLICKBUTTION“
?> 提示:参数中使用了md5哈希,这里我已经验证过是标准的md5,因此可以直接调用Python中的第三方库hashlib来实现md5哈希。
百度翻译
题目难度:简单
百度翻译依托互联网数据资源和自然语言处理技术优势,致力于帮助用户跨越语言鸿沟,方便快捷地获取信息和服务。支持全球200多个语言互译,包括中文(简体)、英语、日语等,覆盖4万多个翻译方向,通过开放平台支持超过40万企业和个人开发者,是国内市场份额第一的翻译类产品。
首先我们打开地址,检查cookie,在通过逐个排查发现cookie中没有 BAIDUID
字段的话会再次刷新获取:
而获取的方式,就在我们清空cookie刷新的第一次请求当中:
接下来通过几次变换词语,点击翻译后,抓到v2transapi?from=zh&to=en这条接口地址,可以看到Form Data表单,其中除了sign和token以及query(待翻译字符)外其余参数可以设置为固定值。
首先我们来解决token,通过全局搜索发现,token第一次被赋值就出现在最开始的第二次请求当中,而搜索下面有行注释引人注目,就是没有cookie的话,是不会返回token的,这也就解释了为什么最开始会有两次请求:第一次请求就是获取cookie,第二次请求需要带上cookie来获取token。
经过测试成功获取token,说明前面的逻辑完全正确:
接下来搜索sign看看是否能找到加密入口:
找到单独的sign高亮,且有赋值的过程,在可疑点上打断点:
接下来再次点击翻译,看到断点停到了7045行处,细心一点的朋友可以看到token也在这里:
sign:f(n)
这里sign是就是 f(n)
函数的返回值,n看上面有调试信息 n = "兔子"
,看看 f()
函数的内容:
进入e函数后看到如下代码块:
现在将e函数拷贝下来,进行输出,发现报错 i 未定义:
先看这段代码:u = null !== i ? i : (i = window[l] || “”) || “”;
大致意思就是 u=i=window[l]
,经过几次调试发现 window[l]
是一个固定值320305.131321201,所以我们可以直接添加一个定义 i = 320305.131321201
变量:
我们再次运行js代码,提示n未定义:
我们返回网页看看,提示n是一个外部引入的函数:
进入n函数:
将n函数的代码拷贝下来运行,正常输出结果:
新榜查询
题目难度:简单
地址:https://newrank.cn/public/info/search.html?value=gzyxgzyx&isBind=false
新榜是上海看榜信息科技有限公司旗下的一款产品。
首先,访问地址,在搜索框随便输入一个关键词进行查询,定位到相关请求:由于该接口查询一次会产生6次接口,返回6个不同的响应,且参数都大体相同,我们这里就拿返回数据最多的WeixinData接口,经过几次测试改变的参数主要有三个。
keyName: 查询关键词
nonce: 加密参数
xyz: 加密参数
点击Initiator选项卡,跳过上面常规的jquery文件开头,直接点击第三个,进行跳转:
跳转后,可以看到是发送的ajax请求的 data
数据部分的值是 l
,而上面有 l = k.objParameter;
这个关系,我们在Console输出 k.objParameter
的值,发现就是我们post传递的参数,再上面又有 k = g(a, d)
这个关系,其中a就是接口的后半段 /xdnphb/data/weixinuser/searchWeixinDataByCondition
的值,d就是一个对象 {keyName: '关键词', order: 'relation', filter: '', hasDeal: 'false'}
的值,现在重点关注的就是 g()
函数的生成逻辑了。
选中 g()
函数出现来源,点击进行跳转:
跳转后,重点观察 g()
函数最后返回值的逻辑,发现参数 nonce
的值来源于 j()
函数的返回值,变量 h
的值就是一个固定的字符串加上 nonce
的值,即 '/xdnphb/data/weixinuser/searchWeixinDataByCondition?AppKey=joker&filter=&hasDeal=false&keyName=qq&order=relation&nonce=加上nonce的值'
,参数 xyz
的值来源于 d(h)
返回值,在下面输出了该值和post传递的 xyz
的值长度一样:
到这里,其实分析就结束了,后面就是把d函数的代码抠下来,补上运行中缺失的函数和变量,最后经过优化的js代码并不长,可以直接放入爬虫当中。
微信公众平台
题目难度:简单
微信公众平台,简称公众号。
首先访问网站,输入账号和密码均为 [email protected]
,点击登录,定位发送登录的请求,关键参数如下:
username: 账号
pwd: 加密参数
imgcode:
f: json
userlang: zh_CN
redirect_url:
token:
lang: zh_CN
ajax: 1
点击Initiator选项,观察发现有一个_loginPost,和我们定位发送登录的请求相符,点击跳转:
跳转后,发现有一个pwd参数,打上断点调试,和Post发送的pwd的值相同,而pwd的值就是 f(密码)
函数的返回值:
选中 f()
函数,展示来源,点击跳转:
跳转后,发现是调用的是md5哈希算法里面的一个函数,其中参数(e, t, n)分别是(密码,undefined,undefined)的值:
和线上哈希后的数值一比对,发现一样,说明是标准的MD5哈希:
房天下登录
题目难度:简单
地址:https://passport.fang.com/?backurl=https%3A%2F%2Fwww.fang.com%2Fdefault.htm
房天下是房地产家居行业专业网络平台,1999年由莫天全先生创立,一直专注于新房、二手房、租房、家居、房地产研究等领域的互联网创新,为全球24个国家,658个城市提供服务,房天下APP累计装机量超2亿,在移动技术、产品、推广方面全面布局,锁定了移动领域的优势地位。2010年9月,房天下在美国纽交所上市。
首先我们访问房天下的登录地址,选择账号密码登录,输入账号:13588888888, 输入密码:88888888,点击登录,回看XHR中的请求所发送的表单信息:
uid: 账号
pwd: 加密参数
Service: soufun-passport-web(可能为固定值)
AutoLogin: 1(可能为固定值)
点击Initiator,点send跳转到发送该ajax请求的地方:
在该处打上断点,重新点击登录,断点卡住,看Call Stack(调用堆栈),忽略jquery常规文件,直接点击第三个 loginClickFn
进行跳转:
跳转后,我们在登录注释下面data中看到了和表单一样的数据结构,可以看到pwd的值是 encryptedString(key_to_encode, that.password.val())
的返回值,现在我们在pwd行打上断点,重新登录:
断点过来后,选中 that.password.val()
发现就是密码本身:
选中 key_to_encode
发现是通过调用RSAKeyPair方法得到的一个对象:
我们全局搜索一下这个RSAKeyPair方法,发现第二个有个function很明显就是该方法,点击跳转,该方法就完整的展示我们面前了,仔细观察该方法,需要传入三个参数才能返回对象,而我们上面选中 key_to_encode
就已经是一个对象了,也就是已经完成了三个参数的传递了,那么是哪里生成了这个对象呢?图中最下面的 new RSAKeyPair
给了我们灵感:
点击跳转到 new RSAKeyPair
位置,给我们完整的展示了该对象的生成的所需参数:
最后剩下一个参数了,选中 encryptedString
是一个函数,点击进行跳转:
跳转后,就是 encryptedString
函数的完整方法了,扣下来补充缺失的变量和方法,再用一个函数包装一下:
黑猫投诉平台
难度:简单
网站地址:https://tousu.sina.com.cn/
黑猫投诉是新浪旗下的消费者服务平台,用户可以通过该平台投诉商家的不规范行为,同时还有企业信誉榜单,以帮助消费者进行消费行为抉择参考。2018年3月14日,微博和新浪网联合举办以“共建消费新生态”为主题的3·15论坛,双方联合推出的消费者服务平台黑猫投诉正式上线。首先,访问平台,输入关键词“游戏”进行搜索,找到网页内容的请求:
请求头中无关键加密字段,查看请求参数发现有三个关键字段:
我们全局搜索一下 signature
字段,只有在一个文件中出现,我们在这个文件中继续搜索该关键字,发现有9处,其中有一处刚好包含上面的三个关键字段,我们在此处打上断点:
刷新后,我们在控制打印相关信息,发现这个位置就是我们要找的接口,对应关系如下:
r = u([l, p, b, h, c, d["type" + e]].sort().join(""));
ts = l
rs = p
signature = r
在上面,我们找到了所有的参数:
在控制台进行打印,最后得到如下关键字对应关系:
// 时间戳
ts = 1686410750729;
// p函数返回的随机16个字符
rs = 'AyKy4kcdsIc5yjFH';
// u函数返回64个字符:7b3bd12aa9450c61d3e9d907b8476849ae0c649fd9cd3ef4ab46a823565b680a
signature = u('$d6eb7ff91ee257475%1101686410750729AyKy4kcdsIc5yjFH游戏');
可以看到 u
函数返回64个字符,这个长度就需要引起注意了,因为SHA256哈希算法的返回值就是64个字符,现在我们将字符串拿到线上加密,发现结果一模一样,说明 u
函数的功能就是SHA256哈希。
最后的爬虫效果如下: