某运动APP登录协议分析
因为一直忙于考试,很久没有学习了,今天随意分析了一个app就当是恢复训练了
某APP登录协议分析
一、抓包
主要分析的是该APP的手机验证登录协议,首先启动Fillder开始抓包,打开该app,输入相关手机号和验证码
抓到的包如下:
POST https://api.gotokeep.com/account/v2/sms HTTP/1.1
Content-Type: application/json; charset=UTF-8
Content-Length: 163
Host: api.gotokeep.com
Connection: Keep-Alive
Accept-Encoding: gzip
x-os-version: 5.1.1
x-geo: 0.0,0.0
x-channel: adhub_cpa__siruifan_04
x-ads: gYdZHMFkdTLC1JvfK4AsSmouEN3+S+OsjkFGaZ9kygpo/FGeJ5N7iJdMyIBtadqqUBgJnRBFi+Ri6KYKwFCVqFVPgWMaqbAAp5JiY9yFM4rGVByS9EsGHY0DB9ekNkSw+9v/Xu/BsbMxxEm9Et4MJT4QbLGf9ifhngIO3aDdE3bN+3aB801nvmOb8ZYsJ2U4Mw2sAGcnJrcDFU2kX3ASbUfhJYGWCkELV8Y6iKoPrPr/wNfkDmtuWUNYUSpSdYlPWWrANkgrPW5YL4wWIQwfVf7cDX5ItxTOGl00XYlKUcnwOsm6JAjdF5Voc0u9mmiT
x-locale: zh--CN
x-screen-height: 800
x-is-new-device: true
x-carrier: 70120
User-Agent: Keep+6.43.0%2FAndroid+5.1.1-24528+Xiaomi+MI+9
x-manufacturer: Xiaomi
x-keep-timezone: Asia/Shanghai
x-timestamp: 1594278593217
x-screen-width: 450
x-connection-type: 4
x-app-platform: keepapp
x-os: Android
x-device-id: 865166020644319111111111111111119da6a866
x-version-name: 6.43.0
x-user-id:
x-version-code: 24528
x-model: MI+9
sign: 5257caf9b35de7f6f9805f3e814773036f6c73e1
二、X-ads
首先分析x-ads:
x-ads: gYdZHMFkdTLC1JvfK4AsSmouEN3+S+OsjkFGaZ9kygpo/FGeJ5N7iJdMyIBtadqqUBgJnRBFi+Ri6KYKwFCVqFVPgWMaqbAAp5JiY9yFM4rGVByS9EsGHY0DB9ekNkSw+9v/Xu/BsbMxxEm9Et4MJT4QbLGf9ifhngIO3aDdE3bN+3aB801nvmOb8ZYsJ2U4Mw2sAGcnJrcDFU2kX3ASbUfhJYGWCkELV8Y6iKoPrPr/wNfkDmtuWUNYUSpSdYlPWWrANkgrPW5YL4wWIQwfVf7cDX5ItxTOGl00XYlKUcnwOsm6JAjdF5Voc0u9mmiT
我们通直接搜索字符串,收到了x-ads,
显然b()返回的就是我们要分析的字符串,直接进去
可以看到b方法也就是将一些参数进行序列化,然后调用m.b()处理后返回
继续跟进
到这里我们就可以得到这个加密算法是AES算法,通过AES算法进行加密后再进行base64编码,对应AES算法,我们可以看到IV已经给出2346892432920300
,key是由一个c(CypLib.a())
返回的
继续分析发现CypLib.a()有两种返回值,若为true则进入native方法进行计算,若为false,则直接返回一个key。
那么怎么判断这个key呢,大概有下面几种思路
(1)查找a(Context context)的交叉引用,判断在对字符串进行加密处理时,是否调用了该方法,若没有调用
,就会返回false,直接对"Pl*Rxe76fx'fWWqR"加密,反之"Pl*Rxe76fx'fWWqR"就会进入native层进行处理。(2)由于只有这两个key,我们可以通过穷举的方式,直接分析得出这两个key,当然也是比较复杂的(3)动态调试smali代码,直接定位到返回的地方,获取c()方法的返回值(4)frida Hook直接找到c()方法返回值
显然通过分析,使用动态调试或者frida hook会简单很多,如果采用(1),(2)分析的话就很有可能需要分析so文件,这里可能需要手动copy一下so层伪c代码,然后修改运行,得到返回值。
这里直接采用frida hook,关于frida hook的教程很多,这里不多赘述,启动frida-server,运行脚本如下
import frida, sysdef on_message(message, data):if message['type'] == 'send':print("[*] {0}".format(message['payload']))else:print(message)jscode = """
Java.perform(function () {var m = Java.use('l.q.a.y.p.m');m.c.implementation = function (param1) {send("Hook Start...");send(param1);var result=this.c(param1);send("AESKey is :"+result);return result;}
});
"""process = frida.get_usb_device().attach('com.gotokeep.keep')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()
最后可以得到key
到这一步,x-ads算法的主要逻辑就已经弄清楚了,
key=56fe59;82g:d873c,iv=2346892432920300
那么直接开始解密操作:
import base64
from Crypto.Cipher import AES
def base64_encode(bdate):return base64.b64encode(bdate).decode()def base64_decode(date_str):return base64.b64decode(date_str)def aes_decrypt(Key,iv,crypted):decryptor=AES.new(Key,AES.MODE_CBC,iv=iv)return decryptor.decrypt(crypted)def aes_encrypt(Key,iv,raw_data):if isinstance(raw_data,str):raw_data=raw_data.encode()#不满足8的倍数补齐if len(raw_data)%8 !=0:pad_len=8-(len(raw_data)%8)raw_data+=bytes([pad_len]*pad_len)encryptor=AES.new(Key,AES.MODE_CBC,iv=iv)return encryptor.encrypt(raw_data)if __name__=='__main__':import jsonkey='56fe59;82g:d873c'.encode()iv='2346892432920300'.encode()data='gYdZHMFkdTLC1JvfK4AsSmouEN3+S+OsjkFGaZ9kygpo/FGeJ5N7iJdMyIBtadqqUBgJnRBFi+Ri6KYKwFCVqFVPgWMaqbAAp5JiY9yFM4rGVByS9EsGHY0DB9ekNkSw+9v/Xu/BsbMxxEm9Et4MJT4QbLGf9ifhngIO3aDdE3bN+3aB801nvmOb8ZYsJ2U4Mw2sAGcnJrcDFU2kX3ASbUfhJYGWCkELV8Y6iKoPrPr/wNfkDmtuWUNYUSpSdYlPWWrANkgrPW5YL4wWIQwfVf7cDX5ItxTOGl00XYlKUcnwOsm6JAjdF5Voc0u9mmiT'crypted=base64_decode(data)decrypt=aes_decrypt(key,iv,crypted)print(decrypt.decode())
运行python脚本,得到结果
{"imei":"865166020644319","adua":"Mozilla\/5.0 (Linux; Android 5.1.1; MI 9) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/4.0 Chrome\/70.0.3538.64 Mobile Safari\/537.36","androidId":"e2437690c1181ef5","device":"phone","oaid":""}
同理,可以分析得出x-device-id
三、sign
我们全局搜索sign字段,发现了一个极有可能的地方
通过分析我们可以得出,sb和各种值进行的拼接,然后通过l.q.a.y.p.b0.a(sb.toString()),进行了一次MD5得到32位的值,再进入CrypLib.a()方法中进行判断
这里我们不妨进入native层看看
jstring __fastcall Java_com_gotokeep_keep_common_utils_CrypLib_getEncryptDeviceId(JNIEnv *a1, jclass a2, jstring a3)
{int v3; // r3int v4; // r0int v5; // r3jstring v7; // [sp+4h] [bp-70h]JNIEnv *v8; // [sp+Ch] [bp-68h]int v9; // [sp+14h] [bp-60h]signed int i; // [sp+18h] [bp-5Ch]char *s; // [sp+1Ch] [bp-58h]int v12; // [sp+24h] [bp-50h]int v13; // [sp+28h] [bp-4Ch]int v14; // [sp+2Ch] [bp-48h]int v15; // [sp+34h] [bp-40h]int v16; // [sp+38h] [bp-3Ch]int v17; // [sp+3Ch] [bp-38h]int v18; // [sp+40h] [bp-34h]int v19; // [sp+44h] [bp-30h]int v20; // [sp+48h] [bp-2Ch]int v21; // [sp+4Ch] [bp-28h]int v22; // [sp+50h] [bp-24h]int v23; // [sp+54h] [bp-20h]int v24; // [sp+58h] [bp-1Ch]int v25; // [sp+5Ch] [bp-18h]char v26; // [sp+60h] [bp-14h]char v27[12]; // [sp+68h] [bp-Ch]v8 = a1;v7 = a3;if ( getSignHashCode(a1) != 1580769512 )return v7;s = ((*v8)->GetStringUTFChars)(v8, v7, 0);v16 = 0;v17 = 0;v18 = 0;v19 = 0;v20 = 0;v21 = 0;v22 = 0;v23 = 0;v24 = 0;v25 = 0;v26 = 0;if ( strlen(s) == 32 ){v9 = 0;for ( i = 7; i >= 0; --i ){v27[i - 48] = s[i];v27[i - 40] = s[i + 8];v27[i - 32] = s[i + 16];v27[i - 24] = s[i + 24];v12 = get_int(s[i]);v13 = get_int(s[i + 8]);v14 = get_int(s[i + 16]);v4 = get_int(s[i + 24]);v15 = v12 + v13 + v14 + v4 + v9 + 929;v5 = v12 + v13 + v14 + v4 + v9 + 929;if ( v5 < 0 )v5 = v12 + v13 + v14 + v4 + v9 + 944;v9 = v5 >> 4;v27[i - 16] = get_char(v15 % 16);}((*v8)->ReleaseStringUTFChars)(v8, v7, s);v3 = ((*v8)->NewStringUTF)(v8, &v16);}else{((*v8)->ReleaseStringUTFChars)(v8, v7, s);v3 = v7;}return v3;
}
是一个特别简单的算法,让人不解的是
这里居然进行了一次签名校验,而且居然直接把签名校验值返回了,看到这里如果想要修改相关资源文件就变得很容易了
然后,我们分析一下sb字段的拼接结果,直接使用frida hook l.q.a.y.p.b0.a(sb.toString())
获取到入参即可,代码还是和上一个差不多,但这里有一个小小的不同点,a是一个重载方法,要记得用overload(‘入参类型’)来区别
import frida, sysdef on_message(message, data):if message['type'] == 'send':print("[*] {0}".format(message['payload']))else:print(message)jscode = """
Java.perform(function () {var b0 = Java.use('l.q.a.y.p.b0');b0.a.overload('java.lang.String').implementation = function (param1) {send("Hook Start...");send("sb is"+param1);var result=this.a(param1);send("ret is :"+result);return result;}
});
"""process = frida.get_usb_device().attach('com.gotokeep.keep')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()
打印结果为:
[*] Hook Start...
[*] sb is{"captcha":"1111","countryCode":"86","countryName":"CHN","mobile":"18202870881","type":"login"}/account/v3/login/smsV1QiLCJhbGciOiJIUzI1NiJ9
总结
总的来说,这个app比较简单,而且很多的逻辑写的也不是很好,通过frida Hook就能很快的获取关键值
某运动APP登录协议分析相关推荐
- 某app登录协议逆向分析
某app登录协议逆向分析 设备 iphone 5s Mac Os app:神奇的字符串57qm5Y2V 本文主要通过frida-trace.fridaHook.lldb动态调试完成破解相应的登录算法, ...
- webqq登录协议分析
webqq登录协议分析 通过webqq接口,可以实现发送.接收qq消息. 1.首先调用:http://ptlogin2.qq.com/check?appid=1002101&uin=qq号码& ...
- 某游戏盒登录协议分析
前言 距离上次写博客已经过去了一个月,博主本人在这期间也分析了不少案列,这次分享一个比较综合的案例,难易程度偏简单,适合协议分析练手,下面直接进入正题. 准备工作 首先我们得安装抓包软件,我这里是用F ...
- 小米登录协议分析_小米智能家居设备流量分析及脚本控制
原标题:小米智能家居设备流量分析及脚本控制 *本文作者:scu-igroup,本文属 FreeBuf 原创奖励计划,未经许可禁止转载. 前言 万物互联的时代即将来临,而现阶段,我们能感触到的,当属智能 ...
- 小米登录协议分析_小米回应小米11充电头兼容问题
小米11从上市销售至今已经几天时间,相信第一批入手的消费者也都收到了这款骁龙888旗舰.从网友们的使用反馈来看,小米11(点此查看评测)在充电方面出现了一些问题,并且该问题现在得到了官方的回应.元旦期 ...
- 小米登录协议分析_小米温湿度传感器协议分析
博主喜欢玩智能家居的东西,智能家居确实能给家里带了不少的方便. 天气热了,博主想做一个:当屋子有人,并温度高于33度时,开空调.博主已有了一套自家的智能家居系统,有网关.人体红外传感器.红外转发器,就 ...
- 小米登录协议分析_性能测试篇之Loadrunner与ida工具结合完成java vuser协议的脚本...
你这么优秀,一定只想把"柠檬班"置顶 ▲ → 性能3期优秀作业 利用lr的java vuser协议完成 (登录,md5加密完成重置支付密码,获取订单列表)请求,并加if判断完善脚本 ...
- “陌x”登录协议分析
1.抓包 抓两次 2.对比 3.我们来方法刨析一下 登录 他一定有一个点击事件 我们搜onclick 方法刨析了一下 发现没找到有效的信息 4.我们来直接使用jadx-gui来搜索抓取到的字段 居然只 ...
- 小米登录协议分析_联想前副总裁常程跳槽小米数月后,波澜再起
► 文 观察者网 吕栋今年初,联想集团前副总裁常程离职2天即加盟小米,这一举动是否违反竞业协议,双方当时曾各执一词.最近,由于联想方面在北京提起劳动仲裁,此事也再度引发舆论关注.9月21日,针对&q ...
- IOS 最右 注册 登录协议分析记录
目前 App Store 最新版是V5.5.28 我用的是V5.5.27 下载后载入Xcode ,准备进行动态调试 进程:tieba 不料有反调试这个文件打开,并打开这个注释,就可以调试了 经过追中 ...
最新文章
- call_user_func
- Spring - Java/J2EE Application Framework 应用框架 第 9 章 DAO支持
- java arraylist 源代码_Java中ArrayList源码浅析
- SAP CRM WebClient UI和CRM Fiori应用里Opportunity的显示过滤逻辑
- layui 数字步进器_图解全新奔驰S级:从“传统豪华”向“数字豪华”转型
- 电脑装机完没有efi_电脑装机如何选内存?看完这篇就全懂了
- 老李谈HTTP1.1的长连接
- ORA-15260 diskgroup space exhausted Problem
- 无需第三方app,清理Mac缓存垃圾
- 10 个功能独特且饱受好评的开源人工智能项目
- C# 访问 带密码的access数据库
- 前端开发之谷歌实用插件fehelper JSON助手
- eNSP实验二:VLAN划分与配置
- 抖音怎么去除水印方法及小工具
- Vue中报如下错误Uncaught (in promise) NavigationDuplicated解决方案
- openGL中向量的加减乘除运算
- jQuery播放音乐
- python(第九天)
- java学习之服务器第28天( --jsp--三个指令--六个动作标签--PageContext域--EL表达式--)
- perl mysql 数据推拉_用perl 从mysql取出数据做统计分析代码
热门文章
- 计算机中word音乐符号在哪里找,word音乐符号怎么打出来|word音乐符号怎么打
- 西工大机考《概率论与数理统计》大作业网考
- 单片机学习方法总结资料分享
- 复旦大学《高等代数学(第三版)》教材勘误表
- iso22000食品安全管理体系_ISO22000-食品安全管理体系认证
- Java实现最简单局域网QQ
- 凤凰职教网计算机一级成绩查询,一-凤凰职教网.PPT
- 服务器系统如何设置屏幕保护,在windows中要设置屏幕保护程序可以使用控制面板的什么功能?_网站服务器运行维护,windows,屏幕保护程序,控制面板...
- Java调用WebService接口
- VB编程的RS485通讯操作界面源码 本程序适应各类带RS485通讯的设备,参数可以自由修改,主要是针对各类变频器RS485通讯(RTU)格式!