观前提示:
本文章仅供学习交流,切勿用于非法通途,如有侵犯贵司请及时联系删除
样本:aHR0cHM6Ly9wYW4uYmFpZHUuY29tL3MvMVVRVnNwRzJvTWVCRGJLOXlvSHZmdGc/cHdkPWxpbm4=
0x1 准备工作
样本无壳 存在证书验证 使用objection脚本直接Pass
本次受害参数
jadx-gui打开样本APK
直接搜索zzzghostsigh
跳转过来查找用例
继续跳转
可能在ghostSigh
里面实现 在objection 验证一下结果
Arguments com.mfw.core.login.util.SecurityTools.ghostSigh(GET&https%3A%2F%2Fmapi.mafengwo.cn%2Fsearch%2Fsearch%2Fget_result_list%2Fv3&app_code%3Dcom.mfw.roadbook%26app_ver%3D10.8.6%26app_version_code%3D1016%26brand%3Dgoogle%26channel_id%3DTengXun%26dev_ver%3DD2218.0%26device_id%3D088fd48f2e39f6dd%26device_type%3Dandroid%26hardware_model%3DPixel%26has_notch%3D0%26jsondata%3D%257B%2522switched_search_type_by_user%2522%253A0%252C%2522page%2522%253A%257B%2522boundary%2522%253A%25220%2522%252C%2522num%2522%253A10%257D%252C%2522keyword%2522%253A%2522%25E5%25B9%25BF%25E5%25B7%259E%2522%252C%2522is_correct%2522%253A%25220%2522%252C%2522search_id%2522%253A%2522616876f0-d55b-4642-9861-49d1487d4677%2522%257D%26mfwsdk_ver%3D20140507%26o_coord%3Dgcj%26o_lat%3D23.210456%26o_lng%3D113.276382%26oauth_consumer_key%3D5%26oauth_nonce%3D20758a6d-750b-4bfb-aff4-05e194f652e4%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1670304163%26oauth_token%3D0_0969044fd4edf59957f4a39bce9200c6%26oauth_version%3D1.0%26open_udid%3D088fd48f2e39f6dd%26screen_height%3D1794%26screen_scale%3D2.88%26screen_width%3D1080%26shumeng_id%3DDurXXFIkF8p6cnynFKceRZixZovBGYlg0uwzlwlxeMcSE5umYEfhbsraVbvpLsybIFUGNsoCyBKpymAQDzelEQpg%26sys_ver%3D8.1.0%26time_offset%3D480%26x_auth_mode%3Dclient_auth) (agent) [292326] Return Value: d043330bcff1ecfe2bd3e096ab729986c6eb1e9e
得到传入明文和传出结果 接下来只需要找出具体算法实现即可
最终定位到libmfw.so
中的xPreAuthencode
其中this.a
为主动调用传入的字符串
回到上层 从这里知道传入的就是包名
从objection验证可确定
0x2 Unidbg主动调用
直接用Unidbg造个框架 无需补环境就能跑出结果
主动调用
对比结果一致
0x3 加密分析
从加密结果可知 无论我们输入的长度多长 都输出固定长度密文
那可以猜测这可能是一个哈希加密
而且输出的密文长度为40 可以猜测这是一个SHA1
那先拿到一份py的SHA1实现
github:https://github.com/alex-a-robinson/SHA1/blob/master/sha1.py
这是SHA1的一个加密流程
从中可以知道一个SHA1会经过20+20+20+20=80轮的加密 而且ABCDE贯穿了整个加密 最终得到一个40位的结果
ABCDE对应的就是魔数 每20轮对应的不同的K值 所以要判断这是不是一个SHA1只需要找到这些值就可以了
根据搜索 可以判断这是一个SHA1
那主动调用加密123456
和正常的sha1对比发现结果不一致
那猜测就是有魔改 从这里可知是从x0
里取出魔数
debugger onsole看x0
01 23 45 67 →0x67452301
89 AB CD EF →0xefcdab89
FE DC BA 98 →0x98badcfe
7C 1F 4A 5E→0x5e4a1f7c
76 54 32 10→0x10325476
原本的魔数为0x67452301
, 0xefcdab89
, 0x98badcfe
, 0x10325476
, 0xc3d2e1f0
从这里可以看到后俩个魔数被更改了 手动更正魔数运行看结果
看来不仅仅更改了魔数 存在其他魔改
从前面可知 SHA1存在80轮加密 那我们手动输出80轮加密的每个结果 对比tracecode不就行了
根据对比每轮的结果发现在第16轮的时候开始出现不同
前15轮的K值为0x5A827999
在第16次循环的时候就将K值提前换成0x6ED9EBA1
搜索0x6ED9EBA1
出现4次
验证结果
按照这个思路接着看第20轮往后到39轮使用的K值为0x8F1BBCDC
第40轮开始又用回K值为0x5A827999
根据tracecode可知这区间又出现EOR又AND可知 这里的计算方式和前16轮一致 K值也一致
搜索0x5A827999
可知一共出现了36次 减去前16轮 所以后面又使用了20轮
在60到79后跟原代码一致
所以算下来一共分为 16+4+20+20+20=80轮
if i <= 15: f = d ^ (b & (c ^ d)) k = 0x5A827999 elif i <= 19: f = b ^ c ^ d k = 0x6ED9EBA1 elif i <= 39: f = (b & c) | (b & d) | (c & d) k = 0x8F1BBCDC elif i <= 59: f = d ^ (b & (c ^ d)) k = 0x5A827999 else: f = b ^ c ^ d k = 0xCA62C1D6
验证结果发现并不完全一致 到底是哪里的问题
根据错误位置 输出h2
h3
和c
d
的值
回到tracecode搜索
从这里就可以看到0xee9397da
与之相加的是0x5e4a1f7c
而0x2ee2fec3
与之相加的是0x98badcfe
也就是需要将c
和d
的位置互相调换
最后拼接得到结果
对比结果 输出一致
感谢各位大佬观看
感谢大佬们的文章分享
如有错误 还请海涵
共同进步 带带弟弟
点赞 在看 分享是你对我最大的支持
逆向lin狗