19.安卓逆向-frida基础-hook分析调试技巧1-hookMD5

news2024/11/24 3:30:34

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

内容参考于:图灵Python学院

本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。

工具下载:

链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3

提取码:6tw3

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:18.安卓逆向-frida基础-调试实战2

上一个内容里,进一步编写了FridaHook算法的脚本,上一个内容只写了HOOK MD5算法的Update方法,它可以得到明文数据,本次接着继续

首先是MD5加密完之后的数据

首先编写下图红框里的代码,然后运行,让它报下图蓝框里的错误,从而得到它有哪些参数

效果图:

完整的hook md5脚本代码

function bytesToHex(arr) {
    var str = "";
    for (var i = 0; i < arr.length; i++) {
        var tmp = arr[i];
        if (tmp < 0) {
            tmp = (255 + tmp + 1).toString(16);
        } else {
            tmp = tmp.toString(16);
        }
        if (tmp.length == 1) {
            tmp = "0" + tmp;
        }
        str += tmp;
    }
    return str;
}
function bytesToBase64(e) {
    var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    var r, a, c, h, o, t;
    for (c = e.length, a = 0, r = ''; a < c;) {
        if (h = 255 & e[a++], a == c) {
            r += base64EncodeChars.charAt(h >> 2),
                r += base64EncodeChars.charAt((3 & h) << 4),
                r += '==';
            break
        }
        if (o = e[a++], a == c) {
            r += base64EncodeChars.charAt(h >> 2),
                r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
                r += base64EncodeChars.charAt((15 & o) << 2),
                r += '=';
            break
        }
        t = e[a++],
            r += base64EncodeChars.charAt(h >> 2),
            r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
            r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6),
            r += base64EncodeChars.charAt(63 & t)
    }
    return r
}
function bytesToString(arr) {
    if (typeof arr === 'string') {
        return arr;
    }
    var str = '',
        _arr = arr;
    for (var i = 0; i < _arr.length; i++) {
        var one = _arr[i].toString(2),
            v = one.match(/^1+?(?=0)/);
        if (v && one.length == 8) {
            var bytesLength = v[0].length;
            var store = _arr[i].toString(2).slice(7 - bytesLength);
            for (var st = 1; st < bytesLength; st++) {
                store += _arr[st + i].toString(2).slice(2);
            }
            str += String.fromCharCode(parseInt(store, 2));
            i += bytesLength - 1;
        } else {
            str += String.fromCharCode(_arr[i]);
        }
    }
    return str;
}

function main() {
    Java.perform(function () {
        // 有些app没有 ByteString,如果没有需要我们自己用Python或js写转换,这个百度一搜一大堆
         var ByteString = Java.use("com.android.okhttp.okio.ByteString")

        var MessageDigest = Java.use('java.security.MessageDigest')

        function toUtf8(data){
            return ByteString.of(data).utf8();
        }

        /**
         * hook Update 方法获取明文数据
         * */
        MessageDigest.getInstance.overload('java.lang.String').implementation = function (str) {
            console.log('算法名:',str)
            return this.getInstance(str)
        }

        MessageDigest.update.overload('byte').implementation=function (str) {
            console.log(`byte算法入参:${str}`)
            return this.update(str)
        }
        MessageDigest.update.overload('java.nio.ByteBuffer').implementation=function (str) {
            console.log(`java.nio.ByteBuffer算法入参:${str}`)
            return this.update(str)
        }
        MessageDigest.update.overload('[B').implementation=function (str) {
            // [B是字节需要转成字符串我们人才认识,toUtf8方法可以把字节转换文字(文字指的是字母、数字、中文、英文)
            console.log(`update.overload('[B')[B算法入参:${toUtf8(str)}`)

            return this.update(str)
        }
        MessageDigest.update.overload('[B', 'int', 'int').implementation=function (str, a1, a2) {
            console.log(`'[B', 'int', 'int算法 入参1:${str},入参2:${a1},入参3:${a2}`)
            return this.update(str, a1, a2)
        }

        /**
         * hook digest 方法获取加密之后的数据
        * */
         MessageDigest.digest.overload().implementation=function () {
            var res = this.digest()
            console.log(`digest.overload()返回值:${bytesToHex(res)}`);
            console.log(`digest.overload()bytesToHex返回值:${bytesToHex(res)}`);
            console.log(`digest.overload()bytesToBase64返回值:${bytesToBase64(res)}`);
             return res
        }

          MessageDigest.digest.overload("[B").implementation=function (arr) {
            console.log(`digest.overload("[B")入参:${bytesToString(arr)}`);
            var res = this.digest(arr);
            console.log(`digest.overload("[B")bytesToString返回值:${bytesToString(res)}`);
            console.log(`digest.overload("[B")bytesToHex返回值:${bytesToHex(res)}`);
            console.log(`digest.overload("[B")bytesToBase64返回值:${bytesToBase64(res)}`);
             return res
        }

    })
}

