当前位置: 首页 > news >正文

安卓逆向 - 某严选app sign算法还原

本文仅供学习交流,只提供关键思路不会给出完整代码,严禁用于非法用途,若有侵权请联系我删除!

目标app: 5ouN5ouN5Lil6YCJMy45LjY=

目标接口:aHR0cHM6Ly9hcGkubS5qZC5jb20vYXBp

一、引言

1、本篇分析某二手交易平台 pp严选关键词搜索涉及的加密 sign,body

二、抓包分析

1、安装app至模拟器上,开启Fiddler,按下图配置代理

 2、成功抓到包,发现请求body中sign,body字段存在加密字符串。

 三、sign参数

1、使用Jadx反编译apk,全局搜索sign。我们会发现出来太多行代码,不太好分析。推荐一个搜索小技巧,改为搜索 put("sign"  ,"sign" 等字段,刷选有用信息。

调整搜索后,出来几条关键信息:

 我们跟进去,定位到关键代码:

hashMap2.put("sign", xu2.b(hashMap2, "6ab527a5d7f643728bac669543b92727"));

 hook验证:

function hook() {var xu2 = Java.use("com.jd.paipai.ppershou.xu2");xu2["b"].implementation = function (hashMap, str) {// console.log(`xu2.b is called: hashMap=${hashMap}, str=${str}`);console.log("hashMap: " + hashMap)var result = this["b"](hashMap, str);console.log("result: " + result);return result;};
}

 hook到结果,发现和我们抓包中的sign一模一样。说明成功找到生成位置!

hashMap: {loginType=4, networkType=wifi, screen=720x1280, functionId=pp.own.channel.biz.inspect.search.list, uuid=1682eadfa03390e9, appid=ppershou, body={"query":{"latitude":"y5Oa2ZqV2qDqdXdnpqHFSA==","recheck":1,"pageNo":1,"longitude":"rvV+ggPmeJQ53yaoJh+lyQ==","key":"iPhone13","pageSize":16}}, ext={"privacyAgreed":1,"referer":"paipai\/android\/3.9.6\/SearchIndexActivity"}, t=1692082902668, build=309060, client=paipai_android, clientVersion=309060, osVersion=Android 7.1.2, partner=ppershou, channel=QIHOO}
result: 05f61ee02e05db33f4a2a6358f07a7a8668cc7992256548d23153199e1b5c83e

2、sign算法还原,观察生成代码,非常明显的HmacSHA256加密特征,遍历Map, 填充&字符后拼装在一起,做HmacSHA256加密,key是 6ab527a5d7f643728bac669543b92727。

 我们将代码抠出来执行,缺啥补啥。

    /*** HmacSHA256加密* @param hashMap 请求体中的值* @param str 秘钥* @return 加密后的字符串*/public static String b(HashMap<String, String> hashMap, String str) {if (hashMap.isEmpty() || TextUtils.isEmpty(str)) {return null;}TreeSet<String> treeSet = new TreeSet<>(hashMap.keySet());StringBuilder stringBuffer = new StringBuilder();for (Object o : treeSet) {String str3 = hashMap.get(o.toString());if (!TextUtils.isEmpty(str3)) {stringBuffer.append(str3);stringBuffer.append(FIELD_DELIMITER);}}String stringBuffer2 = stringBuffer.toString();if (stringBuffer2.endsWith(FIELD_DELIMITER) && stringBuffer2.length() > 1) {stringBuffer2 = stringBuffer2.substring(0, stringBuffer2.length() - 1);}byte[] bytes = stringBuffer2.getBytes();try {SecretKeySpec secretKeySpec = new SecretKeySpec(str.getBytes(), "HmacSHA256");Mac mac = Mac.getInstance("HmacSHA256");mac.init(secretKeySpec);return a(mac.doFinal(bytes));} catch (InvalidKeyException | NoSuchAlgorithmException e) {e.printStackTrace();return null;}}

直接执行,得到结果,还原成功!

 四、body参数

1、body参数为如下这一串,经过我调试验证 hdid是写死的。

body={"hdid":"JM9F1ywUPwflvMIpYPok0tt5k9kW4ArJEU3lfLhxBqw=","ts":1692081460878,"ridx":-1,"cipher":{"body":"oyTndWVyoIS6oyTiYXHfdRVuZIS6Sxu1J2OyWxPWCxPOcWHYZQ5mcUrQU0O9FISiSxTvY2rvY2isEtOiSxLrZ2VEbyS6CImsbQ9kZ2v0dWHvStescxZWA2dxUQ1vIvO1C3vrb0feA2n5UJ09Ssmsa2V5StesaVLeb25vCJCsBMTmYWdvU2v6ZIS6CJZ9pG=="},"ciphertype":5,"version":"1.2.0","appname":"com.jd.paipai.ppershou"}

2、回到sign的位置,上面一行是body的赋值。我们可以根据这个打出堆栈往上分析。

 hashMap2.put("body", new JSONObject(map).toString());

或者直接搜索JM9F1ywUPwflvMIpYPok0tt5k9kW4ArJEU3lfLhxBqw= 这个固定值,很快能定位到关键位置。

 

 往上找到算法是个native方法,时间紧张,我们直接hook上层方法:

function hook9() {var dc2 = Java.use("com.jd.paipai.ppershou.dc2");dc2["a"].implementation = function (map) {var jsonObj = Java.use('org.json.JSONObject').$new(map);console.log("map : " + jsonObj.toString())var result = this["a"](map);console.log("result: " + result);return result;};
}

返回结果就是我们想要的!!!

入参:{"body":"{\"query\":{\"latitude\":\"cwLVo6aFXtB6JuOJauet+Q==\",\"recheck\":1,\"pageNo\":1,\"longitude\":\"Ex5uLAbq5hktzPkRkng\\\/vw==\",\"key\":\"小米\",\"pageSize\":16}}"}result:{"hdid":"JM9F1ywUPwflvMIpYPok0tt5k9kW4ArJEU3lfLhxBqw=","ts":1691647002731,"ridx":-1,"cipher"

搭建RPC主动调用。收工收工!

http://www.lryc.cn/news/125215.html

相关文章:

  • arcgis数据采集与拓扑检查
  • 【前端 | CSS】滚动到底部加载,滚动监听、懒加载
  • word将mathtype公式批量转为latex公式
  • docker-compose部署nacos 2.2.3
  • 软件测试52讲-学习笔记
  • 【ARM 嵌入式 编译系列 4 -- GCC 编译属性 __read_mostly 详细介绍】
  • Maven在IDEA2021版本中全局配置(一次配置处处生效)
  • 名侦探番外——Arduino“炸弹”引爆摩天大楼
  • 自适应AI chatgpt智能聊天创作官网html源码
  • 防抖,节流
  • 【Linux】多线程1——线程概念与线程控制
  • 【Maven】SpringBoot项目使用maven-assembly-plugin插件多环境打包
  • 指令集_基础
  • 学习Vue:数据绑定的基本概念
  • Python 装饰器 - 推导式(列表推导式) - 迭代器 - 生成器 - 闭包
  • 【大数据】Flink 详解(二):核心篇 Ⅲ
  • Jmeter性能测试系列-性能测试需求分析
  • Syncfusion Essential Studio JavaScrip Crack
  • 8.13黄金是否进入下行通道?下周开盘如何布局
  • Idea的基本使用带案例---详细易懂
  • MySQL中的用户管理
  • 【STM32】利用CubeMX对FreeRTOS用按键控制任务
  • c# .net mvc的IHttpHandler奇妙之旅--图片文件请求安全过滤,图片防盗链
  • STM32F407使用Helix库软解MP3并通过DAC输出,最精简的STM32+SD卡实现MP3播放器
  • STM32 CAN 过滤器设置
  • 日常BUG—— maven编译报错
  • Unity 工具 之 Azure 微软SSML语音合成TTS流式获取音频数据的简单整理
  • 学习Vue:插值表达式和指令
  • echart 3d立体颜色渐变柱状图
  • linux shell变量