唯品会so层api_sign算法

声明 
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除!

目录

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除!

前言

抓包

定位加密函数

native层分析

​编辑 post请求python还原算法

总结

前言

上一篇文章是一个半月前了,还是web的,因为博主一直在学android的内容,所以断更了很久,本期带来的是唯品会so层api_sign

设备: pixel4 android10

下载地址: aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9hcHBzLzMxNTgzL2hpc3Rvcnlfdjc0NTA2

版本: 7.45.6

抓包工具: charles配合socksdroid

本来是准备搞最新版的,奈何我的frida启动新版的会闪退,不知道是app检测了还是我的frida版本的问题,这里先埋个坑,后面能解决了再回头看

唯品会so层api_sign算法_第1张图片

抓包

1. 搜索一个商品后往下滑翻个页,一共两个包,复制curl出来 文本对比

唯品会so层api_sign算法_第2张图片

2. 发现是通过传商品id进行翻页的,商品id由另一个包里返回,就是说只有头部的api_sign是变化的,把他注释掉返回的是API signature must not be empty,看来这是必须要分析的,观察它的长度是40位,猜测可能是sha1或者hmacsha1,不确定是在java层还是so层,这里我用算法助手hook了一下摘要算法和hamc算法发现搜不到加密的参数,有可能是魔改的java层或者在so层

定位加密函数

3. 把app拖到jadx里反编译后搜索关键字 api_sign

唯品会so层api_sign算法_第3张图片

4. 这里第二个很像,双击点进去瞅瞅,如下图

唯品会so层api_sign算法_第4张图片

5. 从b.b点进去瞅瞅 

6. 传进来第一个参数是一个上下文对象,第二个treemap对象,三四是两个str,再点进a这个函数里看看

唯品会so层api_sign算法_第5张图片

7. 正常情况下返回apisign,从apiSign点进去,这里我就贴几张图快进一下 

唯品会so层api_sign算法_第6张图片

唯品会so层api_sign算法_第7张图片

8. 这里是关键了,如下图

唯品会so层api_sign算法_第8张图片

9. 找到com.vip.vcsp.KeyInfo这个类里的gs,发现它调用了gsNav这个native方法 ,这个native方法加载自LibName,点进去是keyinfo,所以是libkeyinfo.so

唯品会so层api_sign算法_第9张图片

native层分析

10. 未发现java层算法猜测是so层,掏出ida分析libkeyinfo.so,在exports导出表里搜索gsnav发现是静态注册

唯品会so层api_sign算法_第10张图片

11. 点进去后f5转成伪c代码 

唯品会so层api_sign算法_第11张图片

12. 从j_Functions_gs进去后拉到最下面看返回值 

唯品会so层api_sign算法_第12张图片

13. j_getByteHash有点可疑,点进去看看 

14. 发现调用了getByteHash,再从getByteHash点进去

唯品会so层api_sign算法_第13张图片

15. 发现sha1字眼,十有八九是sha1算法了,有没有魔改还得验证,所以可以hook getByteHash这个函数Module.findExportByName("libkeyinfo.so", "getByteHash"),函数名以汇编中出现的为准

唯品会so层api_sign算法_第14张图片

16. 开着hook和抓包,在输出里搜索api_sign的值

唯品会so层api_sign算法_第15张图片

唯品会so层api_sign算法_第16张图片17. 把传进去的明文找个sha1验证一下

唯品会so层api_sign算法_第17张图片

18. 对比后发现是标准sha1,接着分析传进去的参数, 通过搜索可以发现传进去的参数前32位是盐值,后40位看起来也像是sha1,接着往上看,发现传进去的明文是盐值加表单参数拼接的字符串

唯品会so层api_sign算法_第18张图片

19. 复制出来验证一下发现也是标准sha1,到这里流程就清晰了 sha1(a84c5883206309ad076deea939e850dc + 请求参数拼接后的字符串) , 得到第一次哈希值 sha1(a84c5883206309ad076deea939e850dc + 第一次哈希值), 得到第二次哈希值,即头部的api_sign

唯品会so层api_sign算法_第19张图片 post请求python还原算法

import hashlib
data = {
    "api_key": "23e7f28019e8407b98b84cd05b5aef2c",
    "app_name": "shop_android",
    "app_version": "7.45.6",
    "channel_flag": "0_1",
    "client": "android",
    "client_type": "android",
    "context": "",
    "darkmode": "0",
    "deeplink_cps": "",
    "did": "0.0.8b7c1485b5c14a39511af05c7ab3fe77.1c7d15",
    "extParams": "{\"showSellPoint\":\"1\",\"mclabel\":\"1\",\"cmpStyle\":\"1\",\"ic2label\":\"1\",\"reco\":\"1\",\"vreimg\":\"1\",\"floatwin\":\"1\",\"preheatTipsVer\":\"4\",\"exclusivePrice\":\"1\",\"stdSizeVids\":\"\",\"rank\":\"2\",\"couponVer\":\"v2\",\"live\":\"1\"}",
    "fdc_area_id": "103102102106",
    "mars_cid": "ca80df7a-08a6-3f45-9ed5-212f6205aed2",
    "mobile_channel": "kowd7uq2:::",
    "mobile_platform": "3",
    "other_cps": "",
    "page_id": "page_te_commodity_search_1698026503833",
    "phone_model": "Pixel 4",
    "productIds": "6920468238887599571,6920201626111489235,6920494379145106643,6920505600051864787,6920513277897073875,6920401603189915987,6920260684243911507,6920474112576265683,6920472644902059475,6919453468868617043,6920513277897061587,6920403066637577683,6920442067411766547,6920504144689169619,6920513176371332307,6920482408805473747,6920401603206828371,6920504144689288403,6920516119363553747,6920201626128426195",
    "province_id": "103102",
    "referer": "com.achievo.vipshop.search.activity.VerticalTabSearchProductListActivity",
    "rom": "Dalvik/2.1.0 (Linux; U; Android 10; Pixel 4 Build/QQ2A.200405.005)",
    "scene": "search",
    "sd_tuijian": "0",
    "session_id": "ca80df7a-08a6-3f45-9ed5-212f6205aed2_shop_android_1698026465696",
    "skey": "2d30297ff20ec9b7442dc4f3c335abdc",
    "source_app": "android",
    "standby_id": "kowd7uq2:::",
    "sys_version": "29",
    "timestamp": "1698026513",
    "warehouse": "VIP_SH"
}
string = ""
for key, value in data.items():
    string += f"{key}={value}&"
# 去除末尾的"&"符号
string = string[:-1]
str = 'a84c5883206309ad076deea939e850dc'+string
sign1 = hashlib.sha1(str.encode('utf-8')).hexdigest()
api_sign = hashlib.sha1(('a84c5883206309ad076deea939e850dc'+sign1).encode('utf-8')).hexdigest()
print(api_sign)

总结

1出于安全考虑,本章未提供完整流程,调试环节省略较多,只提供大致思路,具体细节要你自己还原,相信你也能调试出来.

2本人写作水平有限,如有讲解不到位或者讲解错误的地方,还请各位大佬在评论区多多指教,共同进步,也可加本人微信lyaoyao__i(两个_)

你可能感兴趣的:(安卓逆向,python,开发语言,android,安全,java,android,studio,javascript)