当前位置: 首页 > news >正文

某某航空 同盾 blackbox 补环境

文章目录

    • 概要
    • 整体架构流程
    • 技术细节
    • 小结

概要

提示:仅供学习,不得用做商业交易,如有侵权请及时联系

逆向:某某航空 同盾 blackbox 补环境

URL:aHR0cHM6Ly9wYXNzcG9ydC5qdW5leWFvYWlyLmNvbS8=

目标:blackbox参数

整体架构流程

提示:分析流程

1、登录接口:blackbox值

在这里插入图片描述
验证码为鸡眼3

2、通过堆栈找到该值生成的地方:

在这里插入图片描述
在这里插入图片描述
进一步搜索该值生成的地方:
在这里插入图片描述
3、断住该位置,重新初始化加载(刷新页面):
在这里插入图片描述
在这里插入图片描述

该接口加载返回url:aHR0cHM6Ly9mcC50b25nZHVuLm5ldC93ZWIzXzgvcHJvZmlsZS5qc29u
js:fm.js文件生成

4、补环境:

  1. 挂代理,补环境
dtavm = {}
dtavm.log = console.log
function proxy(obj, objname, type) {
    function getMethodHandler(WatchName, target_obj) {
        let methodhandler = {
            apply(target, thisArg, argArray) {
                if (this.target_obj) {
                    thisArg = this.target_obj
                }
                let result = Reflect.apply(target, thisArg, argArray)
                if (target.name !== "toString") {
                    if (target.name === "addEventListener") {
                        dtavm.log(`调用者 => [${WatchName}] 函数名 => [${target.name}], 传参 => [${argArray[0]}], 结果 => [${result}].`)
                    } else if (WatchName === "window.console") {
                    } else {
                        dtavm.log(`调用者 => [${WatchName}] 函数名 => [${target.name}], 传参 => [${argArray}], 结果 => [${result}].`)
                    }
                } else {
                    dtavm.log(`调用者 => [${WatchName}] 函数名 => [${target.name}], 传参 => [${argArray}], 结果 => [${result}].`)
                }
                return result
            },
            construct(target, argArray, newTarget) {
                var result = Reflect.construct(target, argArray, newTarget)
                dtavm.log(`调用者 => [${WatchName}] 构造函数名 => [${target.name}], 传参 => [${argArray}], 结果 => [${(result)}].`)
                return result;
            }
        }
        methodhandler.target_obj = target_obj
        return methodhandler
    }

    function getObjhandler(WatchName) {
        let handler = {
            get(target, propKey, receiver) {
                let result = target[propKey]
                if (result instanceof Object) {
                    if (typeof result === "function") {
                        dtavm.log(`调用者 => [${WatchName}] 获取属性名 => [${propKey}] , 是个函数`)
                        return new Proxy(result, getMethodHandler(WatchName, target))
                    } else {
                        dtavm.log(`调用者 => [${WatchName}] 获取属性名 => [${propKey}], 结果 => [${(result)}]`);
                        if (`${propKey}` === 'top') {
                            return window
                        }
                        if (`${propKey}` === 'self') {
                            return self
                        }
                    }
                    return new Proxy(result, getObjhandler(`${WatchName}.${propKey}`))
                }
                if (typeof (propKey) !== "symbol") {
                    dtavm.log(`调用者 => [${WatchName}] 获取属性名 => [${propKey?.description ?? propKey}], 结果 => [${result}]`);
                }
                return result;
            },
            set(target, propKey, value, receiver) {
                if (value instanceof Object) {
                    dtavm.log(`调用者 => [${WatchName}] 设置属性名 => [${propKey}], 值为 => [${(value)}]`);
                } else {
                    dtavm.log(`调用者 => [${WatchName}] 设置属性名 => [${propKey}], 值为 => [${value}]`);
                }
                return Reflect.set(target, propKey, value, receiver);
            },
            has(target, propKey) {
                var result = Reflect.has(target, propKey);
                dtavm.log(`针对in操作符的代理has=> [${WatchName}] 有无属性名 => [${propKey}], 结果 => [${result}]`)
                return result;
            },
            deleteProperty(target, propKey) {
                var result = Reflect.deleteProperty(target, propKey);
                dtavm.log(`拦截属性delete => [${WatchName}] 删除属性名 => [${propKey}], 结果 => [${result}]`)
                return result;
            },
            defineProperty(target, propKey, attributes) {
                var result = Reflect.defineProperty(target, propKey, attributes);
                dtavm.log(`拦截对象define操作 => [${WatchName}] 待检索属性名 => [${propKey.toString()}] 属性描述 => [${(attributes)}], 结果 => [${result}]`)
                // debugger
                return result
            },
            getPrototypeOf(target) {
                var result = Reflect.getPrototypeOf(target)
                dtavm.log(`被代理的目标对象 => [${WatchName}] 代理结果 => [${(result)}]`)
                return result;
            },
            setPrototypeOf(target, proto) {
                dtavm.log(`被拦截的目标对象 => [${WatchName}] 对象新原型==> [${(proto)}]`)
                return Reflect.setPrototypeOf(target, proto);
            },
            preventcExtensions(target) {
                dtavm.log(`方法用于设置preventcExtensions => [${WatchName}] 防止扩展`)
                return Reflect.preventcExtensions(target);
            },
            isExtensible(target) {
                var result = Reflect.isExtensible(target)
                dtavm.log(`拦截对对象的isExtensible() => [${WatchName}] isExtensible, 返回值==> [${result}]`)
                return result;
            },
        }
        return handler;
    }

    if (type === "method") {
        return new Proxy(obj, getMethodHandler(objname, obj));
    }
    return new Proxy(obj, getObjhandler(objname));
}
  1. 提前加载的window属性:_fmOpt
