JS逆向之BackTest入门滑块与表单加密

news2024/9/25 23:20:00

声明:本文仅限学习交流使用,禁止用于非法用途、商业活动等。否则后果自负。如有侵权,请告知删除,谢谢!本教程也没有专门针对某个网站而编写,单纯的技术研究

一、本期逆向

1.网站:aHR0cDovL2JhY2t0ZXN0LjEwanFrYS5jb20uY24vYmFja3Rlc3QvYXBwLmh0bWwjL215c3RyYXRlZ3k=
ojbk,点击登录就是滑块很好,妙啊

2.先看下有哪些加密,获取滑块的接口勒直接拿没加密

3.验证滑块的时候勒有前一步还有一个getGS的接口

看下表单也就一个uname是加密的

crnd看着有点像随机的字符串

4.接下来看下提交登录了,登录这一块该说不说还挺牛逼。。。

uname、passwd、passwdSalt总共三个参数

5.看看getTicket滑块校验,明文没啥好说的直接提交

6.最后校验的时候还发现了一个 hexin-v,这个校验了时间,好了开始盘它

 二、getGS分析

1.果然crnd是个随机数,固定就好不管它了,uname就是个rsa的加密,啊这,就这

 

2.照着还原一下代码咯,就这样吧,下一个搞滑块

import rsa
import math


class Hex2B64:
    base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    hexChars = "0123456789abcdefghijklmnopqrstuvwxyz"
    __doc__ = """
    用法示例:
    HB = Hex2B64()
    rt = HB.encrypt("5555")
    print(rt)
    print(HB.decrypt(rt))

    对应的Javascript代码👇
    base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    hexChars = "0123456789abcdefghijklmnopqrstuvwxyz";
    const hex2b64 = (d) => {
        let a = '', i = 0;
        for (; i + 3 <= d.length; i += 3) {
            a += base64Chars.charAt(parseInt(d.substring(i, i + 3), 16) >> 6) + base64Chars.charAt(parseInt(d.substring(i, i + 3), 16) & 63);
        }

        if (i + 1 === d.length) {
            a += base64Chars.charAt(parseInt(d.substring(i, i + 1), 16) << 2);
        } else if (i + 2 === d.length) {
            a += base64Chars.charAt(parseInt(d.substring(i, i + 2), 16) >> 2) + base64Chars.charAt((parseInt(d.substring(i, i + 2), 16) & 3) << 4);
        }

        return a.padEnd(Math.ceil(a.length / 4) * 4, '=');
    };
    const b64tohex = (b64) => {
        let hex = "", bits = 0, bitsCount = 0;

        for (let i = 0, len = b64.length; i < len && b64[i] !== "="; ++i) {
            const charIndex = base64Chars.indexOf(b64[i]);
            if (charIndex < 0) continue;

            if (bitsCount === 0) {
                hex += hexChars[charIndex >> 2];
                bits = charIndex & 3;
            } else if (bitsCount === 1) {
                hex += hexChars[(bits << 2) | (charIndex >> 4)];
                bits = charIndex & 15;
            } else if (bitsCount === 2) {
                hex += hexChars[bits] + hexChars[charIndex >> 2];
                bits = charIndex & 3;
            } else {
                hex += hexChars[(bits << 2) | (charIndex >> 4)] + hexChars[charIndex & 15];
                bits = 0;
            }
            bitsCount++;
        }

        return hex + (bitsCount === 1 ? hexChars[bits << 2] : "");
    }

    console.log(hex2b64('5555'));
    console.log(b64tohex("VVU="));
    """

    def encrypt(self, cipher_text: str) -> str:
        """

        @param cipher_text: 密文
        @return:
        """
        new_cipher_text, idx = '', 0
        for idx in range(0, len(cipher_text), 3):
            if idx + 3 > len(cipher_text):
                break
            new_cipher_text += self.base64Chars[trans(int(cipher_text[idx: idx + 3], 16) >> 6)] + self.base64Chars[trans(int(cipher_text[idx: idx + 3], 16) & 63)]

        if idx + 1 == len(cipher_text):
            new_cipher_text += self.base64Chars[trans(int(cipher_text[idx: idx + 1], 16) << 2)]

        elif idx + 2 == len(cipher_text):
            new_cipher_text += self.base64Chars[trans(int(cipher_text[idx: idx + 2], 16) >> 2)] + self.base64Chars[trans(trans(int(cipher_text[idx: idx + 2], 16) & 3) << 4)]

        return new_cipher_text.ljust(math.ceil(len(new_cipher_text) / 4) * 4, '=')

    def decrypt(self, cipher_text: str) -> str:
        """

        @param cipher_text: 密文
        @return:
        """
        new_cipher_text, bits, bits_count = "", 0, 0
        for i in range(len(cipher_text)):
            if cipher_text[i] == "=":
                break

            char_index = self.base64Chars.find(cipher_text[i])
            if char_index < 0:
                continue

            if bits_count == 0:
                new_cipher_text += self.hexChars[trans(char_index >> 2)]
                bits = trans(char_index & 3)

            elif bits_count == 1:
                new_cipher_text += self.hexChars[trans(trans(bits << 2) | trans(char_index >> 4))]
                bits = trans(char_index & 15)

            elif bits_count == 2:
                new_cipher_text += self.hexChars[bits] + self.hexChars[trans(char_index >> 2)]
                bits = trans(char_index & 3)

            else:
                new_cipher_text += self.hexChars[trans(trans(bits << 2) | trans(char_index >> 4))] + self.hexChars[trans(char_index & 15)]
                bits = 0
            bits_count += 1
        return new_cipher_text + (self.hexChars[trans(bits << 2)] if bits_count == 1 else "")


