Incapsula(reese84)逆向分析

本教程仅限于学术探讨,也没有专门针对某个网站而编写,禁止用于非法用途、商业活动、恶意滥用技术等,否则后果自负。观看则同意此约定。如有侵权,请告知删除,谢谢!

目录

概要

2.开始分析第一个接口

3.分析第二个接口

小结


概要

本期逆向网站:aHR0cHM6Ly9zcG9ydHMuc3BvcnRzLTE4OC5jb20vZXJyb3IvZm9yYmlkZGVuP3M9QUVFQUFH

Incapsula 是 Imperva 的反机器人。它有两种模式,即验证码非侵入模式和验证码模式。前者最容易通过,而后者则不怕发出更多禁令。

Incapsula 提供的文件本质上是动态的,部分原因是它们改变了编码函数,使其与前一个函数略有不同,因此每次重新加载都会产生不同的编码函数。这在用于reese84有效负载的编码函数和用于对 cookie 进行编码的编码函数中很明显___utmvc。

reese84此 cookie 尤其包含使用简单xorshift128算法编码的指纹。除此之外,reese84有效负载中的每个键值对都使用一系列ForWhile循环进行编码,这些循环以动态顺序对字节进行打乱、复制、克隆或重新排列。

本次逆向网站是没有 ___utmvc 的,所有这个文件省掉了,这个文件的加密也不是很难可以看看其它博主的文章。

逆向分析流程

1.分析下逆向的接口

第一个请求接口不难看出是一个加密用的JS文件代码

 第二个请求呢就是加密的表单了蛤

2.开始分析第一个接口

1.JS代码拿到node中,第一自执行呢就是加密函数了,我这里就不AST反混淆了,因为文件都是动态的,反混淆亦或者不反混淆都大差不差了

2.代码直接搜索 aih 这个就是他的加密表单其中一部分内容了

3.然后我们的加密入口代码可以写成这样的,剩下的慢慢补环境了

const copyPaste = require('copy-paste');
const CryptoJS = require('crypto-js');

(async () => {
    try {
        function calculateSha1(word) {
            return CryptoJS.SHA1(word).toString();
        }

        new Promise((resolve, reject) => {
                let date = new Date().getTime();
                let data = {
                    "aih": "5lgxcYvyAkiyhyh/pg/bwqpv4eD+Np4gRja9b6L/lps=",
                    "t": {
                        "marks": {
                            "total": date,
                            "interrogation": date + parseInt(Math.random() * 100000)
                        },
                        "measures": {
                            "interrogation": 162
                        },
                        start: () => {
                            // console.log("start: ", arguments);
                        }
                        ,
                        startInternal: () => {
                            // console.log("startInternal: ", arguments);
                        }
                        ,
                        stop: () => {
                            // console.log("stop: ", arguments);
                        }
                        ,
                        stopInternal: () => {
                            // console.log("stopInternal: ", arguments);
                        }
                        ,
                        summary: () => {
                            // console.log("summary: ", arguments);
                        }
                    },
                    "at": 1,
                    "sic": 1,
                    "slc": 4,
                    "s": calculateSha1,
                    "gcs": [],
                    "slt": date
                };

                new window.reese84interrogator(data).interrogate(resolve, reject);
            }
        ).then(data => {
                data = JSON.stringify(data);
                copyPaste.copy(data, function () {
                    console.log('加密表单已复制到粘贴板:', data);
                });
            }
        ).catch(e => {
            console.log("出现异常 --> ", e);
        })
    } catch (err) {
        console.error(err);
    }
})();

4.然后就用我们经典的补环境代理了 Proxy与Reflect 然后怎么办?当然由你们慢慢补咯!

