【APP_汽修宝】数据采集案例APP_数据解密分析


如果不会写代码,那就出书、写博客、做视频、录播客。
                     📚 S35赛季末王者昭君罗


关键代码定位

  • 使用方法【逆向-快速定位关键代码】通过hook常用函数HashMap方法

动态分析

  • 下面是我们通过访问目标页面时 Frida hook 捕获HashMap的调用堆栈:
    在这里插入图片描述
a: username b: AI爱答题
java.lang.Throwable
        at java.util.HashMap.put(Native Method)
        at org.json.JSONObject.put(JSONObject.java:267)
        at org.json.JSONTokener.readObject(JSONTokener.java:384)
        at org.json.JSONTokener.nextValue(JSONTokener.java:100)
        at com.qp333.car.api.DecodeInterceptor.intercept(DecodeInterceptor.java:86)  ## 解码拦截器
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
        at com.qp333.car.api.ParamsInterceptor.intercept(ParamsInterceptor.java:60)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)

        ...

分析该堆栈后,我们定位到了com.qp333.car.api.DecodeInterceptor.intercept目标代码如下:
在这里插入图片描述
其中通过hookaesDecryptString方法得知,通过此方法可以将http响应中的密文转化成明文
在这里插入图片描述

关键代码分析

这段代码展示了如何在 Java 中使用一些工具和方法来解密 JSON 数据,并将解密后的数据放回到 JSON 对象中。让我们逐步解析这段代码:

jSONObject.put("data", new JSONTokener(
    aesDecryptString(
        jSONObject.getString("data"),
        StringUtils.MD5(
            String.format(
                Locale.getDefault(), 
                "%s%s", 
                UserManager.get().sessionid, 
                str
            )
        ),
        String.format(
            Locale.getDefault(), 
            "%s%s%s%s", 
            str + "000", 
            Character.valueOf(str.charAt(1)), 
            Character.valueOf(str.charAt(3)), 
            Character.valueOf(str.charAt(7))
        )
    )
).nextValue());
获取原始加密数据:
jSONObject.getString("data")

这是从 jSONObject 中获取名为 data 的字段的值,该值是一个加密的字符串。

生成解密密钥:
StringUtils.MD5(
    String.format(
        Locale.getDefault(), 
        "%s%s", 
        UserManager.get().sessionid, 
        str
    )
)

这里生成了一个解密密钥。具体步骤是:

使用String.format方法将 UserManager.get().sessionidstr 拼接成一个字符串,Locale.getDefault() 确保格式化时使用默认的区域设置。
将拼接后的字符串传递给 StringUtils.MD5 方法,计算其 MD5 哈希值。这个哈希值将作为解密的密钥。

生成初始向量(IV):
String.format(
    Locale.getDefault(), 
    "%s%s%s%s", 
    str + "000", 
    Character.valueOf(str.charAt(1)), 
    Character.valueOf(str.charAt(3)), 
    Character.valueOf(str.charAt(7))
)

这里生成了解密过程中的初始向量(IV),具体步骤是:

使用 String.format 方法将 str 的第一个字符加上 “000”、str 的第 1、3、7 个字符拼接成一个字符串。
Locale.getDefault() 确保格式化时使用默认的区域设置。
解密数据:

aesDecryptString(
    jSONObject.getString("data"), 
    StringUtils.MD5(String.format(Locale.getDefault(), "%s%s", UserManager.get().sessionid, str)), 
    String.format(Locale.getDefault(), "%s%s%s%s", str + "000", Character.valueOf(str.charAt(1)), Character.valueOf(str.charAt(3)), Character.valueOf(str.charAt(7)))
)

调用aesDecryptString方法,使用从 jSONObject 获取的加密数据、生成的密钥和 IV 进行解密。aesDecryptString 方法返回解密后的字符串。

解析解密后的 JSON 数据:

new JSONTokener(aesDecryptString(...)).nextValue()

将解密后的字符串传递给 JSONTokener,并调用nextValue方法解析解密后的 JSON 数据。

将解密后的数据放回 JSON 对象中:

jSONObject.put("data", new JSONTokener(...).nextValue())

将解析后的 JSON 数据放回 jSONObject 中 data 字段。

整体流程

这段代码的目的是:

  1. 从 JSON 对象中获取加密的 data 字段。
  2. 生成解密密钥和初始向量(IV)。
  3. 使用这些密钥和 IV 通过 aesDecryptString 方法解密数据。
  4. 将解密后的 JSON 数据解析并放回到原来的 jSONObject 中。

