js逆向实战-1号店登录接口参数逆向


声明

本文章中所有内容仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除!

目标

1号店登录接口
地址:aHR0cHMlM0EvL3Bhc3Nwb3J0LnloZC5jb20vcGFzc3BvcnQvbG9naW5faW5wdXQuZG8=

操作步骤

观察接口

在这里插入图片描述
通过观察我们发现,本次的目标是credentials.username、credentials.password、captchaToken。

credentials.username、credentials.password

全局搜索参数名

在这里插入图片描述
我们可以看到credentials.username、credentials.password都是一个加密方式得到的。
跟进这个加密
在这里插入图片描述
在这里插入图片描述
可以看出来其实就是RSA加密
熟悉的朋友很明显能看出来这个代码和jsencrypt库里的RSA几乎是一致的。
所以我们完全可以用·sencrypt这个库自己去实现用户名密码的加密。
但是这个publicKey怎么来的呢
通过搜索我们可以发现它在html页面的代码里
在这里插入图片描述

代码实现

接下来就是代码实现加密过程
如果没安装jsencrypt库,需要先安装

npm install jsencrypt

然后就是js代码

window = this;
var JSEncrypt = require("jsencrypt")
var pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXQG8rnxhslm+2f7Epu3bB0inrnCaTHhUQCYE+2X+qWQgcpn+Hvwyks3A67mvkIcyvV0ED3HFDf+ANoMWV1Ex56dKqOmSUmjrk7s5cjQeiIsxX7Q3hSzO61/kLpKNH+NE6iAPpm96Fg15rCjbm+5rR96DhLNG7zt2JgOd2o1wXkQIDAQAB"
var i = new JSEncrypt();
i.setPublicKey(pubkey);

var j = 13333333333
var k = 123456

j = i.encrypt(j);
k = i.encrypt(k);

console.log(j)
console.log(k)

运行结果
在这里插入图片描述

抠js代码实现

有小伙伴说了,我就想练练抠js代码!
没问题,马上安排!

首先,把关键代码复制下来

如下这段全复制下来
在这里插入图片描述
代码复制下来后,补环境只需要两个

window = this;
navigator = {};

最后加上我们要加密的代码

var k = '18812731329';
var j = 'qaZ123456!';
var pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXQG8rnxhslm+2f7Epu3bB0inrnCaTHhUQCYE+2X+qWQgcpn+Hvwyks3A67mvkIcyvV0ED3HFDf+ANoMWV1Ex56dKqOmSUmjrk7s5cjQeiIsxX7Q3hSzO61/kLpKNH+NE6iAPpm96Fg15rCjbm+5rR96DhLNG7zt2JgOd2o1wXkQIDAQAB";
var i = new JSEncrypt();
i.setPublicKey(pubkey);
j = i.encrypt(j);
k = i.encrypt(k);
console.log(j);
console.log('==================');
console.log(k);

接下来运行又报错了
在这里插入图片描述
只需要添加一行代码
在这里插入图片描述
这是因为其实这个对象上边已经实现了,但是上边定义为window.ASN1,所以这里在给引用一下
这里改了之后呢,又会有新的错误
TypeError: Cannot read properties of null (reading 'bitLength')
那我们在报错的地方打印一下这个bitLength的调用者
在这里插入图片描述
在这里插入图片描述
发现它是空的
这时候吧就不太好确定是哪里出问题了,因为这个代码很多的try…catch捕获的异常都没有打印
但可以初步判断是设置key的时候有问题
那直接在setPublicKey这里打断点进行debug调试
在这里插入图片描述

一直跟进到parseKey这个方法后发现了问题
在这里插入图片描述
在这里插入图片描述
查看这个异常的内容发现说是ReferenceError: Base64 is not defined
其实这个和那个ASN1的异常是一样的,所以这里直接改成window.Base64就可以了
在这里插入图片描述
到这里就没问题了
在这里插入图片描述

获取captchaToken

接下来就是captchaToken参数的获取了,我们把鼠标放到window.jab.getData()这个方法上,跟进去看这个方法
在这里插入图片描述
可以看到它定位的是下边这个方法
在这里插入图片描述
在这里插入图片描述
可以看到是this["c"][2]这个方法

继续跟进就能看到是这个ao
在这里插入图片描述

抠代码实现

我接下来采取的方法还是抠js代码
把整个js文件内容都复制下来
定义一个全局变量,让它等于ao
在这里插入图片描述
因为这个ao实在传参的第二个索引的方法里,所以要修改复制下来的文件最后传的参数
在这里插入图片描述
原始文件中是5,咱们要改成2
在这里插入图片描述
运行代码,环境该补的补,没啥难度,
如果报错:
TypeError: XMLHttpRequest is not a constructor
可以把与之相关的部分代码去掉,并不影响生成逻辑
还会报
TypeError: t is not a constructor
在这里插入图片描述
找到对应的地方
在这里插入图片描述

把这个new t()给替换一下,在浏览器控制到打印new t()
在这里插入图片描述
注意,应该在调试进ao[2]这个方法里边后再输出new t(),不然没有结果
在这里插入图片描述
只需要把代码里的new t()改成{withCredentials:false}即可
再次运行能输出结果了
在这里插入图片描述
但是我们发现这不对啊,明明应该是三部分拼接的啊
在这里插入图片描述
少了g[f[b("0x6c7", "]swn")]("_", "t")]
这个很容易发现其实就是window._t
关键是这个怎么生成的

hook一下window._t,(如果hook不到,那只能一步步跟栈了)可以发现是下边这地方生成的
在这里插入图片描述

一步步的往下跟栈,(过程真是枯燥)

在这里插入图片描述
在这里插入图片描述
控制台输出一下相应的变量
在这里插入图片描述
发现F就是cookie里的_s_id
可以把av的值固定下来,只替换里边的时间戳就可以了
在这里插入图片描述

就可以生成想要的值了

最后还要说一点,在运行这些之前,还运行了ao里边的第一个函数,也就是ak
在这里插入图片描述
因此我们的代码中需要先手动运行一下ak,至于它的传参,可以固定下来
在这里插入图片描述
打断点运行到ak里边,然后控制台输出一下ap
把内容复制下来

var ap = {
    "bizId": "PASSPORT_LOGIN",
    "initCaptcha": true,
    "apiServer": "//nocaptcha.jd.com",
    "staticServer": "//js-nocaptcha.jd.com",
    "jv": "20201218"
}
aaa[0](ap)
console.log(aaa[2]()) 

最后运行结果
1
至此 captchaToken的值也获取到了。

结论

抠js代码真是个枯燥乏味的活计,期间还各种报错,各种补环境,不过最终能成功,还是很欣慰的。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值