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

news2024/11/24 20:24:41

如果不会写代码,那就出书、写博客、做视频、录播客。
                     📚 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()

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

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

相关文章

Linux之BCC 性能工具的移植和使用

一、bcc 工具 bcc 的全称:BPF Compiler Collection BCC(BPF Compiler Collection)是一个用于创建高效的内核跟踪和操作程序的工具包,包含了几个有用的工具和示例。它利用了扩展的BPF(Berkeley Packet Filters&#x…

【C/C++】【学生成绩管理系统】深度剖析

可接各类C/C管理系统课设 目录 实现功能 部分1:系统设置和主菜单 1. 引入头文件 2. 定义结构体 3. 函数声明 4. 主函数 部分2:添加学生信息 部分3:删除学生信息 部分4:修改学生信息 部分5:查询学生信息 部分…

大众点评_token,mtgsig

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经许可禁止转载&#xff0…

以太网基础知识(三)—FEC概念以及编码原理介绍

1:前言 KR4(528,514) FEC表示的意思: KR4 RS(528,514) FEC 是一种以太网中使用的FEC(Forward Error Correction)编码方案。在这个方案中,采用的是Reed-Solomon (RS) 编码算法,它被设计用于提高数据传输的…

9M高速USB转接芯片CH347转双串口转I2C转SPI转JTAG转SWD

1、概述 CH347 TSSOP20封装和丝印 CH347 是一款高速 USB 总线转接芯片,通过 USB 总线提供异步串口、I2C 同步串行接口、SPI 同步串行接口和 JTAG 接口等。 在异步串口方式下,CH347 提供了 2 个高速串口,支持 RS485 串口收发使能控制、硬件流控…

论文阅读:基于谱分析的全新早停策略

来自JMLR的一篇论文,https://www.jmlr.org/papers/volume24/21-1441/21-1441.pdf 这篇文章试图通过分析模型权重矩阵的频谱来解释模型,并在此基础上提出了一种用于早停的频谱标准。 1,分类难度对权重矩阵谱的影响 1.1 相关研究 在最近针对…

SN74HC14+陶瓷振子做振荡器的试验初步

本想试验一下465khz用SN74HC14做振荡器,实验了很多次,无法起振。 用1M,4M的也无法起振,用到10Mhz时,能起振,用小频谱仪看,谐波相当丰富,从10M到300Mhz,当然我是通过实验在…

python14 字典类型

字典类型 键值对方式,可变数据类型,所以有增删改功能 声明方式1 {} 大括号,示例 d {key1 : value1, key2 : value2, key3 : value3 ....} 声明方式2 使用内置函数 dict() 创建1)通过映射函数创建字典zip(list1,list2) 继承了序列的所有操作 …

第零篇——数学到底应该怎么学?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 宏观讲解数学定位,数学学习方式方法,再次详细学习…

C# OpenCV 部署RecRecNet广角图像畸变矫正

C# OpenCV 部署RecRecNet广角图像畸变矫正 目录 说明 效果 模型信息 项目 代码 下载 说明 ICCV2023 - RecRecNet: Rectangling Rectified Wide-Angle Images by Thin-Plate Spline Model and DoF-based Curriculum Learning 参考: https://github.com/Kang…

Vue52-scoped样式

一、scoped样式的作用 1-1、scoped样式的作用 vue中组件的样式都是汇总到一起的。容易出现一个问题:类名冲突。 示例: school和student组件的类名都叫demo,则student的样式将覆盖school的样式,因为App.vue中,先引入的…

Spring事务管理、SpringAop

目录 ​编辑 Spring事务管理 注解:Transactional rollbackFor 事务属性-传播行为 propagation SpringAOP AOP核心概念 通知类型 通知顺序 切入点表达式 切入点表达式-execution 切入点表达式-annotation 连接点 ​编辑 将案例中 增、删、改 相关接口的操作日志记…

unity跑酷游戏(源码)

包括:触发机关, 优化 fog的调试 效果 碰到障碍物游戏时间暂停(挂载到障碍物上) 上面需要有碰撞体 游戏物体上需要有标签 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Barri…

【仿真建模-anylogic】FlowchartBlock原理解析

Author:赵志乾 Date:2024-06-17 Declaration:All Right Reserved!!! 1. 类图 2. 原理解析 2.1 核心函数 函数功能FlowchartBlock(Engine engine ,Agent owner, AgentList population )构造函数&#xff…

C语言王国——深入自定义类型(结构体)

目录 一、引言 二、结构体 1. 结构体类型的声明 2. 结构体变量的创建和初始化 2.1 创建 2.2 初始化 2.3 typedef 2.4 特殊声明 2.5 自引用 3. 结构成员访问操作符 4. 结构体内存对齐 4.1 对齐规则 4.2 offsetof 4.3 为什么存在内存对齐 5. 结构体传参 6. 结构体实现…

仅靠独立网站也能赚到100万,真的太牛了

你听说过 Photopea 吗?这是一个免费的类似 Photoshop 的图像编辑器。 这个项目: 每月1300万访问量每月150万用户使用小时每月10万美元的广告收入 Photopea 项目的天才创造者是 Ivan Kutskir。 令人惊讶的是,他独自处理了每日50万用户&…

数组趣味玩法:在Java SE中尝试创新玩法

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一…

C++ | Leetcode C++题解之第160题相交链表

题目: 题解: class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {if (headA nullptr || headB nullptr) {return nullptr;}ListNode *pA headA, *pB headB;while (pA ! pB) {pA pA nullptr ? headB : p…

【Vue3】插槽的使用及其分类

历史小剧场 后来我才明白,造反的宋江,和招安的宋江,始终是同一个人。 为什么要造反? 造反,就是为了招安。 ----《明朝那些事儿》 概念 在日常的项目开发中,当我们在编写一个完整的组件时,不可避…

款基于SpringBoot+Vue+ElementUI技术栈开发的自定义表单工具(已开源)

TDuck填鸭表单是一个开源的问卷调查系统,一款基于SpringBootVueElementUI技术栈开发的自定义表单工具,它不仅支持问卷调查,还能进行数据收集。TDuck团队经过两年的优化,使得社区版功能趋于稳定。2023年5月,团队推出了可…