main()

然后使用上方的脚本去找一个真实的app试一试,通过抓包的方式不通过逆向的方式找它的明文,如下图对app抓的包

然后下图红框位置有一个哈希算法,它的值就是MD5,然后试一试我们的Frida Hook脚本能不能得到它

然后运行Frida hook脚本,然后来到app里刷新界面,效果如下图,可以正常hook得到算法

然后下图蓝框是它要加密的数据,红框是加密完的数据,下图蓝框和红框之间有很多东西,这可能是因为MD中调用了其它方法,也被我们hook了,所以会打印多余的

然后通过在线的MD5加密工具验证,正常

然后对数据进行拆分,如下图的拆分

上图里经过多次调用接口发现 C50GIK6GDhQNjtMRVRoQbwxVovXCX8DU 是不变的,所以它可能是用来加密用的钥匙,是写死的,然后我们也对它写死

Python代码测试

首先来到Charles(青花瓷),然后选中参数,然后右击,选择Copy cURL Request

然后百度搜索 curl request 转Python代码 在线 这个关键字,如下图红框,它可以给我们生成Python代码,复制粘贴之后改改就行了

import hashlib
import time

import requests

headers = {
    'Host': '',
    'os': 'android',
    'appversion': '10.2.1',
    'rmt-device-id': '30F1CB8DE4DD5B232D9465BBD71C57EC8F65FC80',
    'rmt-hash': 'c5ca34fe9d02fb642273df676c8fff39',
    'rmt-request-time': '1728311097476',
    'rmt-device-type': 'android',
    'rmt-build': '1002100',
    'rmt-app-version': '10.2.1',
    'rmt-app-id': '9',
    'user-agent': 'okhttp/4.11.0',
}

_ts = str(int(time.time() * 1000))

params = {
    'list_version': '',
    'classid': '3378',
    'appid': '9',
    'page': '1',
}

headers['rmt-request-time'] = _ts
pa = "C50GIK6GDhQNjtMRVRoQbwxVovXCX8DUv5"


def md5s(param):
    md5 = hashlib.md5()
    md5.update(param.encode())
    return md5.hexdigest()


hash = md5s(pa+"android"+headers['rmt-request-time']+headers['rmt-device-id']+headers['rmt-hash'])
headers['rmt-hash'] = hash


response = requests.get('', params=params, headers=headers)
print(response.text)

这样可以不用逆向就可以得到想要的东西了


img

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

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

相关文章

C#多线程基本使用和探讨

线程是并发编程的基础概念之一。在现代应用程序中&#xff0c;我们通常需要执行多个任务并行处理&#xff0c;以提高性能。C# 提供了多种并发编程工具&#xff0c;如Thread、Task、异步编程和Parallel等。 Thread 类 Thread 类是最基本的线程实现方法。使用Thread类&#xff0…