def public_encrypt(cipher_text: str, public: str, key_size: str) -> rsa.encrypt:
    return rsa.encrypt(cipher_text.encode(), rsa.PublicKey(int(public, 16), int(key_size, 16)))

三、dologinreturnjson2登录滑块及表单分析

1.继续跟进、好家伙备注都不删除,点个赞

 2.简简单单还原下登录的加密吧,用的加密还挺多:md5、sha256、hmac_sha256

import hashlib


def Hashlib(cipher_text: str, model="md5") -> str:
    """
    hashlib 加密
    @param cipher_text:
    @param model:
    @return:
    """
    if hasattr(hashlib, model.lower()):
        return getattr(hashlib, model)(cipher_text.encode()).hexdigest()
    raise Exception("模块不存在...")
let encoder = new TextEncoder("utf-8"), DEFAULT_STATE = [], ROUND_CONSTANTS = [], n = 2, nPrime = 0;

while (nPrime < 64) {
    let isPrime = true;
    for (let factor = 2; factor <= n / 2; factor++) {
        if (n % factor === 0) {
            isPrime = false;
        }
    }
    if (isPrime) {
        if (nPrime < 8) {
            DEFAULT_STATE[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
        }
        ROUND_CONSTANTS[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
        nPrime++;
    }
    n++;
}

function getFractionalBits(n) {
    return ((n - (n | 0)) * Math.pow(2, 32)) | 0;
}

function convertEndian(word) {
    return (word >>> 24) | (((word >>> 16) & 255) << 8) | ((word & 65280) << 8) | (word << 24);
}

function rightRotate(word, bits) {
    return (word >>> bits) | (word << (32 - bits));
}

function hmac(data) {
    let STATE = DEFAULT_STATE.slice(), length = data.length, bitLength = length * 8,
        newBitLength = (512 - ((bitLength + 64) % 512) - 1) + bitLength + 65, round, MRound, M = new Uint32Array(64),
        bytes = new Uint8Array(newBitLength / 8), words = new Uint32Array(bytes.buffer);

    bytes.set(data, 0);
    bytes[length] = 128;
    words[words.length - 1] = convertEndian(bitLength);
    for (let block = 0; block < newBitLength / 32; block += 16) {
        let workingState = STATE.slice();
        for (round = 0; round < 64; round++) {
            if (round < 16) {
                MRound = convertEndian(words[block + round]);
            } else {
                let gamma0x = M[round - 15], gamma1x = M[round - 2];
                MRound = M[round - 7] + M[round - 16] + (rightRotate(gamma0x, 7) ^ rightRotate(gamma0x, 18) ^ (gamma0x >>> 3)) + (rightRotate(gamma1x, 17) ^ rightRotate(gamma1x, 19) ^ (gamma1x >>> 10));
            }

            M[round] = MRound |= 0;
            let t1 = (rightRotate(workingState[4], 6) ^ rightRotate(workingState[4], 11) ^ rightRotate(workingState[4], 25)) + ((workingState[4] & workingState[5]) ^ (~workingState[4] & workingState[6])) + workingState[7] + MRound + ROUND_CONSTANTS[round],
                t2 = (rightRotate(workingState[0], 2) ^ rightRotate(workingState[0], 13) ^ rightRotate(workingState[0], 22)) + ((workingState[0] & workingState[1]) ^ (workingState[2] & (workingState[0] ^ workingState[1])));

            for (let i = 7; i > 0; i--) {
                workingState[i] = workingState[i - 1];
            }
            workingState[0] = (t1 + t2) | 0;
            workingState[4] = (workingState[4] + t1) | 0;
        }
        for (round = 0; round < 8; round++) {
            STATE[round] = (STATE[round] + workingState[round]) | 0;
        }
    }

    return new Uint8Array(new Uint32Array(STATE.map(function (val) {
        return convertEndian(val)
    })).buffer);
}

function hmac_sha256(inputKey, inputData) {
    inputKey = typeof inputKey === "string" ? encoder.encode(inputKey) : inputKey;
    inputData = typeof inputData === "string" ? encoder.encode(inputData) : inputData;
    if (inputKey.length > 64)
        inputKey = hmac(inputKey);

    if (inputKey.length < 64) {
        const tmp = new Uint8Array(64);
        tmp.set(inputKey, 0);
        inputKey = tmp;
    }

    let inherentKey = new Uint8Array(64), outpointKey = new Uint8Array(64),
        msg = new Uint8Array(inputData.length + 64), result = new Uint8Array(64 + 32);
    for (let i = 0; i < 64; i++) {
        inherentKey[i] = 54 ^ inputKey[i];
        outpointKey[i] = 92 ^ inputKey[i];
    }
    msg.set(inherentKey, 0);
    msg.set(inputData, 64);
    result.set(outpointKey, 0);
    result.set(hmac(msg), 64);
    return Array.prototype.map.call(hmac(result), byte => ('0' + parseInt(byte).toString(16)).slice(-2)).join('');
}


// console.log(hmac_sha256("kNJzKtvcGuRRnftcHVcP", "6512bd43d9caa6e02c990b0a82652dca"));

3.好了,看看滑块的搞了什么飞机,ok没啥玩意

 四、hexin-v的分析

这个勒找的时候有一点小坑,不过也没啥照着扣就行了,怎么找到的就自己找了

 五、结果

好了又水一篇文章~~

。。。。。。。。。

。。。。。。。。

。。。。。。

。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/367206.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

聊聊 HTAP 的前世今生

随着现代社会大型实时分析应用的逐渐流行&#xff0c;关系型数据库已经难以处理高并发的事务请求。商业层面上&#xff0c;当全球进入数字化时代&#xff0c;数字化技术渗透到各行各业&#xff0c;同时产生了海量数据&#xff0c;数据的存储和应用是企业决策的重要依据之一&…

计网数据链路层

第二层:数据链路层 数据链路层传输单位为帧 数据链路层三大问题&#xff1a;封装成帧&#xff0c;差错检测&#xff0c;可靠传输 两个协议&#xff1a; 共享式以太网的媒体接入控制协议CSMA/CD 802.11局域网的媒体接入控制协议CSMA/CA 在封装成帧的问题中&#xff0c;数据链路层…

100种思维模型之诺依曼思维模型-019

生活中&#xff0c;难免总会遇到一些“大”、“笼统”、“难入手”的问题&#xff01; 如&#xff0c;前几天突然接到领导安排&#xff0c;帮忙梳理一个材料“***景区创建5A级旅游景区提升规划”。 对于一个没有学过景区提升规划、没有做过规划的我来说&#xff0c;真的挺难的…

Mysql 索引(三)—— 不同索引的创建方式(主键索引、普通索引、唯一键索引)

了解了主键索引的底层原理&#xff0c;主键索引其实就是根据主键字段建立相关的数据结构&#xff08;B树&#xff09;&#xff0c;此后在使用主键字段作为条件查询时&#xff0c;会直接根据主键查找B树的叶子结点。除了主键索引外&#xff0c;普通索引和唯一键索引也是如此&…

URP渲染管线光照机制剖析

上一节通过剖析URP 摄像机了解摄像机的机制&#xff0c;本节来分析URP的光照的主要机制&#xff0c;并通过与内置的向前渲染管线做对比&#xff0c;来比较它们的与不同。 对啦&#xff01;这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白&#xff0c;也有一些…

[机器学习]XGBoost---增量学习多阶段任务学习

一 说明当我们的训练数据非常多&#xff0c;并且还在不断增加时&#xff0c;每次都用全量训练&#xff0c;数据过多&#xff0c;时间过长&#xff0c;此时就可以使用增量训练&#xff1a;用新增的数据微调校正模型。二 全量与增量的差异在使用增量训练时&#xff0c;最关心的问…

矩阵通高效监管企业新媒体矩阵,账号集中管理与运营数据分析

越来越多的企业在全网布局旗下账号&#xff0c;希望通过社媒传播矩阵&#xff0c;以内容连接产品与用户&#xff0c;达成增加销售线索或扩大品牌声量的目的。构建矩阵的优势在于&#xff0c;内容能多元发展&#xff0c;聚集不同平台流量&#xff1b;多种营销渠道自主掌控&#…

高并发系统设计之限流

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 文章目录限流算法计数器算法滑动窗口漏桶算法令牌桶算法限流算法实现Guava RateLimiter实现限流令牌预分配预热限流Nginx 限流limit_connlimit_req黑白名单限流这篇文章来讲讲限流&#xff0c;在高并发系统中…

【包装工单批次编号不存在】和【MES没有样品单报工数据】

包装工单批次编号不存在 今天在做数据的时候,发现一个诡异的问题,有几个包装工单明细里没有批次编号。 我问了下假捻的同事,他们说很奇怪,有的时候有,有的时候没有。 我又咨询了供应商,供应商说不可能没有,批次编号的业务逻辑是通过物料编码+区分号+等级+包装方式 4个…

多模态机器学习入门——文献阅读(一)Multimodal Machine Learning: A Survey and Taxonomy

文章目录说明论文阅读AbstractIntroductionIntroduction总结Applications&#xff1a;A Historical Perspective补充与总结3 MULTIMODAL REPRESENTATIONS总结Joint Repersentations&#xff08;1&#xff09;总结和附加(一)Joint Repersentations&#xff08;2&#xff09;总结…

问题总结:Map存入的数据丢失类型任意

发现问题&#xff1a;Map存入的数据丢失类型 经常会使用 Map<String&#xff0c;Object> 来用于存储键值对的数据&#xff0c;由于我们使用 Object 类型来接收数字&#xff0c;但是有些时候会出现map并不知道我们传入的是 Long 还是 Integer 。也就是出现数据类型丢失的…

变分推断 | MATLAB实现VBMC变分贝叶斯蒙特卡洛模拟的贝叶斯推断

变分推断 | MATLAB实现变分贝叶斯蒙特卡洛模拟的贝叶斯推断 目录 变分推断 | MATLAB实现变分贝叶斯蒙特卡洛模拟的贝叶斯推断效果一览基本介绍研究内容模型描述模型设计参考资料效果一览 基本介绍 MATLAB实现变分贝叶斯蒙特卡洛模拟的贝叶斯推断。变分贝叶斯蒙特卡洛(VBMC)是…

6年测试经验老鸟:做不好自动化测试,还谈什么高薪?

提起自动化测试&#xff0c;可谓仁者见人&#xff0c;智者见智&#xff0c;心中五味杂陈啊&#xff01;你从任何一个招聘渠道来看最近两年对测试岗位的要求&#xff0c;几乎都要求会自动化测试。而不少人一直认为手工测试才是王道&#xff0c;工作中有的时候也用不到程序&#…

摆烂三年,我从普通二本到春招华为OD上岸啦

萌妹镇楼 年前拿到的意向书 答读者问 薪资情况 定级D2,13K2K,两个月年终奖&#xff0c;周六加班双倍工资&#xff0c;下个月发。每年一次加薪&#xff0c;OD转华为一次加薪。 加班强度 124晚9点&#xff0c;35晚6点&#xff0c;项目紧急的话&#xff0c;周六会安排加班 转…

依赖倒转原则和里氏代换原则详解

初学依赖倒转原则和里氏代换原则时&#xff0c;由于笔者水平有限&#xff0c;并没有看懂书上的专业术语的解释&#xff0c;经过反复摸索和学习&#xff0c;发现里氏代换原则和依赖倒转原则可以一言以蔽之&#xff1a; 里氏代换原则&#xff1a;开发时以抽象为核心&#xff0c;…

CMake常用指令

CMake常用指令一、前言二、基本指令2.1、ADD_DEFINITIONS2.&#xff12;、ADD_DEPENDENCIES2.3、ADD_TEST 与ENABLE_TESTING 指令。2.4、AUX_SOURCE_DIRECTORY2.5、CMAKE_MINIMUM_REQUIRED2.6、EXEC_PROGRAM2.7、FILE 指令2.8、INCLUDE 指令2.9、其他指令三、FIND_系列指令四、…

云计算 概念与技术

如果我倡导的计算机在未来得到使用&#xff0c;那么有一天&#xff0c;计算也可能像电话一样成为共用设施。计算机应用将成为一全新的、重要的产业的基础。 ——John McCarthy 云计算的概念 定义 Garther公司的定义 一种计算方式&#xff0c;能通过Internet技术将可扩展的和…

内核模块调试常用命令整理

一、 模块加载 1.1 最简单的一个驱动 static int __init my_driver_init( void ) {printk("init my_driver\n");return 0; }static void __exit my_driver_exit( void ) {printk("exit my_driver\n"); }module_init( my_driver_init ); module_exit( my_…

Xamarin.Forsm for Android 显示 PDF

背景 某些情况下&#xff0c;需要让用户阅读下发的文件&#xff0c;特别是红头文件&#xff0c;这些文件一般都是使用PDF格式下发&#xff0c;这种文件有很重要的一点就是不能更改。这时候就需要使用原文件进行展示。 Xamarin.Forms Android 中的 WebView 控件是不能直接显示的…

R统计绘图-NMDS、环境因子拟合(线性和非线性)、多元统计(adonis2和ANOSIM)及绘图(双因素自定义图例)

这个推文也在电脑里待了快一年了&#xff0c;拖延症患者&#xff0c;今天终于把它发出来了。NMDS分析过程已经R统计-PCA/PCoA/db-RDA/NMDS/CA/CCA/DCA等排序分析教程中写过了。最近又重新看了《Numerical Ecology with R》一书,巩固一下知识&#xff0c;正好重新整理了一下发出…