frida-ida hook操作

hook app 酷安app

fiddler抓取app时,发现有个参数 x-app-token一直在变化

于是我们用jadx打开

 我们使用jadx打开该app,搜索x-app-token

 我们打开as函数,找到该相关的函数

发现token是藏在一个叫做native-lib的so文件里里

我们用apktool编译此app

现在我们使用ida静态打开libnative-lib.so文件

在里面搜索getAS.发现没找到,此时我们正常情况下需要动态调试JNI_ONload函数里面RegisterNatives的信息,来发现该函数执行的实际名称

1 使用frida-hook技术去hook RegisterNatives函数,打印出和RegisterNatives相关的信息;操作方式https://www.cnblogs.com/wuxianyu/p/14518414.html

2 取巧的方式 静态打开JNI_ONLoad 找到RegisterNatives 一般里面的第三个参数是常量,我们点进去,找到里面有关于xxx+1的,这个大概率就是注册的函数

还有一种很多命名都是以规则是 sub_+内存地址的方式命名的

  

 

此时也可以用半猜测的方法,去猜测该函数的可能性。我们发现有个getAuthSRtring函数

仔细找找

 发现里面有个return。

再有个signature 我们判断v17可能是token

正常token的组成=时间戳+固定的字符串+device_id

现在我们通过token来反推

现在把v17重命名成token

在反推里的时候,你反推到哪一步,就双击该程序运行的函数,最好多双击双击里面的函数,比如md5加密啊,base64编码啊,这种的,ida会随着点击进行自动更改伪代码,多点点之后会发现函数的代码有所改变,变得更容易看懂

 

 从现在可推断出token是v55赋值的 

我们可以拿出个笔记本进行笔记

token=v55

v55=v81

v81=v61

v61=

v61有点麻烦 我们先看v43 

v43=v57

v57=a4

a4是最上方int a5传过来的 

由于jadx分析

getAs传递了两个参数,第一个是appcontent。第二个是device_id

而a4的类型又为int。判断a4为device_id我们将v43改为deviceid

我们再来看v85

v85是v40的十六进制输出 %x代表16进制

bin():十进制转二进制
oct():十进制转八进制
int():十进制转十进制
hex():十进制转十六进制

sprintf代表格式化输出字符串

而v40=又是个时间戳

我们现在吧v85改成timestamp

现在也就判断出

v81=v61+deviceid+'0x'+timestamp

现在我们在看这个md5加密 

意思是说把v58的值进行md5加密。v61就是实际v58加密后的16进制输出

我们现在在看v58

 v58的初始值为0,那中间肯定有赋值的操作

可以看到将v52赋值给v58.   v53是赋值的长度

v52又是v51赋值  

v51是一串base64加密

再往上上看分析就比较麻烦。我们现在对这串base54进行frida hook操作,来打印该加密字符串,先找到该base64的偏移量,双击此函数,点进去为0002E884

现在我们通过hook操作,我们知道 ,so文件的基地址+函数的偏移量=函数实际在内存中的地址

现在我们可以先获取getAuthstring的实际内存地址,再减去getAuthstring偏移量的。得到so文件的基地址

然后那so文件的基地址加上base64函数的偏移量,就得到来base64函数的实际内存地址

然后在对base64函数进行打印操作,就能打印出该函数运行的值

代码如下(注:frida最好安装12.10.8 的 frida-tools安装6.0.1。frida-server安装12.8.10)

import frida
import sys

def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)


hook_lib_native = """
//获得 getAuthstring的绝对地址
var getAuthString_absulate_add = Module.getExportByName('libnative-lib.so', 'getAuthString');

//获得 native so文件的 基础地址
var native_lib_base_add = parseInt(getAuthString_absulate_add) - parseInt('0x66500');

send('native_lib_base_addr:'+ptr(native_lib_base_add));

//b64_encode address
//base64的内存地址==so文件的基地址+base64的偏移量//0002E884
//
//注:如果hook过程中b64没输出。说明可能app运行没调用到该函数,建议更换其他b64的偏移量进行尝试
//像这下面的0x31DB8 正常情况下是0002E84但是输入0002E84并没有反应,猜测应该是没有调用到该函数,于是使用其他的b64encode偏移量进行尝试,
//你会发现ida里面 的都是000但是实际上写的话都是0x,正宗写法,我也不知道为啥,反正以后偏移量的是啥000开头的 一律写0x就完事了

var b64_encode_add = ptr(native_lib_base_add + parseInt('0x31DB8'));
send('b64_encode_addr:'+b64_encode_add);
//对b64_encode_add进行打印操作
Interceptor.attach(b64_encode_add,
{
onEnter: function(args) {
send("b64_encode ori:"+Memory.readCString(args[0]));
},
onLeave:function(retval){
//send("retval:"+retval);
}
}
);
"""

process = frida.get_usb_device().attach('com.coolapk.market')
script = process.create_script(hook_lib_native)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read()

 打印出来的base64加密如图所示

token://com.coolapk.market/c67ef5943784d09750dcfbb31020f0ab?1c12ffd15fb3467d73afe9d28c0712f3 $ 3b943bad-3b28-3e38-9f59-fec57db00094 &com.coolapk.market

现在我们来分析此段加密的字符串的组成

 看这段

v49=v62

v62=v65+v45+$+deviceid+&+v47

通过前面的我们知道 v49=token://com.coolapk.market/c67ef5943784d09750dcfbb31020f0ab?1c12ffd15fb3467d73afe9d28c0712f3 $ 3b943bad-3b28-3e38-9f59-fec57db00094 &com.coolapk.market

通过多次打印v49输出,发现前面的这段token://com.coolapk.market/c67ef5943784d09750dcfbb31020f0ab?是不变的。也就是v65是不变的

我们现在进行拆分 得出 v45=1c12ffd15fb3467d73afe9d28c0712f3

有可能是时间戳

deviceid=3b943bad-3b28-3e38-9f59-fec57db00094(每个人的设备不同,这里仅代表我的设备id)

v47=com.coolapk.market

现在我们在分析v45

v45=v68

v68=md5(v65)

v65=&s

&s=十进制输出的v40

v40=timestamp

现在退出了v45是个十进制输出后加密成md5的时间戳

现在我们理清了

v49=v65+v45+$+deviceid+&+v47=token://com.coolapk.market/c67ef5943784d09750dcfbb31020f0ab?+timestamp.int+$+ 3b943bad-3b28-3e38-9f59-fec57db00094+&+com.coolapk.market

v81=v61+deviceid+'0x'+timestamp.hex

也就是tooken=v61+deviceid+'0x'+timestamp.hex

我们再把之前的关系里一遍

v61=  md5(v58)

v58=v52

v52=v51

v51=base64(v49)

也就是说先对v49进行b64转码

转码后的v58进行md5加密就是61

tooken=md5(base64(token://com.coolapk.market/c67ef5943784d09750dcfbb31020f0ab?+timestamp.int+$+ 3b943bad-3b28-3e38-9f59-fec57db00094+&+com.coolapk.market))+token://com.coolapk.market/c67ef5943784d09750dcfbb31020f0ab?+timestamp.int+$+ 3b943bad-3b28-3e38-9f59-fec57db00094+&+com.coolapk.market+'0x'+timestamp.hex

检验正确

很绕,多实践

学习自猿人学

原文地址:https://www.cnblogs.com/wuxianyu/p/14332956.html