[md]## ins 登录enc_password获取
目标网址 aHR0cHM6Ly93d3cuaW5zdGFncmFtLmNvbS8=
1. 抓包
POST https://www.instagram.com/accounts/login/ajax/
payload = {
enc_password: #PWD_INSTAGRAM_BROWSER:10:1650113230:AbFQAHOTPiX8WpL1YUGC0BzN/OPlUZ1+dKwhqoZxq5HMnEUFvVBDbStPcRuatPOPWm9EuIbm9JVqKJM0X6jLK0NEm+a5rRqgVA+tlJiIItdWknJeifUCzsY9ik/MaRNRQapCIFySa6SoSsqg
username: xxx@163.com
queryParams: {}
optIntoOneTap: false
stopDeletionNonce:
trustedDeviceRecords: {}
}
很容易看出来enc_password是一个加密后拼接起来的参数,他就是我们今天要找的加密参数。
2. 调试分析
- 全局搜索 enc_password
什么都没有,nothing,那换一个关键词试一下,PWD_INSTAGRAM_BROWSER是用来拼接字符串的,很可能会搜到,试一下
有了,点进去,格式化看一下,
这个地方好像是我们要找的地方,仔细看一下,下面还有用冒号拼接的字符串,和我们最终的结果很像。那就打个断点,调试一下。
这个就是最终的结果,开始搞他。进入到函数里面,继续打断点,调试
会找到这样一个函数, t是你的密码,c= n(); 看一下n函数,发现是一个10位数的时间戳,这里就可以想到最终的结果里面也有一个时间戳,应该就是这个了。进入到函数中打断点,调试。
到这里就能清晰地看到,获取了KeyId, PublicKey, Version,三个参数加上咱们传过来的 t(密码), n(时间戳),调用了encryptPassword(),继续跟进去查看。
在这里 t,c,n,o,s是我们上面传来的参数,u是o转成的byte数组,我这里有一个自用的方法str_to_utf8()
function strToUtf8(n) {
if ('string' != typeof n)
throw new TypeError('expected string');
var t, o = unescape(encodeURIComponent(n)), c = new Uint8Array(o.length);
for (t = 0; t < o.length; t++)
c[t] = o.charCodeAt(t);
return c
}
然后 y是经历一个加密函数得到的结果,最终return的结果应该是base64后的y 和 s, n进行一定格式的拼接。继续看y是怎么来的
y = await i(d[1]).encrypt(t, c, u, f);
这个y经历了这么多,一步一步的看吧,先是 u = o + h.length; 然后 const w = n(c); 接下来就到了 const y = new Uint8Array(u);
我们需要的y出现了,初始化一个u长度的无符号整型数组,然后第0位填1,第1位填s,然后索引f += 1,下面很明显的写着AES-GCM,有同学可能就觉得这只是一个通用的加密算法,我们找到key,iv不就可以了吗,但是这里不止这一个算法。
继续看,AES-GCM iv是空的12位无符号整形数组,还有一个additionalData(添加的数据) length:256 所以是aes-256-gcm算法,
这里有关于这个算法的详细信息 https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey
使用的也是window.crypto, node里面正好有相应可以使用的算法。继续往下看,经过aes加密的结果为o,然后 return Promise.all([n, o]) 继续下一步。
上一步的结果传到了n参数上面,通过t函数就获得了o的值,然后y的索引继续增加,y不断被更新,返回了最后生成的y,
现在的问题就是找t函数的逻辑,继续调试。
这里面又有三个新的函数 c = i(d[1]).box.keyPair(); var l = i(d[2])(c.publicKey, n) , o = i(d[1]).box(t, l, n, c.secretKey);
第一个c是生成publicKey和secretKey, 然后通过这两个key去生成下面两个参数。这个地方就跳过了,扣出相应的函数,就能跑了
看 l 的生成
这里面又看到了一个算法 blake2b, 也就是说 l 是 blake2b生成的,复制一下需要的js代码,就可以生成 l 了,这个不是用的官方的算法库,不知道有没有魔改,我就直接抠出来代码跑的。接下来看 o 参数的生成。
又是一个很规矩的函数,没有混淆,直接复制,o参数到这里就结束了。
最后把生成的 y数组 base64编码一下就获得了最后的结果,如下图,我用node改写的算法,获取的结果
和请求中的参数很像,放到登录程序中测试一下,
登陆成功,在测试一下,这个cookie好不好使
完美的获取到了数据。还要注意的地方就是ins后端是用django写的,所以post请求需要加上csrf_token,还有就是publickey,KeyId,Version 这几个参数的获取,因为他们会变的。
今天的分享就到这里了,这是我学习中的一次尝试,记录一下,有不对的地方希望大家可以指正。谢谢大家的浏览。