【题解】【模拟】—— [NOIP2013 普及组] 表达式求值

【题解】【模拟】—— [NOIP2013 普及组] 表达式求值 [NOIP2013 普及组] 表达式求值题目背景题目描述输入格式输出格式输入输出样例输入 #1输出 #1输入 #2输出 #2输入 #3输出 #3 提示 1.简单做法1.1.题意解析1.2.AC代码 2.使用栈的做法2.1.题意解析2.2.AC代码 [NOIP2013 普及组…

C高级--shell脚本实现分支判断

题目&#xff1a; 分支结构结合test指令完成一下编程 1>判断闰年 2>输入一个数判断是否为偶数 3>使用test指令实现等级判断 90--100A 60--89B 0-50C 其他错误 代码如下&#xff1a; #!/bin/bash read -p "请输入一个年份&#xff1a;" year if [ $((y…

Cisco Meraki平台登陆

登陆以下网址 https://n4.meraki.cn/ 输入之前注册的邮箱&#xff0c;点击Next 输入之前注册时输入的密码&#xff0c;注意不是企业邮箱的密码&#xff01; 查看邮箱&#xff0c;将验证码输入&#xff0c;点击Verify&#xff08;验证&#xff09;&#xff0c;此验证码10分…

C语言-文件IO

文件IO I :input 输入&#xff0c;从文件中读取数据到内存 O:output 输出&#xff0c;把数据写入到文件 Linux系统IO 和 c语言标准IO 1、linux系统IO 1.1 简介 linux操作系统把对文件的操作封装成了多个函数&#xff0c;统称为linux系统IO。 文件描述符(File descirptor)…

笔试算法day01

目录 1.除2 2.Fibonacci数列&#xff08;Fib 数列&#xff09; 3.单词搜索 1.除2 除2&#xff01; (nowcoder.com) 算法思路&#xff1a; 只需要对最大的n个偶数进行/2即可。 将所有的偶数存进大根堆中&#xff0c;执行k次操作即可 #include <iostream> #include <…

2024年AI知识库哪家强?8款主流软件对比分析

在当今这个信息爆炸的时代&#xff0c;如何高效地管理、搜索和共享知识成为了一个重要的问题。AI知识库作为一种先进的解决方案&#xff0c;正受到越来越多企业和个人的青睐。本文将对比分析8款主流的AI知识库软件&#xff0c;帮助大家找到最适合自己的工具。 1. HelpLook AI知…

机器学习K近邻算法——回归问题K近邻算法示例

针对“数据4.1”&#xff0c;讲解回归问题的K近邻算法&#xff0c;以V1&#xff08;营业利润水平&#xff09;为响应变量&#xff0c;以V2&#xff08;固定资产投资&#xff09;、V3&#xff08;平均职工人数&#xff09;、V4&#xff08;研究开发支出&#xff09;为特征变量。…

Flutter 进阶:根据IP地址判断用户国家/地区

在应用开发中根据IP地址判断用户国家/地区的两种方法 引言 在开发国际化应用时&#xff0c;了解用户的地理位置至关重要。这不仅影响用户体验&#xff0c;还关系到内容展示和合规性。本文将介绍两种通过IP地址判断用户所在国家或地区的方法。 方法一&#xff1a;使用 ip-api…

redis高级(面试题二)

目录 一、redis的五大数据结构有哪些&#xff1f;zset底层是什么结构&#xff1f; 1、redis五大数据结构有哪些&#xff1f; 2、什么是skiplist&#xff1f; 3、zset底层是什么结构&#xff1f; 二、Redis的内存过期策略是什么&#xff1f;Redis的内存淘汰策略有哪些&#…

【专题】数据库系统的基本原理

1. 数据库系统概述 1.1. 数据库系统的应用 电信业、银行业、金融业、销售业、联机的零售商、大学、航空业、人力资源、制造业等等。 1.2 数据库系统的概念 (1) 数据&#xff08;Data&#xff09; 数据是数据库存储的基本对象。是描述现实世界中各种具体事物或抽象概念的、可…