代码重构

import base64
import hashlib

from Crypto.Cipher import AES


def md5_string(s):
    return hashlib.md5(s.encode('utf-8')).hexdigest()


def pad(data):
    block_size = AES.block_size
    pad_len = block_size - (len(data) % block_size)
    return data + chr(pad_len) * pad_len


def unpad(data):
    pad_len = ord(data[-1])
    return data[:-pad_len]


def aes_decrypt(data, key, iv):
    cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8'))
    decrypted = cipher.decrypt(base64.b64decode(data))
    return decrypted.decode('utf-8', 'ignore')


def parse_result(data, session_id, time_str):
    # 生成动态MD5密钥
    md5_key = md5_string(f"{session_id}{time_str}")

    # 生成动态IV
    iv_dynamic = f"{time_str}000{time_str[1]}{time_str[3]}{time_str[7]}"

    print(f"MD5 Key: {md5_key}")
    print(f"Dynamic IV: {iv_dynamic}")

    try:
        decrypted_data = aes_decrypt(data, md5_key, iv_dynamic)
        print(f"Decrypted data (raw): {decrypted_data}")
        return decrypted_data
    except Exception as e:
        print(f"Error during decryption: {e}")
        return None


def main():

    session_id = '请求参数中获取'
    encrypted_message = "加密数据"
    timestamp = "1718554525"  # URL请求发起时间戳

    # 解密
    decrypted_data = parse_result(encrypted_message, session_id, timestamp)
    print("Decrypted Data:", decrypted_data)


if __name__ == "__main__":
    main()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nginx与Gateway

Nginx与Gateway Nginx 基本介绍 Nginx 是一款轻量级的高性能 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。它由俄罗斯的 Igor Sysoev 所开发,最初供俄罗斯大型的门户网站及搜索引擎 Rambler 使用。 Nginx 的特点在于其占用…

RIP解决不连续子网问题

#交换设备 RIP解决不连续子网问题 一、不连续子网的概念 相同主网下的子网,被另一个主网分割,例如下面实验拓扑在某公司的网络整改项目中,原先R1 和RS 属于同一主网络 10.0.0.0/8,现被 R2、R3、R4 分离,整网采用了 …

从xxl-job源码中学习Netty的使用

1. 启动与Spring实例化 com.xxl.job.core.executor.impl.XxlJobSpringExecutor.java类 继承SmartInitializingSingleton 类,在afterSingletonsInstantiated 实例化后方法中 调用initJobHandlerMethodRepository 把所有的xxljob任务管理起来; private…

.net8系列-图文并茂手把手教你使用Nlog记录.net日志

