某站平台的签名算法分享

  • 先charles抓包,api.xxxxxx.com域名的包

  • 分析包 看到路径参数如下

  • appkey=1d8b6e7d45233436&build=5531000&channel=dw056&mobi_app=android&mode=0&oid=326052200&plat=2&platform=android&ps=20&statistics=%7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%225.53.1%22%2C%22abtest%22%3A%22%22%7D&ts=1705305495&type=1&sign=2c9086d4acc853a017ec087699902634
    可以看到一个sign,是个32字符,128位,直觉告诉我可能是个md5签名

  • 然后用jadx打开xxx.apk包,全局搜索sign字符串,在众多函数方法中,找到一个SignedQuery函数,跟进去看,发现又个loadLibrary(xxx),那么直接告诉我是在一个so里

  • 用apktool把xxx.apk decode出来,拿到libxxx.so

  • 用ida打开该libxxx.so,直接看JNI_OnLoad函数,找到这一行

    if ( (*v5)->RegisterNatives(v5, v4, (const JNINativeMethod *)&register_native_struct, 5) < 0

  • register_native_struct跟进去

 

  • 每个函数进去看下,有惊喜,确实是个md5算法,找到 md5_impl,跟进去看看算法参数

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    163

    164

    165

    166

    167

    168

    int __fastcall md5_impl(JNIEnv *a1, jobject (*a2)(JNIEnv *, jclass, jmethodID, ...))

    {

    JNIEnv *v2; // r11

    jobject (*v3)(JNIEnv *, jclass, jmethodID, ...); // r6

    const char *v4; // r2

    const char *v5; // r1

    int result; // r0

    int v7; // r0

    JNIEnv v8; // r1

    int v9; // r0

    int v10; // r4

    int v11; // r0

    int v12; // r10

    signed int v13; // r9

    int v14; // r5

    int v15; // r8

    time_t v16; // r0

    int v17; // r6

    int v18; // r5

    const char *input_str; // r8

    _DWORD *v20; // r10

    int v21; // r4

    _DWORD *v22; // r0

    int v23; // r1

    int v24; // r2

    int v25; // r0

    unsigned int input_len; // r5

    signed int v27; // r4

    char *v28; // r5

    int v29; // r4

    const char *v30; // [sp+8h] [bp-C0h]

    int v31; // [sp+8h] [bp-C0h]

    int v32; // [sp+Ch] [bp-BCh]

    char v33; // [sp+10h] [bp-B8h]

    int s; // [sp+38h] [bp-90h]

    int v35; // [sp+3Ch] [bp-8Ch]

    int v36; // [sp+40h] [bp-88h]

    int v37; // [sp+44h] [bp-84h]

    char v38[24]; // [sp+90h] [bp-38h]

    int v39; // [sp+A8h] [bp-20h]

    v2 = a1;

    v3 = a2;

    if ( !sub_2D20((int)a1) )

    goto LABEL_5;

    v4 = "com.xxxxxxxx.nativelibrary.SignedQuery";

    v5 = "java/lang/ClassNotFoundException";

    LABEL_3:

    sub_401C((int)v2, (int)v5, (int)v4);

    result = 0;

    while ( _stack_chk_guard != v39 )

    {

    LABEL_5:

    if ( !v3 )

    {

      v5 = "java/lang/NullPointerException";

      v4 = "Null params!";

      goto LABEL_3;

    }

    v7 = is_empty(v2, (int)v3);

    v8 = *v2;

    if ( v7 )

    {

      v3 = v8->NewObject;

      result = ((int (__fastcall *)(JNIEnv *, int, int, _DWORD, _DWORD))v3)(

                 v2,

                 cls_signed_query,

                 signed_query_init,

                 0,

                 0);

    }

    else

    {

      v9 = ((int (__fastcall *)(JNIEnv *, const char *))v8->NewStringUTF)(v2, "appkey");

      v10 = v9;

      v11 = sub_60CC(v2, (int)v3, v9);          // // 校验appkey

      v12 = v11;

      if ( v11 )

      {

        v30 = (const char *)((int (__fastcall *)(JNIEnv *, int, _DWORD))(*v2)->GetStringUTFChars)(v2, v11, 0);

        v13 = check_app_key_get_type(v30);

      }

      else

      {

        v13 = -1;

        v30 = 0;

      }

      v14 = ((int (__fastcall *)(JNIEnv *, const char *))(*v2)->NewStringUTF)(v2, "ts");

      v15 = sub_60CC(v2, (int)v3, v14);

      if ( !v15 )

      {

        v36 = 0;

        v37 = 0;

        s = 0;

        v35 = 0;

        v16 = time(0);

        sprintf((char *)&s, "%ld", v16);

        ((void (__fastcall *)(JNIEnv *, int *))(*v2)->NewStringUTF)(v2, &s);

        sub_6188((int)v2);

      }

      sub_41D0(v2, v14);

      sub_41D0(v2, v15);

      v17 = ((int (__fastcall *)(JNIEnv *, int, int, jobject (*)(JNIEnv *, jclass, jmethodID, ...)))(*v2)->CallStaticObjectMethod)(

              v2,

              cls_signed_query,

              method_signed_query_r,

              v3);

      v18 = 0;

      if ( sub_3F70((int)v2) )

        v17 = 0;

      v32 = v17;

      input_str = (const char *)((int (__fastcall *)(JNIEnv *, int, _DWORD))(*v2)->GetStringUTFChars)(v2, v17, 0);

      if ( v13 != -1 )

      {

        ((void (__fastcall *)(JNIEnv *, int, const char *))(*v2)->ReleaseStringUTFChars)(v2, v12, v30);

        v20 = malloc(0x10u);

        if ( v20 )

        {

          v31 = v10;

          v21 = global_key[v13];

          v22 = &global_key[v13];

          v23 = v22[5];

          v24 = v22[10];

          v25 = v22[15];

          *v20 = v21;

          v20[1] = v23;

          v20[2] = v24;

          v20[3] = v25;

          _aeabi_memclr8(&v33, 33);

          input_len = strlen(input_str);

          _aeabi_memclr8(v38, 24);

          _aeabi_memclr8(&s, 88);

          md5_init(&s);

          md5_update((int)&s, (int)input_str, input_len);

          sprintf(v38, "%08x", v21);

          md5_update((int)&s, (int)v38, 8u);

          v27 = 1;

          do

          {

            sprintf(v38, "%08x", v20[v27]);

            md5_update((int)&s, (int)v38, 8u);

            ++v27;

          }

          while ( v27 != 4 );

          md5_final((int)v38, (int)&s);

          v28 = &v33;

          v29 = 0;

          do

          {

            sprintf(v28, "%02x", (unsigned __int8)v38[v29++]);

            v28 += 2;

          }

          while ( v29 != 16 );

          free(v20);

          v10 = v31;

          v18 = ((int (__fastcall *)(JNIEnv *, char *))(*v2)->NewStringUTF)(v2, &v33);

        }

        else

        {

          v18 = 0;

        }

      }

      sub_41D0(v2, v10);

      v3 = (*v2)->NewObject;

      result = ((int (__fastcall *)(JNIEnv *, int, int, int, int))v3)(v2, cls_signed_query, signed_query_init, v32, v18);

    }

    }

    return result;} 

  • 分析代码,发现关键在 check_app_key_get_type和global_key,一个是app key获取type,还有一个存着类似于secret key的 global key

  • 整体看下来,结论就是 md5加密,按参数字典序排序,然后拼接SecretKey,再md5得到sign,取其中一个type来验证下:

  • 图片描述


    和app请求生成的sign一样,secret key打码,如果想要,可以按步骤自己去试试,实测成功,关键地方都写清楚了

 最后,写个python脚本试试,确实都能访问,这里脚本就不放了,求赞求加精,求账号升级,感谢

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

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

相关文章

异步编程Completablefuture使用详解----进阶篇

JDK版本&#xff1a;jdk17 IDEA版本&#xff1a;IntelliJ IDEA 2022.1.3 文章目录 前言一、异步任务的交互1.1 applyToEither1.2 acceptEither1.3 runAfterEither 二、get() 和 join() 区别三、ParallelStream VS CompletableFuture3.1 使用串行流执行并统计总耗时3.2 使用并行…

前端JavaScript篇之map和Object的区别、map和weakMap的区别

目录 map和Object的区别map和weakMap的区别 map和Object的区别 Object是JavaScript的内置对象&#xff0c;用于存储键值对。Object的键必须是字符串或符号&#xff0c;值可以是任意类型。Map是ES6引入的新数据结构&#xff0c;用于存储键值对。Map的键可以是任意类型&#xff…

C++ 日期类的实现

目录 前言 日期类中的成员函数和成员变量 日期类中成员函数的详解和实现 1.天数前后的判断 2.天数加减的实现 3.前置 && 后置 4.计算天数差值 前言 日期类的实现将综合前面所学的&#xff08;类的6个默认成员函数&#xff09;&#xff0c;进一步理解和掌握类的…

COX预测模型过程中,我踩过的那些雷

R语言做&#xff01;初学者先进来看看&#xff01;&#xff01;&#xff01; SCI冲 COX分析&#xff1a;做临床信息与预后相关的COX分析大致都会分为两个步骤&#xff0c;先做单因素COX回归分析&#xff0c;再根据P值挑选有意义的变量&#xff0c;最终纳入COX多因素回归模型中&…

20240202在WIN10下部署faster-whisper

20240202在WIN10下部署faster-whisper 2024/2/2 12:15 前提条件&#xff0c;可以通过技术手段上外网&#xff01;^_ 首先你要有一张NVIDIA的显卡&#xff0c;比如我用的PDD拼多多的二手GTX1080显卡。【并且极其可能是矿卡&#xff01;】800&#xffe5; 2、请正确安装好NVIDIA最…

SpringBoot实战项目第一天

环境搭建 后端部分需要准备&#xff1a; sql数据库 创建SpringBoot工程&#xff0c;引入对应的依赖(web\mybatis\mysql驱动) 配置文件application.yml中引入mybatis的配置信息 创建包结构&#xff0c;并准备实体类 完成今日开发后项目部分内容如下图示 用户注册于登录部分…

[BUUCTF]-PWN:mrctf2020_easy_equation解析

查看保护 再看ida 很明了&#xff0c;题目就是让我们用格式化字符串漏洞修改judge的值&#xff08;可以用python脚本进行计算&#xff0c;最终算出来得2&#xff09;使等式成立&#xff0c;然后getshell。 虽然操作比较简单&#xff0c;但我还是列出了几种方法 解法一&#x…

uni-app移动端图片预览组件 movable-area 、movable-view (支持缩放,拖动效果、替换部分代码图片可直接使用)

UniApp图片预览组件 利用uni-app官方<movable-area>、<movable-view>内置视图组件 配合 uView 组件的u-popup 弹框组件共同实现封装的图片预览组件&#xff0c;支持手指缩放、拖动效果&#xff0c;替换代码中部分图片后 可以直接使用。 效果图&#xff1a; 组件代码…

【数据结构与算法】——单链表的原理及C语言实现

数据结构与算法——链表原理及C语言实现 链表的原理链表的基本属性设计创建一个空链表链表的遍历&#xff08;显示数据&#xff09;释放链表内存空间 链表的基本操作设计&#xff08;增删改查&#xff09;链表插入节点链表删除节点链表查找节点增删改查测试程序 链表的复杂操作…

Vulnhub billu b0x

0x01 环境搭建 1. 从官方下载靶机环境&#xff0c;解压到本地&#xff0c;双击OVF文件直接导入到vmware虚拟机里面。2. 将虚拟机的网络适配器调成NAT模式&#xff0c;然后开机即可进行操作了。 0x02 主机发现 nmap -sn 192.168.2.0/24 成功获取靶机IP为192.168.2.129。 0x0…

本次安装Visual Studio 所用的安装程序不完整。请重新运行VisualStudio安装程序以解决此问题

今天点开VS的时候遇到了这个问题 因为昨天升级到一半电脑关机了&#xff0c;今天打开软件遇到如下错误&#xff0c; 解决办法很简单&#xff0c;找到安装目录进入Installer文件夹 我的目录在C:\Program Files (x86)\Microsoft Visual Studio\Installer 找到vs_installer.exe…

【python】python爱心代码

一、实现效果&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 二、准备工作 &#xff08;1)、导入必要的模块&#xff1a; 代码首先导入了需要使用的模块&#xff1a;requests、lxml和csv。 import requests from lxml import etree import csv 如果出现…

C#写个小工具,把多个word文档进行合并成一个word文档

先要安装包 帮助类WordDocumentMerger&#xff0c;用于处理word合并功能 using System; using System.Collections.Generic; using System.Text; using Microsoft.Office.Interop.Word; using System.Reflection; using System.IO; using System.Diagnostics;namespace WordH…

分别用JavaScript,Java,PHP,C++实现桶排序的算法(附带源码)

桶排序是计数排序的升级版。它利用了函数的映射关系&#xff0c;高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效&#xff0c;我们需要做到这两点&#xff1a; 在额外空间充足的情况下&#xff0c;尽量增大桶的数量使用的映射函数能够将输入的 N 个数据均匀的分…

【C语言】字符串函数介绍

目录 前言&#xff1a; 1. strlen 函数 函数介绍 strlen 函数的使用 strlen 函数的模拟实现 2. strcpy 函数 函数介绍 strcpy 函数的使用 strcpy 函数的模拟实现 3. strcat 函数 函数介绍 strcat 函数的使用 strcat 函数的模拟实现 4. strcmp 函数 函数介绍 st…

4K Video Downloader forMac/win:畅享高清视频下载的终极利器!

在如今的数字时代&#xff0c;高清视频已经成为人们生活中不可或缺的一部分。无论是观看精彩的电影、音乐视频&#xff0c;还是学习教育类的在线课程&#xff0c;我们都希望能够以最清晰流畅的方式来欣赏。而为了满足这一需求&#xff0c;我们需要一款功能强大的高清视频下载软…

工业平板电脑定制_三防平板电脑安卓主板厂家

工业平板电脑具有IP68级三防品质&#xff0c;采用高强度工业材质制造&#xff0c;结构稳固坚韧&#xff0c;具备较高的抗冲击和防震能力。隔空减震技术进一步加强了产品的抗冲击和防震动功能。广泛应用于工控、医疗、电信、电力、工业自动化设备、汽车检测、制造业等多个领域&a…

Flink实时数仓同步:快照表实战详解

一、背景 在大数据领域&#xff0c;初始阶段业务数据通常被存储于关系型数据库&#xff0c;如MySQL。然而&#xff0c;为满足日常分析和报表等需求&#xff0c;大数据平台采用多种同步方式&#xff0c;以适应这些业务数据的不同存储需求。这些同步存储方式包括离线仓库和实时仓…

MySQL数据库入门

MySQL数据库概述 1&#xff0c;为什么要使用数据库2&#xff0c;数据库的相关概念3&#xff0c;常见的数据库管理系统4&#xff0c;MySQL介绍5&#xff0c;关系型数据库和非关系型数据库6&#xff0c;关系型数据库的设计规则7&#xff0c;表的关联关系7.1&#xff0c;一对一7.2…

短剧小程序开发:打造高效、便捷的娱乐体验

随着移动互联网的普及和用户需求的多样化&#xff0c;短剧小程序作为一种新型的应用形态&#xff0c;逐渐受到了广大用户的青睐。短剧小程序开发旨在为用户提供一种高效、便捷的娱乐体验&#xff0c;让用户在忙碌的生活中轻松享受到精彩的短剧内容。本文将探讨短剧小程序开发的…