包:5ZOU5ZOp5ZOU5ZOpXzYuMTguYXBrCnR2LmRhbm1ha3UuYmlsaQ==
该软件涉及hook检测和抓包检测:
hook检测参考:https://bbs.kanxue.com/thread-277034.htm
抓包:用lsp的JustTrustMe
frida:16.1.3
frida-tools :12.2.1
安卓10
python 3.11.4
好了下面就可以开心的使用使用frida进行hook抓包了
先抓一个登录包
登录包是这样的,有四个参数需要处理的
hook newStringUtf 可以找到sign的值
打印调用堆栈可以定位到这个so
定位到了这个地方
分析一下函数的来源,上面几个函数很关键的
下面是挨个进去看一下,这里面都做了啥
很幸运是的第一个函数里面,对MD5的模数进行初始化了
拿下面就是MD5相关的函数了
下面找一个MD5的源码对着函数进行重名了和类型的修改
修改好了就是这样的,代码简洁明了,就是加盐的MD5
下面对MD5的MD5Update和 MD5Final进行hook
打印参数的时候这里调用两个,第一个包后面分析,我们先看这个sign的加密
ok成功抓到sign,看一下是怎么来的
这里第一个MD5Update里面是明文数据
后面三个加盐的数据
最后两个是MD5Final里面调用的可以忽略了
明文就是前面所有参数的总和:太长了就不贴了,后面会分析都是啥
后面加盐的4个参数是这样的:
60698ba2
f68e01ce
44738920
a0ffe768
拼接在后面,使用MD5加密后,和我们上面抓到的数据一模一样的
这四个参数在我的手机上面是固定的,如果对于怎么来的比较感兴趣在分析一下
看一下java层哪里调用了一个函数,使用这个脚本
定位到了这个函数,通过hook发现i2是1,i3是0
在so层会对这个值进行判断,根据值不用取不同的数据
因为i1==1,所有这里对应的表格是dword_971C
v19经过分析是0,对比appkey=bca7e84c2d947ac6得来得,这里不在赘述了
剩下三个参数来自于,数组得下标是7,14,28得数据
欧克到这里sign基本上已经分析完毕了,知道明文书加盐得参数都是怎么来得
搜索字符串,找到了login,我们需要分析都在这个里面,看一下哪里调用得
找到引用得地方,可以看到密码得加密方式,跟过去看一下
很清楚,进行更一下
RSA非对称加密
hook一下,获取明文和公钥
明文是密码拼接一个数据,那个拼接得是什么呢?
还记得之前说过登录发送两个包吗?
看返回啥得,我们得hash和公钥
哈哈哈,到此密码也搞定了
device_meta 是login得第三个参数,dt 是login得第四个参数
就是这两个参数,java层可以直接往上跟,
ok可以看到一个字符串书随机生成得
随机生成得16位字符串,对device_meta进行AES加密
这里hook一下,看一下device_meta得明文是啥
霍,好家伙,把手机上面得设备信息上传了,我说数据怎么这么大呢
这信息量真得大呀卧槽、卧槽、卧槽
到这里
device_meta分析完了
下面看一下dt,这里就很熟悉
将上面生成得key用公钥加密,然后上传上去,到此这个登录包得,四个参数都已经分析完了
后面有个滑块,因为初学不会滑块,就先到这里了
function hook_netString(){
var symbols
=
Process.getModuleByName(
"libart.so"
).enumerateSymbols();
var newStringUtf
=
null;
for
(let i
=
0
; i < symbols.length; i
+
+
) {
var symbol
=
symbols[i];
if
(symbol.name.indexOf(
"CheckJNI"
)
=
=
-
1
&&
symbol.name.indexOf(
"NewStringUTF"
) !
=
-
1
){
console.log(symbol.name, symbol.address);
newStringUtf
=
symbol.address;
}
}
if
(newStringUtf){
Interceptor.attach(newStringUtf, {
onEnter: function (args) {
console.log(
"newStringUtf args: "
, args[
1
].readCString());
console.log(Thread.backtrace(this.context, Backtracer.FUZZY).
map
(DebugSymbol.fromAddress).join(
'\n'
)
+
'\n'
);
}, onLeave: function (retval) {
console.log(
"newStringUtf retval: "
, retval);
}
});
}
function hook_netString(){
var symbols
=
Process.getModuleByName(
"libart.so"
).enumerateSymbols();
var newStringUtf
=
null;
for
(let i
=
0
; i < symbols.length; i
+
+
) {
var symbol
=
symbols[i];
if
(symbol.name.indexOf(
"CheckJNI"
)
=
=
-
1
&&
symbol.name.indexOf(
"NewStringUTF"
) !
=
-
1
){
console.log(symbol.name, symbol.address);
newStringUtf
=
symbol.address;
}
}
if
(newStringUtf){
Interceptor.attach(newStringUtf, {
onEnter: function (args) {
console.log(
"newStringUtf args: "
, args[
1
].readCString());
console.log(Thread.backtrace(this.context, Backtracer.FUZZY).
map
(DebugSymbol.fromAddress).join(
'\n'
)
+
'\n'
);
}, onLeave: function (retval) {
console.log(
"newStringUtf retval: "
, retval);
}
});
}
args:
2d0fd1f3b61fd50921c0f71a3ee2cf0b
0xb2b611a5
libbili.so!
0x31a5
args:
2d0fd1f3b61fd50921c0f71a3ee2cf0b
0xb2b611a5
libbili.so!
0x31a5
let libbili
=
Module.findBaseAddress(
"libbili.so"
);
if
(libbili !
=
null){
console.log(
"so addr:"
,libbili);
Interceptor.attach(libbili.add(
0x2F88
+
1
),{
onEnter:function(args){
console.log(
"明文1:"
,JSON.stringify((args[
1
])),args[
2
],args[
3
]);
}
})
Interceptor.attach(libbili.add(
0x22B0
+
1
),{
onEnter:function(args){
console.log(
"明文1:"
,ptr(args[
1
]).readCString(),hexdump(args[
1
]))
}
})
Interceptor.attach(libbili.add(
0x2AE0
+
1
),{
onEnter:function(args){
this.args1
=
args[
0
];
},
onLeave:function(args){
console.log(
"返回:"
,ptr(this.args1).readCString(),hexdump(this.args1))
}
})
}
let libbili
=
Module.findBaseAddress(
"libbili.so"
);
if
(libbili !
=
null){
console.log(
"so addr:"
,libbili);
Interceptor.attach(libbili.add(
0x2F88
+
1
),{
onEnter:function(args){
console.log(
"明文1:"
,JSON.stringify((args[
1
])),args[
2
],args[
3
]);
}
})
Interceptor.attach(libbili.add(
0x22B0
+
1
),{
onEnter:function(args){
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2023-12-12 14:17
被mb_kbkqyusp编辑
,原因: 代码格式优化