0x2 抓包分析
现在APP不知道为什么进不去了,用的之前的图片凑合一下
通过截图看得出来,有signaturenonce和signature很像加密。多次抓包比对,同样的参数提交signature都不一样,那么这个signature就是我们要处理的参数了。同时返回值也进行了加密。
0x3 脱壳&&反编译
先查一下壳,360免费版的。免费的360还是随便脱的。脱好了之后直接拖入jadx来看一下。
就一处,不会这么简单就完结了吧。
timestampkeep没见过,frida hook一下
let SecurityUtil = Java.use("net.security.device.api.SecurityUtil");
SecurityUtil["sendPopRequest"].implementation = function (str, map, map2) {
console.log('sendPopRequest is called' + ', ' + 'str: ' + str + ', ' + 'map: ' + map + ', ' + 'map2: ' + map2);
let ret = this.sendPopRequest(str, map, map2);
console.log('sendPopRequest ret value is ' + ret);
return ret;
};
发现不走这里。
换下思路,signature 是40位的,首先想到的就是sha1。那就HOOK一下哈希算法试下。
}
也不走这里。
0X4 初识unity
注意到app页面在第一次加载的时候有明显的卡顿,怀疑不是纯java开发。解压查看一下lib库都有哪些。注意到这里有个unity的so,大概率是unity开发的APP了。unity主要可以看成两类,dll游戏和libil2cpp游戏。这里没有看到libil2cpp,那么大概率就是dll游戏了。解压APK资源assets\bin\Data\Managed这个路径下找到Assembly-CSharp.dll就是主要逻辑所在的dll了反编译这个来进行逆向。
0X5 反编译Unity与还原算法
下载安装ILSpy,需要.net 的运行环境,如果没有的话第一次启动会跳转到.net的下载。将dll拖进去。
选择保存代码。Vscode打开文件夹,查看代码资源。搜索signaturenonce 可以看到很明了的代码。
那么signature就是 signaturenonce=×tamp=&body=按照ascii码升序排序,之后加一个盐值tGgFVEed0KSZ5So4VgcXAluyELikd1eF然后进行sha1计算。验证一下,解决。
另外就是返回值解密部分,
AES ECB模式。测试一下
搞定,完结
0X6 总结
unity主要可以看成两类,dll游戏和libil2cpp游戏。其中dll游戏可以通过反编译直接看到源码来进行逆向修改,属于比较简单的。本次样本360的免费加固+dll的unity属于入门级的,适合练手。并且没有对dll进行加密,也没有对算法进行魔改,基本上没有安全性。
0x1
样本分析
样本:Y2MuamNsZC50YW9qaW5jaGVuZ3poZW4
=
版本号:
1.2
.
0
加固:
360
0x1
样本分析
样本:Y2MuamNsZC50YW9qaW5jaGVuZ3poZW4
=
版本号:
1.2
.
0
加固:
360
var md
=
Java.use(
'java.security.MessageDigest'
);
md.getInstance.overload(
'java.lang.String'
,
'java.lang.String'
).implementation
=
function (a,b) {
send(
"======================================"
);
send(
"算法名:"
+
a);
return
this.getInstance(a, b);
}
md.getInstance.overload(
'java.lang.String'
).implementation
=
function (a) {
send(
"======================================"
);
send(
"算法名:"
+
a);
return
this.getInstance(a);
}
md.update.overload(
'[B'
).implementation
=
function (a) {
send(
"======================================"
);
send(
"update:"
+
ByteToString(a))
return
this.update(a);
}
md.update.overload(
'[B'
,
'int'
,
'int'
).implementation
=
function (a,b,c) {
send(
"======================================"
);
send(
"update:"
+
ByteToString(a)
+
"|"
+
b
+
"|"
+
c);
return
this.update(a,b,c);
}
md.digest.overload().implementation
=
function () {
send(
"======================================"
);
var result
=
this.digest();
send(
"digest结果:"
+
BytesToHex(result));
/
/
console.log(
"digest结果:"
+
ByteToString(result));
return
result;
}
md.digest.overload(
'[B'
).implementation
=
function (a) {
send(
"======================================"
);
send(
"digest参数:"
+
ByteToString(a));
var result
=
this.digest(a);
send(
"digest结果:"
+
BytesToHex(result));
/
/
send(
"digest结果:"
+
ByteToString(result));
return
result;
var md
=
Java.use(
'java.security.MessageDigest'
);
md.getInstance.overload(
'java.lang.String'
,
'java.lang.String'
).implementation
=
function (a,b) {
send(
"======================================"
);
send(
"算法名:"
+
a);
return
this.getInstance(a, b);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!