window._fmOpt = {
    partner: 'jxhk',
    appName: 'jxhk_web',
    token: 'jxhk' + "-" + new Date().getTime() + "-" + Math.random().toString(16).substr(2),
    fmb: true,
    success: function (data) {
        _blackbox = data
    },
    fpHost: "https://fp.xxx.net"
};

3.接口生成的地方:document.createElement会创建一个script标签,然后赋值src链接,最后得到刚刚我们看到的接口并响应得到

_1743586336088_9724({
    "code": "000",
    "result": {
        "tokenId": "xxx",
        "xxid": "xx/xxx+8nEJGtj+fM4QZmvqCvcMiy/EdGYN4=",
        "xdid": "xx",
        "bxid": "MfgjSjjxV//xx==",
        "c": {
            "factor": 0,
            "op": 0,
            "cm": 0,
            "vt": 604800
        }
    },
    "desc": ""
})

4._1743586336088_9724这个在fm文件中已经被重写成了一个方法,最后允许该方法生成blackbox

//script创建的标签
Object.defineProperty(script, 'src', {
    set: function (value) {
        if (value != undefined) {
            fetch(value).then(function (response) {
                return response.text();
            }).then(function (text) {
                console.log('profile.json响应结果:',text)
                eval(text);
            })
        }
    }
})

5.eval执行之后在window._fmOpt.success得到我们需要的_blackbox

技术细节

提示:结果

最后,看结果吧!

在这里插入图片描述

这里说一下,作者最近开了星球,主要以补环境为主,欢迎各位的加入,咱们一起学习交流~

小结

提示:学习交流+v看主页(可加知识星球)

http://www.dtcms.com/a/107579.html

相关文章:

  • 华为云数据库服务实践
  • 如何解决跨系统审批慢、人工干预多的问题?
  • es自定义ik分词器中文词库实现热更新
  • Elasticsearch 证书问题解决
  • 基于pycharm的YOLOv11模型训练方法
  • mac 最新的chrome版本配置selenium的方式
  • React 文件上传新玩法:Aliyun OSS 加持的智能上传组件
  • d202542
  • 架构师面试(二十五):分布式存储 Leader 设计
  • 元素定位-cssSelector
  • SSM框架学习(Day-1)
  • Kubernetes 入门篇之 Node 安装与部署
  • 视频分析设备平台EasyCVR视频结构化AI智能分析:筑牢校园阳光考场远程监控网
  • 基于 Cesium.js 的交互式绘图工具库
  • IO 端口与 IO 内存
  • 电流与电压的守护者
  • 3. 矩阵置零
  • Vue + Axios + Mock.js 全链路实操:从封装到数据模拟的深度解析
  • 两种方法证明r(A+B)<=r(A,B)<=r(A)+r(B)
  • 【一起来学kubernetes】33、Hpa使用详解
  • 常见操作系统特点及区别对比
  • 双翌闪耀2025上海机器视觉展,以创新技术赋能产业未来
  • C++中的继承
  • P2782 友好城市
  • 私有云(三)双节点部署openstack
  • 自学-C语言-基础-数组、函数、指针、结构体和共同体、文件
  • 111.在 Vue 3 中使用 OpenLayers 实现动态曲线流动图(类似 ECharts 迁徙状态)
  • 从代码学习深度学习 - 残差网络(ResNet)PyTorch版
  • MSVC编译遇到C2059、C2143、C2059、C2365、C2059等错误的解决方案
  • 打开pycharm显示编制索引后卡死