-
免责声明
由于传播、利用本公众号所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。
APP抓包:
打开app,进正常的抓包配置,输入任意账号和密码并发送登录请求,请求如下
可以看到请求中对密码进行了加密,回显的信息为明文信息。
测试另外两个字段发现存在签名校验。
将app拖入jadx中进行分析,在AndroidManifest.xml中查看启动时的入口类com.che168.autotradercloud.ATCApplication.
全局搜索pwd关键词,由于入口类为com.xxxx.autotradercloud.ATCApplication,所以加密算法大概率在com.xxxx.autotradercloud下,通过包名可以看到存在与user相关的。
通过查找最终定位到登录的请求方法,可以看到此处的str3参数经过SecurityUtil.encodeMD5进行md5加密然后作为了pwd的值进行post请求。
publicstaticvoidloginByPassword(String str, String str2, String str3, String str4, String str5, ResponseCallback<UserBean> responseCallback) {
HttpUtil.Builder builder = newHttpUtil.Builder();
builder.tag(str).method(HttpUtil.Method.POST).signType(1).url(LOGIN_URL).param("username", str2).param("type", str4).param("signkey", str5).param("pwd", SecurityUtil.encodeMD5(str3));
doRequest(builder, responseCallback, newTypeToken<BaseResult<UserBean>>() { // from class: com.che168.autotradercloud.user.model.UserModel.5
}.getType());
}
双击encodeMD5进行跟踪,方法如下:
回到我们的请求,密码的明文为1qaz2WSX,密文为8c97677e7cf25c075d5a0f8c907daaca,经过再次发送请求验证发现密文并没有进行变化,说明此处没有添加随机数。但通过前后对比发现
那么通过md5加密工具,对明文进行加密,发现与请求中的相同,说明加密方法没有进行魔改。
所以此时我们已经定位了密码的加密方法。通过发包对比,udid和_sign的值每次发送请求都会变。所以我们直接通过frida的自吐脚本算法来确定加密的方法和密钥。
开启frida监听
开启app然后使用自吐脚本进行hook如下所示
发送请求并对请求进行拦截,发送到重放器。
在终端搜索_sign的值和udis即可定位到相关的加密明文
将这两段取出进行分析。
首先是udid,加密方式为des加密,密钥:appapiche168comappapiche,偏移量:appapich,明文为:865300049928839|9032043468740|404472
然后是_sign通过明文分析发现由多个字段构成,是将post数据前后加上了固定字段W@oC!AH_6Ew1f6%8,然后进行md5加密形成_sign。
那这里面的值就只有udid我们不知道其加密明文是怎么构成的了。所以下面我们要对udid的加密方式进行定位,查看其明文获取的方式。
W!AH_6Ew1f6%8
_appid atc.android
appversion 3.47.0
channelid csy
pwd 8c97677e7cf25c075d5a0f8c907daaca
signkey
type
udid
mpNM4kti7ieW9syCMdRp+hDKaszt+12Zw2Jx+aOmdu9ZmCgi2PeU6A==
username 15236478965
W!AH_6Ew1f6%8
==============================desede/CBC/PKCS5Padding==============================
desede/CBC/PKCS5Paddinginit mode 1
desede/CBC/PKCS5Paddinginit key Utf8: appapiche168comappapiche
desede/CBC/PKCS5Paddinginit key Hex:
617070617069636865313638636f6d617070617069636865
desede/CBC/PKCS5Paddinginit key Base64: YXBwYXBpY2hlMTY4Y29tYXBwYXBpY2hl
desede/CBC/PKCS5Paddinginit iv Utf8: appapich
desede/CBC/PKCS5Paddinginit iv Hex: 6170706170696368
desede/CBC/PKCS5Paddinginit iv Base64: YXBwYXBpY2g=
==============================desede/CBC/PKCS5Padding==============================
desede/CBC/PKCS5Padding update data Utf8: 865300049928839|9032043468740|404472
desede/CBC/PKCS5Padding update data Hex:
3836353330303034393932383833397c393033323034333436383734307c343034343732
desede/CBC/PKCS5Padding update data Base64:
ODY1MzAwMDQ5OTI4ODM5fDkwMzIwNDM0Njg3NDB8NDA0NDcy
desede/CBC/PKCS5Padding doFinal result Hex:
9a934ce24b62ee2796f6cc8231d469fa10ca6accedfb5d99c36271f9a3a676ef59982822d8f794e8
desede/CBC/PKCS5Padding doFinal result Base64:
mpNM4kti7ieW9syCMdRp+hDKaszt+12Zw2Jx+aOmdu9ZmCgi2PeU6A==
==============================MD5==============================
MD5 update data Utf8:
W!AH_6Ew1f6%8_appidatc.androidappversion3.47.0channelidcsypwd8c97677e7cf25c075d5a0f8c907daacasignkeytypeudidmpNM4kti7ieW9syCMdRp+hDKaszt+12Zw2Jx+aOmdu9ZmCgi2PeU6A==username15236478965W!AH_6Ew1f6%8
MD5 update data Hex:
57406f432141485f36457731663625385f61707069646174632e616e64726f696461707076657273696f6e332e34372e306368616e6e656c696463737970776438633937363737653763663235633037356435613066386339303764616163617369676e6b657974797065756469646d704e4d346b746937696557397379434d6452702b68444b61737a742b31325a77324a782b614f6d6475395a6d4367693250655536413d3d757365726e616d65313532333634373839363557406f432141485f3645773166362538
MD5 update data Base64:
V0BvQyFBSF82RXcxZjYlOF9hcHBpZGF0Yy5hbmRyb2lkYXBwdmVyc2lvbjMuNDcuMGNoYW5uZWxpZGNzeXB3ZDhjOTc2NzdlN2NmMjVjMDc1ZDVhMGY4YzkwN2RhYWNhc2lnbmtleXR5cGV1ZGlkbXBOTTRrdGk3aWVXOXN5Q01kUnAraERLYXN6dCsxMlp3Mkp4K2FPbWR1OVptQ2dpMlBlVTZBPT11c2VybmFtZTE1MjM2NDc4OTY1V0BvQyFBSF82RXcxZjYlOA==
==============================MD5==============================
MD5 digest result Hex:
46545d60e24fe7d30629075f316eaecf
MD5 digest result Base64: RlRdYOJP59MGKQdfMW6uzw==
开启脚本中的堆栈显示。
再次进行请求,输出如下,可以看到encode3Des是由getUDID来调用的,找到com.che168.autotradercloud.util.AppUtils.getUDID方法。
getUDID方法如下,这里我们就确定了这明文的来源,由IMEI+系统运行时间+设备id。下面我们来进行验证
publicstatic
StringgetUDID(Context context) {
return
SecurityUtil.encode3Des(context, getIMEI(context) +
HiAnalyticsConstant.REPORT_VAL_SEPARATOR + System.nanoTime() +
HiAnalyticsConstant.REPORT_VAL_SEPARATOR + SPUtils.getDeviceId());
}
查看getIMEI方法可以看到其内容是通过SharedPreferences进行存储的。
如果您有想要保存的相对较小键值对集合,则可以使用SharedPreferencesAPI。SharedPreferences对象指向包含键值对的文件,并提供读写这些键值对的简单方法。每个SharedPreferences文件均由框架进行管理,可以是私有文件,也可以是共享文件。
其保存位置为:/data/data/包名/shared_prefs/,文件名需要在代码中进行命名,所以我们往上翻找,可以看到其调用create时传入的值PREFER_NAME = "autoTraderCloud_pre"。
连接adb shell查看其文件内容cat /data/data/com.che168.autotradercloud/shared_prefs/autoTraderCloud_pre.xml可以看到存储在文件中的两个值。
到此就知道了登录请求的完整加密方式
_sign:前后加上固定的值W@oC!AH_6Ew1f6%8,将请求中除去_sign外的所有内容进行拼接,然后进行md5加密
pwd:对输入的密码进行md5加密
udid:将IMEI+系统运行时间+设备id用|进行拼接,然后进行3DES加密对加密结果进行url编码
了解完加密方式以后我们可以通过frida-rpc的方式调用加密方法来进行加密爆破登录。
算法解密代码放星球了,星球内容不多,优惠后仅需59元。
原文始发于微信公众号(思极安全实验室):某车APP加密算法分析
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论