Nlog是什么? NLog是一个为.NET平台设计的灵活且免费的日志记录库。它适用于包括.NET Framework、.NET Core和.NET Standard在内的多种.NET环境。 Nlog有什么好处或者特点? 配置灵活:NLog允许开发者通过配置文件(通常是NLog.conf…

串口触摸屏分割字符串

分割字符串的方法1、split2、indexOf()3、substr(start,length) 分割字符串的方法 1、split:将一个字符串分割为子字符串,然后将结果作为字符串数组返回。 2、indexOf() :返回某个指定的字符串值在字符串中首次出现的位置(从左向右…

机器人、人工智能相关领域 news/events (专栏目录)

Some Insights 一些机器人、人工智能或相关领域的news、events等 1. 智能制造 - 你需要了解的 10 个基本要素 2. 现实世界中的人工智能:工业制造的 4 个成功案例研究 3. 企业使用人工智能情况调查 4. 未来工厂中的人工智能:人工智能加速制造成果规模…

用React编写一个密码组件表单

theme: condensed-night-purple highlight: atelier-cave-light 背景介绍 我们在使用网站或者应用程序的登录界面或创建帐户界面时,往往避免不了需要用户输入密码这一步骤,而用户是否可以选择看见他们输入的密码是十分重要的一项功能。尤其是在当输入的…

QT绘图项目 - 汽车表盘

目录 前言: 整体代码 widget.h widget.cpp 效果演示 实现刻度文字正确排版 优化代码 达到效果 封装整理代码结构: widget.h widget.cpp 指针样式美化 优化后的指针API 效果演示 设置高速刻度为红色 优化刻度API 效果演示 速度显示优化 给内圈画上黑色 优化速度…

【学习-华为HCIA数通网络工程师真题(持续更新)】(2024-6-16更)

1、在 VRP 平台上,可以通过下面哪种方式访向上条历史命令? 上光标 (ctrlU 为自定义快捷键,ctrlP 为显示历史缓存区的前一条命令,左光标为移动光标) 2、主机 A (10.1.1.2/24)和主机 B…

在亚马逊云上部署WordPress:一个完整的LAMP环境安装教程

什么是LAMP LAMP是一个流行的开源软件堆栈,用于网站和网络应用程序的开发和部署。LAMP是几个主要组件的首字母缩写,包括: Linux:操作系统层,LAMP通常部署在Linux操作系统上,但它也可以使用其他类似Unix的…

Golang | Leetcode Golang题解之第155题最小栈

题目: 题解: type MinStack struct {stack []intminStack []int }func Constructor() MinStack {return MinStack{stack: []int{},minStack: []int{math.MaxInt64},} }func (this *MinStack) Push(x int) {this.stack append(this.stack, x)top : thi…

牛客周赛 Round 47 解题报告 | 珂学家

前言 题解 这真的是牛客周赛? 哭了 欢迎关注 珂朵莉 牛客周赛专栏 珂朵莉 牛客小白月赛专栏 A. 小红的葫芦 签到题 但是写起来有点变扭,方法应该蛮多的 统计分组 有2组一组长度为2,一组长度为3 def check(arr):arr.sort()if arr[0] …

Git学习2 -- VSCode中的Git

看了下,主要的插件有3个。自带的Source Control。第1个是Gitlens,第2个是Git Graph。第三个还有个git history。 首先是Source Control。界面大概是这样的。 还是挺直观的。在第一栏source control,可以进行基本的git操作。主要的git操作都是…

MongoDB~高可用集群介绍:复制集群(副本集)、分片集群

背景 MongoDB 的集群主要包括副本集(Replica Set)和分片集群(Sharded Cluster)两种类型。 副本集 组成:通常由一个主节点(Primary)和多个从节点(Secondary)构成。 功…

Objective-C 学习笔记 | init

Objective-C 学习笔记 | init Objective-C 学习笔记 | init编写 init 方法禁用 init 方法 Objective-C 学习笔记 | init init 是实例方法,负责初始化对象,并返回初始化后的对象的地址。 编写 init 方法 完整代码见于:UestcXiye/Objective-…

【前端:HTML+CSS+JavaScript】HTML基础(下)

一、表格标签 1.1 表格的主要作用 表格主要用于显示、展示数据。因为她可以让数据显示的非常频繁&#xff0c;可读性非常好。特别是后台展示数据的时候&#xff0c;能够熟练运用表格就线程显得很重要。表格不是用来布局页面的。而是用来展示数据的。 1.2 表格的基本语法 <…

windows11 x64 23H2 企业纯净版2024.6.16

闲来无事试安装了下da_nao_yan的 【6月12日更新】Windows11 22631.3737企业版 23H2 自用优化版 &#xff08;原版地址&#xff1a;https://bbs.pcbeta.com/viewthread-1985546-1-1.html&#xff09;&#xff0c;感觉比原版流畅多了&#xff0c;重新按照自己习惯封装了下&#x…

Nvidia芯片Jetson系列 系统烧录环境 搭建

一、序言 Jetson 系列产品烧录系统的方法一般有两种&#xff1a; 一种为使用 NVIDIA 官方提供 的 SDK manager 软件给 Jetson 设备烧录系统&#xff08;请查看说明文档《Jetson 产品使用 SDKmanager 烧录系统》&#xff09;。 另一种即为当前文档所描述的&#xff0c;在安装 Ub…

Azure数据分析Power BI

Azure数据分析Power BI 一、Power BI简介二、Power BI 如何匹配角色三、Power BI 构建基块四、使用 Power BI 服务一、Power BI简介 Microsoft Power BI 是一系列的软件服务、应用和连接器,这些软件服务、应用和连接器协同工作,将不相关的数据源转化为合乎逻辑、视觉上逼真的…

Java实现俄罗斯方块-初始化游戏界面的JPanel

目录 技术实现&#xff1a; 2.初始化游戏界面&#xff1b; 2.1 什么是游戏界面 2.2 JPanel面板 2.3 流布局管理器【FlowLayout】 2.4 网络布局管理器 【GridLayout】 2.5 边界布局管理器 技术实现&#xff1a; 1.初始化游戏窗口&#xff1b; 2.初始化游戏界面&#xff…