JS逆向实战25——某壳找房模拟登录+百度喵星人指纹加密破解.
声明
本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!
目标
目标网站
aHR0cHM6Ly9iai5rZS5jb20v
目标
获取登录列表中的 password
,loginTicketId
,srcId
抓包分析
我们对比两次抓包 (建议都使用无痕浏览器 或者是使用抓包软件)来看看这个请求参数
可以看到 如上图所示。有区别的分别是
- password
- context 字典中的值
- loginTicketId
这个context本文不做研究。我们把我们需要逆向的两组值拿出来。
// ==== 第一次请求 ====
"password": "FtvyGhja3uFP+aVoKUuUntFybn8/O4BoDGoNdfrfm2BAbZo3NXw0VliAhSE39jBiYbXH7kEMetiXEmSsO4WZEtU51uSkV3rrsPDYjuGk2SzEDzvTZ2iLpC8ghY0Na8xqZqA/CvFOrNR8DTdjeuPNur9+y4KQ5U1S+yQ08+38cng=",
"loginTicketId": "N33YL74DgakMzd3UDU2xml3OLxypILHf",
"srcId": "eyJ0Ijoie1wiZGF0YVwiOlwiMmFmNDE2MGViODlmZjY5MzYyYzhhYjYwZjk2M2U4OTVmNWY0YmZjN2U1NTE3NThlZGI3MDYzZDY2Y2JlZWVmYTRhZDJmZWVmYzgyZWQxMDg1ODJlODk1OGIzNDNmNDAxYTRjMzk5MzhlNmU1YThlZjc3YjhmY2E1MDU4ZGQ2ZTdmMGUyYjljMzViMTcxYTA4NzE5M2M4MmVkMjZmOTEwMWMyMjYxOTQ1ZGY1MWE0NDAxOGUyZDJiZWJlYTg3NDU4NGE0ZWVjZWRlZWFhZmZlNWU3NmU2ZjQ2YWFiMzgxODJjMzFmMDA3ZDFkODUxM2VmMmFhODBlZGZhN2ZlMzkyNVwiLFwia2V5X2lkXCI6XCIxXCIsXCJzaWduXCI6XCIwOTMzYjdiN1wifSIsInIiOiJodHRwczovL2JqLmtlLmNvbS8iLCJvcyI6IndlYiIsInYiOiIwLjEifQ==",
// ==== 第二次请求
"password": "MCHQCwLmp3O22OmWoIv1qvkRfTkkzGiZmHZnEDaTdgY0mLwD9Ve+XcsZYiT/i+8V4rB2j3JCF5kWUp8Hx/YNkiL6FuBO4MWujradjYkkv8WN92creehj+RnvXUKkLNe4vMXUWKSMxVM9kbq+OFOOWJAtc3tocLjqJlN7apvYtKs=",
"loginTicketId": "dagM7n2Hn8NNUJLemfLanH7MCk4wYYNz",
"srcId": "eyJ0Ijoie1wiZGF0YVwiOlwiMmFmNDE2MGViODlmZjY5MzYyYzhhYjYwZjk2M2U4OTVmNWY0YmZjN2U1NTE3NThlZGI3MDYzZDY2Y2JlZWVmYTRhZDJmZWVmYzgyZWQxMDg1ODJlODk1OGIzNDNmNDAxYTRjMzk5MzhlNmU1YThlZjc3YjhmY2E1MDU4ZGQ2ZTdmMGUyYjljMzViMTcxYTA4NzE5M2M4MmVkMjZmOTEwMWMyMjYxOTQ1ZGY1MWE0NDAxOGUyZDJiZWJlYTg3NDU4NGE0ZWVjZWRlZWFhZmZlNWU3NmU2ZjQ2YWFiMzgxODJjMzFmMDA3ZDFkODUxM2VmMmFhODBlZGZhN2ZlMzkyNVwiLFwia2V5X2lkXCI6XCIxXCIsXCJzaWduXCI6XCIwOTMzYjdiN1wifSIsInIiOiJodHRwczovL2JqLmtlLmNvbS8iLCJvcyI6IndlYiIsInYiOiIwLjEifQ==",
ps: 原值密码都是一样。
我们本文目标之一是弄出来这个srcId
由于有点像一个定值。看上去好欺负一点。所以我们先去搜这个srcId
srcId
直接搜索srcid即可
然后找到了这个生成的地方。是用base64 生成的。也确实这个值很像base64。我们执行下看看。
可以看到 和我们刚刚请求的值一模一样。
从第一张图我们看到
- t 有点像一个接口的返回值。
- n是当前页面的 URL 地址
- os和v是定值。
t的话。我们先跟栈看看
好的 跟了两个栈之后得到这个responseURL的值。那我们就可以通过请求这个地址得到这个t的值。那么这样的话所有的值都得到了。
我们可以改下一下JS 封装一下函数
window= global;
function get_srcID(t) {
srcId = window.btoa(JSON.stringify({
t: t, r: "https://bj.ke.com/", os: "web", v: "0.1"
})
)
return srcId
}
ps: 这个t值 所请求的连接为:https://miao.baidu.com/abdr 请求的请求负载加密为百度喵星人跟踪URL指纹加密。请看后续单独段落介绍
loginTicketId
搜索loginTicketID。发现这个值等于某个请求里的值。
很简单了。伪造请求,查看URL的值和t的值
请求就能得到loginTicketID
password
搜索跟栈 找到密码加密处
然后点击下一步
发现这里套了两层函数
第一层this.getKey().encrypt(t)
得到了一个hex的值。
得到最终加密的值
然后我们进函数看
发现都是给t这个原型链赋值函数
然后我们就发现这是个webpack。那其实这样就简单了。不需要扣太多代码。把加载器搞出来。后面按照webpack的方式扣。直接调用最外层的o.ec.encrypt(t.password)
这个函数即可。
步骤如下:
- 定义全局变量
- 把这个o.ec赋值给全局变量
- 最下面调用这个全局变量.encrypt
那现在的目标就很明确了 找一下这个o.ec 在哪里开始定义的。
搜索**.ec**
** 找到new 声明函数的位置**
然后我们就可以进行改写了
既然得到了大体流程。我们就可以進行調試了 再次之前 需要找到加密的模块在哪个函数里。方便我们在结果中调用。
我们直接在随便一个调用n的地方打上断点。然后输入 n.m
这样所有的模块下标与模块就都显示出来了。
然后我们用查询模糊字符串索引的方式 返回函数下标
代码如下:
n.m.forEach(function(func,index) {
if (func.toString().indexOf('o.ec.encrypt(t.password)')!=-1){
console.log(index)
}
})
结果如下:
然后我们输入
去复制这个函数。然后丢到webpack的模块中。然后一个一个顺着补就可以了
扣代码
复制加载器。把索引为53的模块 复制到文件中就可以开始补了
window = global;
!function(n) {
var r = {};
function i(t) {
if (r[t])
return r[t].exports;
var e = r[t] = {
i: t,
l: !1,
exports: {}
};
console.log(t)
return n[t].call(e.exports, e, e.exports, i),
e.l = !0,
e.exports
}
...
window.bk = i
}(
{
53:...
....
}
);
window.bk(53).default()
报错 : window is not defined
补上
window = global;
报错:navigator is not defined
补上
navigator = {
appName:"Netscape"
}
补到51位会跳出个 window.location.href未定义
补上
window.location= {
href:'https://bj.ke.com/'
}
这里补环境的参数基本只有这些。
后面就是扣webpack 。篇幅问题就不讲了。
等扣到最后 会报一个 t.services 未定义。
不用管。直接把这些未定义的全部注释掉就可以了。
然后我们定义一个全局变量复制给this.ec
如下图所示。
然后我们调用这个函数即可。
window.bk(53).default()
console.log(window.zx.encrypt("admin*123"))
结果
最后成功出值。我们放到代码中运行下看看
可以看到 这里返回给我们的值是密码校验失败。说明直接调用这个还是不对。我们重新去网站中跟着栈走一遍 看看。
然后我们跟栈 初始化
——密码加密
发现有这么一段代码。
在请求xxx/authentication/authenticate 的函数的时候。还返回了一个公钥。需要传给js。所以才执行不成功。
**PS: 其实这里公钥可以写死,但是为了防止公钥改变。我这里用的请求里的公钥。
然后重新请求。发现请求成功了。
百度miao URL 指纹加密
上文留了个小坑: srcId这个值。我们最后用的其实是一串定值。
而这串值怎么来的呢? 是请求https://miao.baidu.com/abdr这个地址得来。
那我们去找这个请求。
然后一看。这玩意好像是百度做广告用的推广URL。把这个请求负载有点像base64.我们进行base64
解码看看。
这个token用base64解码后,有两个字段,分别是"key_id"和“data”。
好 这个我们暂且不管。直接去看栈,然后跟栈去请求。
一步一步跟栈(真的跟的很辛苦)得到下文这个参数的地方
然后继续往下走
得到了这些提交的参数。可以看到。这些提交的参数。就是一些浏览器指纹。还有一些乱七八糟的信息。然后搅和在一起做的计算。
这里我使用的是补环境的方式。直接用挂上proxy代理。然后把T的值传进去就行了。
也可以用扣代码,也算是相对简单的。感兴趣可以自己扣一下
结果
依然能请求成功!!
对了 感兴趣的小伙伴 可以关注下我的微信公众号