Nuxt日志监控(服务端及客户端日志检测)

此文章主要讲解如何使用Nuxt进行日志监控&#xff0c;例如服务端请求日志&#xff0c;客户端请求日志&#xff0c;方便线上出现问题能及时排查问题所在 一、下载依赖 npm install winston winston-daily-rotate-file二、plugin下创建日志处理插件winston.js&#xff0c;对日志…

靠谱!有了它,微信自动统计报表轻松搞定!

当你需要定期统计多个微信号的数据时&#xff0c;每次都要逐一登录并手动统计各种数据&#xff0c;这不仅耗时&#xff0c;还容易出错。 好在&#xff0c;一个便捷的工具——个微管理系统能够帮助我们高效地管理这些繁杂的数据&#xff0c;让我们的工作事半功倍。 好友统计报…

安装Node.js环境,安装vue工具(最佳实践)

一、安装Node.js 去官网下载自己需求的安装包&#xff08;我提供的步骤是windows10 64x&#xff09; 下载 | Node.js 中文网 (nodejs.cn)https://nodejs.cn/download/ 下载好后&#xff0c;安装到默认路径就好了&#xff0c;所占用的内容很少。 一直点next就行了 安装好后&a…

python操作.docx、.pptx文件

python操作.docx、.pptx文件 .docx文件和.pptx文件是Microsoft Office套件中两种常见的文件格式&#xff0c;分别对应Word文档和PowerPoint演示文稿。WPS Office完美支持Microsoft Office文件格式。 使用 Python 操作 .docx 和 .pptx 文件是一项非常实用的技能&#xff0c;尤…

BlabkForestLabs 又放大招:“蓝莓”模型其实是 Flux1.1?!

神秘的 AI 生成模型 BlabkForestLabs 又放大招了&#xff1f;就在 AI 绘画圈还在训练 Flux.1 练的不亦乐乎的时候&#xff0c;黑森林工作室又推出了一个新的模型—— Flux1.1 &#xff01;这次升级后的 Flux1.1 性能直接完爆前版的 Flux.1 &#xff0c;再次将 AI 绘画的上限拉高…

如何给ppt增加新的一页?这2个ppt使用技巧值得推荐!

在当今讲究视觉表现力的时代&#xff0c;PPT已经成为职场中不可或缺的工具。无论是汇报工作、演示方案还是传递想法&#xff0c;一份精美的PPT都能让你的演讲&#xff08;演示&#xff09;更加出色。 然而&#xff0c;制作PPT并非易事&#xff0c;尤其是对于新手来说&#xff…

STM32-HAL库 驱动DS18B20温度传感器 -- 2024.10.8

目录 一、教程简介 二、驱动理论讲解 三、CubeMX生成底层代码 四、Keil5编写代码 五、实验结果 一、教程简介 本教程面向初学者&#xff0c;只介绍DS18B20的常用功能&#xff0c;但也能满足大部分的运用需求。跟着本教程操作&#xff0c;可在10分钟内解决DS18b20通信难题。…

windows认证

本地环境用户信息存储在%systemroot%/system32/SAM 域环境用户信息存储在ntds.dit 本地认证 windows系统下哈希结构&#xff1a;username:RID:LM-HASH:NT-HASH LM哈希 算法&#xff1a; 转大写&#xff0c;转二进制&#xff0c;补0补足14字节 二分获得两段字串&#xff…

算法:238.除自身以外数组的乘积

题目 链接&#xff1a;leetcode链接 思路分析&#xff08;前缀和&#xff09; 这道题非常类似 724. 寻找数组的中心下标 在前一篇博客讲解了该题目 传送门:算法&#xff1a;724.寻找数组的中心下标 这道题目的区别在于&#xff0c;这道题是预处理前缀积和后缀积 另外&#x…