function detectionEnv(proxy_name_array, out_call = true, out_fault = true) {
    require('colors');
    const beautify = require("js-beautify");

    const createHandler = ({obj_name, env_path = undefined, env_value = undefined}) => {
        const handler = {
            get: function (target, property, receiver) {
                const value = Reflect.get(target, property, receiver);
                // 如果是symbol就直接返回
                try {
                    if (typeof property === 'symbol') {
                        return value
                    }
                } catch (e) {
                    console.log(`1.${e}`, property);
                }

                // 拼接路径
                let envPath = "";
                try {
                    envPath = `${env_path || obj_name}.${property}`;
                } catch (e) {
                    console.log(`2.${e}`, property, property === Symbol.toStringTag);
                }

                // 递归判断
                try {
                    if (typeof value === 'object' && value !== null && value !== undefined) {
                        const env_path_tag = envPath.split(".").pop();
                        if (out_call && propertyPath.exists(envPath) && env_value && env_path_tag === property) {
                            console.log(`方法:get  |  1.调用环境方法:${envPath}  |  属性:${property}  |  属性类型:${typeof property}  |  属性值类型:${typeof value}`.green);
                        }

                        envPath !== "" && propertyPath.set("get", envPath)
                        // 递归调用
                        return createHandler({obj_name: value, env_path: envPath, env_value: obj_name});
                    }
                } catch (e) {
                    console.log(`3.${e}`, property);
                }

                // 日志输出
                try {
                    if (propertyPath.exists("get", envPath)) {
                        if (out_fault && value === undefined) {
                            console.log(`方法:get  |  1.缺失环境方法:${envPath}  |  属性:${property}  |  属性类型:${typeof property}  |  属性值类型:${typeof value}`.red);
                        } else {
                            out_call && console.log(`方法:get  |  2.调用环境方法:${envPath}  |  属性:${property}  |  属性类型:${typeof property}  |  属性值类型:${typeof value}`.cyan);
                        }
                    }
                } catch (e) {
                    console.log(`3.${e}`, property);
                }

                envPath !== "" && propertyPath.set("get", envPath)
                return value;
            },

            set: function (target, property, value, receiver) {
                console.log(`方法:set    对象:${obj_name}    属性:${property}    属性类型:${typeof property}    属性值类型:${typeof value}`.blue);
                return Reflect.set(target, property, value, receiver);
            },

            deleteProperty: function (target, propKey) {
                console.log(`方法:deleteProperty    |    删除属性:${propKey}`.yellow);
                return Reflect.deleteProperty(target, propKey);
            },

            apply: function (target, thisArg, argumentsList) {
                console.log(`方法:apply    |    调用函数:${target.name || 'anonymous'}`.yellow);
                return Reflect.apply(target, thisArg, argumentsList);
            },

            construct: function (target, argumentsList, newTarget) {
                console.log(`方法:construct    |    构造函数:${target.name || 'anonymous'}`.yellow);
                return Reflect.construct(target, argumentsList, newTarget);
            },

            defineProperty: function (target, property, descriptor) {
                console.log(`方法:defineProperty    |    定义属性:${property}`.yellow);
                return Reflect.defineProperty(target, property, descriptor);
            },

            getOwnPropertyDescriptor: function (target, property) {
                console.log(`方法:getOwnPropertyDescriptor    |    获取属性描述符:${property}`.yellow);
                return Reflect.getOwnPropertyDescriptor(target, property);
            },

            getPrototypeOf: function (target) {
                console.log(`方法:getPrototypeOf    |    获取原型`.yellow);
                return Reflect.getPrototypeOf(target);
            },

            setPrototypeOf: function (target, prototype) {
                console.log(`方法:setPrototypeOf    |    设置原型${prototype}`.yellow);
                return Reflect.setPrototypeOf(target, prototype);
            },

            isExtensible: function (target) {
                console.log(`方法:isExtensible    |    检查是否可扩展`.yellow);
                return Reflect.isExtensible(target);
            },

            preventExtensions: function (target) {
                console.log(`方法:preventExtensions    |    阻止扩展`.yellow);
                return Reflect.preventExtensions(target);
            },

            has: function (target, property) {
                console.log(`方法:has    |    检查属性是否存在:${property}`.yellow);
                return Reflect.has(target, property);
            },

            ownKeys: function (target) {
                console.log(`方法:ownKeys    |    获取自身属性键`.yellow);
                return Reflect.ownKeys(target);
            }
        };

        if (env_path === undefined) {
            let handlerString = "{" + Object.entries(handler).map(([key, value]) => {
                return `${key}: ${value.toString()}`
            }).join(",\n") + "}";
            handlerString = beautify(handlerString, {indent_size: 2, space_in_empty_paren: true});

            const name = obj_name.toUpperCase() === "window".toUpperCase() ? "global" : "Object.create({})"
            // 开始代理
            return eval(`
                try {
                    ${obj_name} = new Proxy(${obj_name}, ${handlerString});
                } catch (e) {
                    console.log(("未定义 " + obj_name + " 默认赋值为: ${name}").red);
                    ${obj_name} = new Proxy(${name}, ${handlerString});
                }`);
        }

        // 递归
        return new Proxy(obj_name, handler);
    }

    const propertyPath = new class {
        constructor() {
            this.PropertyPath = new Map();
        }

        exists(key, property_path) {
            let property_path_set = this.get(key);
            return !property_path_set.has(property_path);
        }

        get(key) {
            let property_path_set = this.PropertyPath.get(key.toLowerCase());
            if (!property_path_set) {
                property_path_set = new Set();
            }
            return property_path_set;
        }

        set(key, property_path) {
            let property_path_set = this.get(key);
            property_path_set.add(property_path);
            this.PropertyPath.set(key.toLowerCase(), property_path_set);
        }
    }
    proxy_name_array.forEach(obj_name => createHandler({obj_name: obj_name}));
}
const proxy_array = [
    "baseSelector.hqrW1", "baseSelector.footerText", "baseSelector.xnSV0", "baseSelector.frHelperLoopLink",
    "alert", "window", "body", "document", "history", "getContext", "localStorage", "location", "navigator", "sessionStorage", "XMLHttpRequest",
    "WebSocket", "requestAnimationFrame", "getElementsByTagName", "getElementsByClassName",
    "cancelAnimationFrame", "addEventListener", "removeEventListener", "dispatchEvent", "FileReader", "Worker",
    "SharedWorker", "AudioContext", "WebGLRenderingContext", "WebGL2RenderingContext", "Audio", "Video", "Image",
    "indexedDB", "canvas", "screen"
];
detectionEnv(proxy_array, true, true);

 5.我自己也尝试过还原算法,但是呢,需要正则的东西太多了就放弃了,不信邪的小伙伴可以试试,当然肯定也有大佬还原了纯算法,反正我是不行(狗头保命)

