最近分析某个 app时,发现注册口的风控特别严格。
严格到什么程度?
1)国内 IP不让使用
2) 设备没有sim卡不让注册
3) 发现设备环境不干净直接封号
4) 注册不允许使用 vpn
5) google注册必须是 @gmail.com后缀
注册时,携带了一个后台下发的设备 id,这个设备 id必须带上。也就是这个下发设备 id的协议必须请求成功,才能进行后续的注册。
①确定device_id来源
直接搜索相关字符串,最后定位在了这个 sdk的代码中:

没错,就是 libdu.so. 至于这是哪个 sdk,懂的都懂。
现在 AI 这么先进了,我就直接让 AI 告诉我,最终加密前的函数是哪个:

接下来就用一段 frida脚本输出验证下:
Interceptor.attach(module.base.add(0xc5f28), {
onEnter(args) {
console.log("call 0xC5F28");
console.log(
Memory.readByteArray(args[2], args[3].readPointer().toInt32()),
);
console.log(args[2].readUtf8String());
},
onLeave(retval) {
//console.log(retval.readUtf8String());
},
});
很明显这是一个 json字符串,也就是加密前请求的关键参数,字符串形式如下:
{
"nAt": "2",
"ubF": "这里是设备 id",
"AYk": "CA305B:D678CB:120F1C",
"P1J": "CA305B:D678CB:120F1C",
"R37": "Xiaomi",
"R3d": "XXXX",
"DUv": "xxxx.xxxx.xxx",
"SAN": 30,
"Zrs": 341,
"EV2": "app版本字符串",
"AAA": "v1.0",
"BBB": "v1.0",
"3mS": "v8.8.0",
"2cO": "时间戳",
"GVp": "Organic",
"mIS": "<n?1>B9pm==8nn?CD;>oaAp;?k8o?m<8<?#!",
"sfOo": "ED71279",
"foO": ";O@Ao?m;Bq=l;m>",
"4VP": 5,
"bf7": "41007",
"JPd": "41007",
"J7w": 0,
"NoH": 1,
"wSK": "IP",
"DVp": "?=B<A0B@9>8<=>",
"9N2": ";;7",
"Bn2": "BD!=ABB@=<?7=@<",
"IPz": "agMgzXYY5A==",
"sj5K": "61EF187",
"jK5": ";Q!!;E;=;;AA;;Q;",
"JYD": 4,
"02P": "86,-1",
"7S2": {
"0": {
"txo": ".k#yy",
"Zne": "h!A9>9<=<7ABOE=qqCEOoECq?:?A<D!B+?:lo@pEBBp;E<pf",
"MCN": "i889<fBBC;:"
}
},
"iYB": {
"txo": ".k#yy",
"Zne": "h!A9>9<=<7ABOE=qqCEOoECq?:?A<D!B+?:lo@pEBBp;E<pf",
"MCN": "i889<fBBC;:",
"mch": "TTQb",
"AWo": ";;;;;<;;;;",
"8tS": 63959,
"Hsz": 63959
},
"z4e": 3,
"zpA": "WIFI",
"QQW": 1,
"2Lp": 0,
"B7G": {
},
"vuS": "A@n@o?8nm>m8n;mB!o?=AQ<?pp8@?>@8Bm@n",
"9be": 14,
"6yY": "1c0c42eda039a179b3b619b671b0c0c83a43b6d44d26a8951c167aa76e6fe7af",
"vG9": 0,
"gaR": ";",
"Nue": "=9DC=CBD9?9@",
"T5u": {
"_adb._tcp.": {
"0": "adb-ba20125,f:3",
"1": "adb-ba20125,IP:PORT"
},
"wrs": "-2",
"i": "0,58.248.99.72;"
},
"Kvk": "73D2D0E56AC213AC2731AF49C328769C",
"NAB": 1,
"UOv": ">B@A0D@;A<?<!=A=<@B",
"sCc": 1,
"uCM": {
"pnb": 2,
"I2Y": 1,
"LzC": 54,
"nF5": 100,
"fgm": 4003,
"YXM": 330
},
"Db2": -1,
"box": {
},
"h6Z": "APP名",
"cxX": 1
}
这个协议的返回内容包含设备 id,同样问了大模型后,我知道了解密后的数据:
{
"err": "0",
"n_a": "设备 id",
"nctl": "2",
"ocdd": "",
"cdd": "设备 id",
"o_a": "",
"dlab": "7bAXRd3ep5GgYO0hC4K12A==",
"denv": "0",
"isem": "1",
"itime": "504700"
}
这个协议的 url是 70cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4L8r3!0T1j5h3I4Q4x3X3c8S2N6h3&6A6i4K6u0W2j5$3S2W2j5$3E0@1M7Y4g2K6N6s2N6G2M7Y4c8Z5K9h3&6W2M7%4y4Q4x3X3g2U0L8$3#2Q4x3V1k6S2i4K6u0r3L8h3c8F1j5g2)9J5c8Y4u0W2M7r3!0J5N6l9`.`.
看起来json字符串中的 value是有加密的,key应该是固定的,只是用了一个没有任何含义的字符串。
接着我又问了 AI, 它告诉了我字符串解密的函数:
Interceptor.attach(module.base.add(0xefdc0), {
onEnter(args) {},
onLeave(retval) {
var str = Memory.readUtf8String(retval);
console.log("dec str: " + str);
if (str === "AYk") {
console.log(module.base);
console.log(
"called from:\n" +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress)
.join("\n") +
"\n",
);
}
},
});sdk中用到的字符串,最终都会通过这个函数解密,那么现在想分析哪个字段,可以随时打印出调用栈。
例如很快就看到了检测 root 相关:

很快,大部分字段都被还原了:

篡改了该协议中所有与设备 id有关的字段内容,下发了新的设备 id。
抓包发现 sdk还有很多别的协议:

这个协议 3c8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4L8r3!0T1j5h3I4Q4x3X3c8S2N6h3&6A6i4K6u0W2j5$3S2W2j5$3E0@1M7Y4g2K6N6s2N6G2M7Y4c8Z5K9h3&6W2M7%4y4Q4x3X3g2U0L8$3#2Q4x3V1k6S2i4K6u0r3k6o6u0S2M7r3W2Q4x3V1k6J5k6i4m8G2M7Y4c8Q4x3@1j5`. 上报的数据最全面
协议的内容就不贴了,value 都是加密后的奇怪字符串。
完结!
最后于 1小时前
被CCTV果冻爽编辑
,原因: