Y29tLnNhbmt1YWkubWVpdHVhbg==
[1]我是小三大佬对2.0版本的参数分析
https://www.cnblogs.com/2014asm/p/15391247.html
[2]qxpy大佬对1.5版本的a2分析
https://mp.weixin.qq.com/s/S_3tM_TbOfbBRprmQGDwrA
[3]qxpy大佬对2.1版本的a5分析
https://mp.weixin.qq.com/s/bfGvUyIN8aS4Y1KkOWwRpQ
[4]TS大佬对风控参数的分析
https://blog.vivcms.com/2021/01/07/429.html
[5]houjingyi大佬对libmtguard.so混淆的还原分析
https://bbs.kanxue.com/thread-271853.htm
a0:mtgsig版本号(这里分析2.4)
a1:appkey(相同版本app此值固定)
a3:Android设备版本
a4:时间戳
a5:加密的设备信息1
a6:固定值
a7:xid
a8:dfp
a9:加密的设备信息2
a10:a2参数加密时需xor的随机数
x0:固定值
a2:sign值
基于对libmtguard.so的JNI方法main函数hook,如下图:
以上图片分析:
1.调用main(47)前就已经生成过mtgsig参数,证明dfp已经生成并通过对比main(47)返回值和mtgsig['a8']相等,验证猜想
2.unidbg模拟执行时,如果main(47)前调用了main(1),则会在全局变量中存储dfp并在main(47)调用用时存储到/data/data/xxx/file/.mtg_dfpid文件中
3.unidbg模拟执行时,如果只调用main(47),则会自行生成uuid和时间戳等参数构造dfp并存储到上述文件中
4.后续会发现mtgsig['a8']值会发生改变(通过后续分析则是请求返回)
这里分析来源unidbg只调用main(47)的逻辑,猜测main(1)中生成dfp算法一致
dfp算法步骤
1."0000"+uuid(去除'-')+时间戳(十六进制)+"0"+CRC(前面部分)
2.0000 8a8921de5fc14ed1b428d1d7485f99c1 18bc6958715 0 eb79a8ab
3.以上内容转成hex
4.00 00 8a 89 21 de 5f c1 4e d1 b4 28 d1 d7 48 5f 99 c1 18 bc 69 58 71 50 eb 79 a8 ab
5.固定hex(多次测试目前版本app该值固定)
6.两组hex进行xor得到结果取大写
1.从生成时间戳入手,分析地址0x17bf5(GetStringUtfChars),全局一共两处调用,第一次是uuid,第二次是时间戳
2.结合ida代码和unidbg调试代码分析方法的执行逻辑
1.0x6F68E -> bl sub_17bc4
2.0x17bc4 -> GetStringUtfChars
3.0x6f2bb -> bl #0x40006e22(解密字符串得到'0000')
4.0x6f2e1 -> bl #0x40012aa4(拼接字符串:'0000'+uuid)
5.0x6f333 -> bl #0x4002aa18(CRC算法,查看入参:"0000"+uuid(去除'-')+时间戳(十六进制)+"0")
6.0x6f375 -> bl #0x4000c8f4(拼接"0000"+uuid(去除'-')+时间戳(十六进制)+"0"+CRC(前面部分))
7.0x6f389 -> bl #0x4006ee60(入参:上诉拼接好的字符串,返回:dfp)
8.0x6efe7 -> bl #0x4006e968(String to Hex)
9.0x6ef61 -> eors r1, r0(r1则是so中固定hex,r0则是StringToHex内容)
这里描述的xid是指在请求fingerprint/v1/info/report获取真正的xid之前使用的a7
构造main(1)和main(2)的时候,都会生成a7,如果指定了.mtg_dfpid_com.sankuai.meituan文件,可以发现生成的a7并非此文件的xid(文件中的xid是请求返回的,抓包时的a7就是该值)
猜测我构造的unidbg可能并不完善,并没有读取到已经返回的a7,那么此时的a7有可能是自己加密生成的,分析代码,看a7如何构造,然后抓包分析获取真正xid之前的mtgsig参数中的a7,对比加密是否一致
【以下分析是在分析a9参数时,发现的一个aes算法中打印发现,具体如何寻找aes算法后续a9参数分析】
xid算法步骤
1.AES_data = '0'+dfp+'1'+时间戳(10进制hex)
2.AES_KEY='meituan1sankuai0'
3.AES_IV='0102030405060708'
4.AES_CBC(AES_data) -> base64
1.unidbg对标准AES算法0x9dfc5下断点调试
2.通过入参很容易分析出'0'+dfp+'1'+时间戳(10进制hex),至于后面的1+6551f39f,根据经验分析8位6xxxxx这样的hex,可能就是时间戳10位的hex
还有时间戳13位的hex,就是11位的18cxxxx这样的开头(后续也会用到)
3.通过unidbg的blr指令查看调用AES算法0x9dfc5的位置,并分析so层,找到key初始化的地方和iv的地方
4.0x2ABF6 -> bl sub_9D32C 就是key初始化的地方,可以获取到key,至于iv,则mt大部分iv都是'0102030405060708'
1.设备信息进行zlib压缩
2.压缩内容进行魔改RC4算法
3.最后结果进行base64
4.魔改RC4的key:固定hex xor (a1+a3+a4)
1.a5='EGQJ3E...VR6X=',明显的base64编码,在so文件中定位base64编码进行分析
2.搜索'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
3.交叉引用定位引用位置
4.unidbg对0xfe6c下断点进行调试,并且blr找到调用base64的位置
5.定位base64的入参哪里来,如上图发现是0xbdc2调用一个方法来的(分析后是魔改RC4),如果不严谨还可以结合trace日志向上分析
6.分析0xbdc2调用方法内部逻辑,结合RC4源码,发现类似:v9 = *(result + v7); *(result + v8) = v9这样的代码,猜测就是RC4算法,而RC4算法在加密前会进行密钥初始化,上面的图片中可以知道在调用RC4算法前还有一个0xbdb8调用了0x2af9c方法,明显这个就是rc4_init方法,而参数2就是key,参数3就是key_len
7.unidbg验证猜想
8.使用RC4算法工具去计算,发现结果还是不对,这是因为魔改了RC4,在RC4方法代码对比没有问题,那么可能问题出现在rc4_init上
9.下面分析RC4的KEY怎么来的,对key的地址0x402ed090进行tracewrite,搜索哪里对这个地址进行了写入
10.分析0x2b8a8地址前后的代码,看该值如何获得
11.Key是xor而来,分析xor的数据内容,很容易分析出是a1+a3+a4的值xor固定值,至于rc4的入参,直接unidbg 下断点看内容就知道是0x78、0x9c开头的zlib压缩数据,解压缩得设备信息
1.设备信息zlib压缩
2.crc32获取校验值
3.AES_KEY=crc32+'MXMYBS@H'
4.AES_CBC(zlib压缩信息,iv='0102030405060708')
5.a9=crc32+aes加密结果
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2024-3-10 20:10
被我是小趴菜编辑
,原因: 修改错误