1. 看一个手机号加密的例子
这个例子来自某视频App,可以看到mobile字段是被加密的。
一、尝试字符串匹配
也许是手机号都是1xx开头,也许是这个加密字符串有个特征头。反正经过我们观察,发现它大概率是 3sCt 开头。
而这种加密算法大概率是在Native层去做的。所以我们首选是去 hook_libart 里面的 GetStringUTFChars
和 NewStringUTF
。
结果木有结果。
二、尝试Base64
这个3sCt开头的字符串,很像Base64的结果。我们尝试用Base64去解一下,发现能解开。
那就毫不犹豫地尝试 Hook android.util.Base64
。
依然木有结果,这就比较神奇了,唯一的解释是 App木有用标准的Base64库函数,而是自己写了一个Base64算法。毕竟Base64的算法满天飞,有手就行。
三、搜索关键字mobile
现在死马当活马医吧。只能尝试去搜搜字符串了
结果并不多,比较有重大嫌疑的就是这两处了。
我们点进去分析 m434739f
函数。
这个App已经混淆到令人发指了,居然还能出现 atlasEncrypt
这么明显的函数,一定得好好Hook它。m60341e
也值得我们注意,这个类很像是Base64算法,这也解释了为啥Hook android.util.Base64 木有结果。
四、写个demo验证
var IKSecurityExCls = Java.use("com.xxxixxxu.android.security.KSecurity");
IKSecurityExCls.atlasEncrypt.implementation = function(a){
var StrCls = Java.use('java.lang.String');
var inStr = StrCls.$new(a);
var result = this.atlasEncrypt(a);
console.log(inStr + " >>> atlasEncrypt(Hex) " + bytesToHex(result));
console.log(inStr + " >>> atlasEncrypt(Base64) " + bytesToBase64(result));
return result;
}
最后发现可以得到预期的结果~
2. Frida开发Sekiro客户端
Sekiro是个相当牛X的库,基本上就是开箱即用了。
// 在普通Android应用中使用sekiro
new SekiroClient("test-android", UUID.randomUUID().toString())
.setupSekiroRequestInitializer(new SekiroRequestInitializer(){
@Overridepublic void onSekiroRequest(SekiroRequest sekiroRequest, HandlerRegistry handlerRegistry) {
handlerRegistry.registerSekiroHandler(new ClientTimeHandler());
}
}).start();
在Android代码里面这样一条api就可以了,然后在ClientTimeHandler
类里面写逻辑。
Frida使用就稍稍有点复杂,复杂的点就在于要创建一个java类ClientTimeHandler
来处理调用逻辑。
function initSekiro() {
const SekiroClient = Java.use('com.virjar.sekiro.business.api.SekiroClient');
const ActionHandler = Java.use('com.virjar.sekiro.business.api.interfaze.ActionHandler');
const SekiroRequestInitializer = Java.use('com.virjar.sekiro.business.api.interfaze.SekiroRequestInitializer');
//注册一个ClientTimeHandler类,继承 ActionHandlerconst
ClientTimeHandler = Java.registerClass({
name: 'ClientTimeHandler',
implements: [ActionHandler],
methods: {
action: function () {return 'mobile';},
handleRequest: function (sekiroRequest, sekiroResponse) {
const requestJsonData = sekiroRequest.getJsonModel();
const requestData = JSON.parse(requestJsonData)['requestData'];
if(!requestData){
sekiroResponse.failed(JavaString.$new('requestData 不能为空'));
}else{
try{
sekiroResponse.success(callMobile(requestData));
}catch(error){
sekiroResponse.failed(JavaString.$new(error.stack));
throw error;
}
}
}
}
})
// 注册一个 SekiroRequestDefault类, 继承SekiroRequestInitializerconst
SekiroRequestDefault = Java.registerClass({
name: "SekiroRequestDefault",
implements: [SekiroRequestInitializer],
methods: {
nSekiroRequest: function (sekiroRequest, handlerRegistry) {
handlerRegistry.registerSekiroHandler(ClientTimeHandler.$new());
}
}
});
const clientID = guid();
const group = 'fridaHook_atlasEncrypt';
const ip = '110.42.246.110';
// 服务端端口号 默认是 conf/config.properties 里面配置5620, 这里改成了 8989
const sekiro = SekiroClient.$new(group, clientID, ip, 8989);
sekiro.setupSekiroRequestInitializer(SekiroRequestDefault.$new());
sekiro.start();
}
三、验证
http://110.42.246.110:8989/business-demo/groupList 展示当前系统中注册过的所有 group
{"data":["fridaHook_atlasEncrypt"],"ok":true,"status":0}
http://110.42.246.110:8989/business-demo/clientQueue?group=fridaHook_atlasEncrypt 展示特定 group 下,注册过哪些客户端/手机。
{"data":["65c8e8b5-1a67-2036-5b38-769cb670aeb3"],"ok":true,"status":0}
执行一下看看结果
import requests
url = 'http://110.42.246.110:8989/business-demo/invoke'
mobileid = '18913872618'
data = {
'group': 'fridaHook_atlasEncrypt',
'action': 'mobile',
'requestData': mobileid
}
res = requests.post(url,json=data).json()
print(res['data'])
结果很完美3sCt3iAAMzIwOTAxMjA4AM8HAO7Jtk8ia8xTExAAAACFS7z70nRA3Ppgtdz9Kefb
收工~
> 本文出处 > http://91fans.com.cn/post/fridasekirorpc/#gsc.tab=0
> http://91fans.com.cn/post/smallvideosignthr/#gsc.tab=0