3.分析第二个接口

1.然后分析第二个接口看看,反正我第一眼看到的时候,是两个头都大的

2.然后cookies里面还有一个 ___utmvc 这个网站的是不用的,所以我们就不逆向它了,这个比起interrogation简单多了,感兴趣的自己研究下吧

 3.然后开始用上面的代理,去补环境吧,然后自己慢慢补了两千多行,肝了一周环境,也是累人的一天蛤!

小结

然后我们看下成品效果如何吧!这个网站的reese84,如果你返回的长度是544,那么恭喜你风控绕过了,理论上搞定一个网站都是通用的,这边也是成功爬到数据的,本期逆向结束了,铁子别卷太猛,小心肾透支哦!

Reese84 算法通常指的是一种用于图像处理的技术,特别是在音频信号的增强、降噪以及恢复方面有着广泛的应用。它是由一个名为 Reese 的研究者在一系列论文中提出的,具体指的是针对某些特定类型的噪声环境下的信号处理算法。 在实际应用中,Reese84 算法的核心思想是对输入的信号进行分析,识别并去除干扰部分,同时保留或增强原始信号的信息。这一过程可能涉及到频域分析、滤波操作等技术手段,目的是为了提高音频质量或增强特定信息。 对于具体的算法步骤,由于 Reeseman 或该算法的具体细节并未在公开文献中有详细的描述,所以很难提供精确的操作流程。然而,一般来说,这类算法可能会包括以下几个基本步骤: 1. **信号预处理**:首先对输入信号进行预处理,如采样、标准化等,确保数据适合后续的算法处理。 2. **特征提取**:从信号中提取关键特征,比如频率成分、能量分布等。这一步骤有助于理解和区分信号的不同部分。 3. **噪声分析与分离**:利用统计模型或机器学习方法来分析和识别噪声模式,并将其从信号中分离出来。 4. **信号修复**:基于对信号的理解,针对性地修正或替换已经分析出的噪声部分。 5. **结果合成**:将处理后的信号片段重新组合成完整的、更高质量的输出信号。 6. **后处理**:最后可能还包括进一步优化音质的过程,比如调整均衡、消除剩余杂音等。 请注意,尽管 Reese84 算法可能在特定领域内有其独特的贡献和用途,但它并非是最广为人知或最常用的音频信号处理技术之一。对于更普遍的音频处理需求,如降噪、音效增强等,可能存在更为成熟且广泛应用的算法和技术,例如基于深度学习的端到端音频处理方法等。 -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值