Facebook登录协议分析
分析登录请求参数

优先关注encpass和lgndim
| lgndim | eyJ3IjoyNTYwLCJoIjoxNDQwLCJhdyI6MjU2MCwiYWgiOjE0MDAsImMiOjI0fQ== | {"w":2560,"h":1440,"aw":2560,"ah":1400,"c":24} |
|---|---|---|
| encpass | #PWD_BROWSER:5:1659513194:AZNQANED7RG7mD6aA7... |
lgndim的base64编码ey开头基本都为json格式的base64后数据 , 直接使用atob进行解码 , 记录的是屏幕信息和色位
尝试追踪密码加密调用栈
1.尝试性全局搜索encpass字段

- 非常轻松找到赋值位置
- 尝试下断追踪加密函数
2.通过request原型的send追踪调用栈中的encpass字段
debug(XMLHttpRequest.prototype.send)拦截请求函数- 拦截失败 , 网页直接跳转并显示登录失败

- 这时候可以根据经验判断是通过form表单进行submit提交跳转
- 由此可以判断表单密码字段是实时加密
接下来尝试拦截html标签内容进行加密定位

- 表单中无密码字段 , 说明是通过点击按钮后生成一个input标签并进行submit操作


- 拦截后可以清晰看到
745行处进行插入input标签操作 - 接下来尝试追踪加密函数
分析加密函数调用位置
e = c("DOM").scry(h.loginForm, 'input[id="pass"]')[0]
g = Math.floor(Date.now() / 1e3).toString();
f.encryptPassword(d.keyId, d.publicKey, e.value, g)
| d.keyId | 147 | |
|---|---|---|
| d.publicKey | 38b94d0f9dd8b649c030620e261c583d97618b14aa09bf0ebf52b5b4ddfa5f3d | key |
| e.value | ccirE7L1bN | 密码 |
| g | 1659514608 | 10位时间戳 |
- 初步判断为hmac之类的签名算法
- 进入encryptPassword函数

- 一个简单的ast混淆控制流后的代码 , 对比shape与腾讯vm的分析要容易的太多
549行下断 , 确认各变量的内容
| f | 密码 |
|---|---|
| g | 时间戳 |
| j | 密码的utf8字节 |
| k | 时间戳的utf8字节 |
- 进一步深入encrypt函数分析过程

- 加密函数的控制流 , key为hex格式 , 从内容来看加密算法基本确认为aes-gcm格式
- 定位
501行代码处参数细节 - aes-gcm-256算法

- 附加数据为前文中的时间戳字节
- e为密码的字节
h.subtle.encrypt(w, a, e.buffer) Promise {<pending>}- 返回了一个promise对象 , 处于pending状态
- promise.all去返回处理结果 , 那么基本确认加密细节需要进一步深入
- 进入
h.subtle.encrypt函数 h.subtle.encrypt.toString() 'function encrypt() { [native code] }'- 无法进入 , 说明是浏览器自带的加密库 , 那么至此已经完成大部分工作内容
- 剩余部分手动调用标准库中的AES-GCM-256算法即可