← 返回文章列表

Facebook登录协议分析

facebook

分析登录请求参数

优先关注encpasslgndim

lgndimeyJ3IjoyNTYwLCJoIjoxNDQwLCJhdyI6MjU2MCwiYWgiOjE0MDAsImMiOjI0fQ=={"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.keyId147
d.publicKey38b94d0f9dd8b649c030620e261c583d97618b14aa09bf0ebf52b5b4ddfa5f3dkey
e.valueccirE7L1bN密码
g165951460810位时间戳
  • 初步判断为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算法即可