分析样例下载:链接: https://pan.baidu.com/s/1TErQmcjNbLG54yJbD31mLg 密码: j455

练习1、algorithmbase_50.apk

老样子直接ida分析libnative-lib.so。根据返回值处理找到关键函数sub_B9F4

image-20210114220409205

写个frida来查一下看看参数都是些什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function hook_native(){
var base_addr=Module.getBaseAddress("libnative-lib.so");
var sub_B9F4=base_addr.add(0xB9F4+1);
Interceptor.attach(sub_B9F4,{
onEnter:function(args){
console.log("onEnter sub_B9F4");
this.arg4=args[4];
console.log(hexdump(args[0],{length:args[1].toInt32()}));
console.log(hexdump(args[2],{length:args[3].toInt32()}));

},onLeave:function(retval){
console.log("onLeave sub_B9F4");
console.log(hexdump(this.arg4,{length:0x10}));
}
})
}
function hook_java(){
Java.perform(function(){
var native_lib=Java.use("com.kanxue.algorithmbase.MainActivity");
native_lib.encodeFromJni_50.implementation=function(input){
var res=this.encodeFromJni_50(input);
console.log("input:",input,"output:",res);
return res;
}
});
}
function main(){
hook_java();
hook_native();
}
setImmediate(main)

然后根据输出结果把字段的意义标注好。分别是input,input_size,kanxue_imyang,13,output

1
2
3
4
5
6
7
8
9
10
onEnter sub_B9F4
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
d6bcde40 4d 44 45 77 71 70 57 42 71 43 45 57 49 6d 58 4a MDEwqpWBqCEWImXJ
d6bcde50 4d 7a 6a 56 63 76 6f 6f 72 78 63 77 47 MzjVcvoorxcwG
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
d6c66b01 6b 61 6e 78 75 65 5f 69 6d 79 61 6e 67 kanxue_imyang
onLeave sub_B9F4
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d308 2f 49 e7 d6 89 c2 41 77 87 25 5d 18 6d 60 21 47 /I....Aw.%].m`!G
input: MDEwqpWBqCEWImXJMzjVcvoorxcwG output: 2f49e7d689c2417787255d186d602147

然后继续进去看函数。

image-20210114222053217

这里看到了几个熟悉的常量。看起来是和MD5相关的函数。但是又不完全是md5的算法。然后hoo一下sub_AF84

1
2
3
4
5
6
7
8
9
10
11
12
var sub_AF84=base_addr.add(0xAF84+1);
Interceptor.attach(sub_AF84,{
onEnter:function(args){
console.log("onEnter sub_AF84");
console.log(hexdump(args[0],{length:0x30}));
console.log(hexdump(args[1],{length:0x30}));
},onLeave:function(retval){
console.log("onLeave sub_AF84");
console.log(retval);
console.log(hexdump(retval,{length:0x30}));
}
})

输出结果是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
onEnter sub_AF84
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d258 85 b8 ae dd 3b 59 c5 59 4e 35 62 17 9c 92 d8 d7 ....;Y.YN5b.....
ff87d268 00 02 00 00 00 00 00 00 5d 57 58 4e 43 53 69 5f ........]WXNCSi_
ff87d278 5b 4f 57 58 51 36 36 36 36 36 36 36 36 36 36 36 [OWXQ66666666666
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
e3ad3280 6c 4b 58 42 71 77 6b 41 67 79 75 50 6c 61 72 6f lKXBqwkAgyuPlaro
e3ad3290 6a 58 76 4a 63 00 65 72 4e 61 74 69 76 65 3a 00 jXvJc.erNative:.
e3ad32a0 00 82 2b d7 00 82 2b d7 00 82 2b d7 00 82 2b d7 ..+...+...+...+.
onLeave sub_AF84
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d285 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 6666666666666666
ff87d295 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 6666666666666666
ff87d2a5 36 36 36 36 36 36 36 36 36 36 36 cb 8f 68 7c dc 66666666666..h|.
onEnter sub_AF84
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d258 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 .#Eg........vT2.
ff87d268 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
ff87d278 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d1d6 37 3d 32 24 29 39 03 35 31 25 3d 32 3b 5c 5c 5c 7=2$)9.51%=2;\\\
ff87d1e6 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c \\\\\\\\\\\\\\\\
ff87d1f6 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c \\\\\\\\\\\\\\\\

这种将后面空白部分填充为0x5c的特征是hmac的。我们翻一翻网上的hmac的源码看看函数定义

1
void hmac_sha256(const unsigned char *data, size_t len, const unsigned char *key, int len_key, unsigned char *out)

上面这个例子虽然是hmac+sha256的。但是定义都是差不多。然后发现我们之前hook看到的函数定义和这个基本一样的。那么kanxue_imyang多半就是key了。

这个很可能是hmac+MD5的组合。接下来可以验证一下结果。是正确的。第一题搞定

image-20210114225845426

========================================================================================

练习2、algorithmbase_51.apk

老样子。直接看ida的加密函数encodeFromJni_151。然后发现和上面的例子差不多。

image-20210114230109335

发现那个key被字符串加密了。用unidbg来跑下解密字符串

image-20210114230210551

然后看到这个key依然没有变。还是kanxue_imyang

image-20210114230240424

然后打印一下结果输出

1
input: iUmDZItFtGUbYQNFHYyRIIBAuvfBx output: 518688644d0e0551da5d4c9883cdcb4e

我们确定出了key。但是还得确定组合算法是不是MD5。先拿MD5的几个常量搜索一下0x28955B88、0x242070DB、0x173848AA

随便搜索几个之后。就发现有些能搜索到。有些搜索不到。那么这个可能是一个改了table的MD5。那么先跑一下trace。然后查一下看看有多少个常量被修改了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

public class lianxi51 {
public static void main(String[] args) {
lianxi51 lianxi = new lianxi51();
lianxi.Call_EncodeFromJni_32();
}
private final AndroidEmulator emulator;
private final VM vm;
private DvmClass Clazz;
private lianxi51() {
emulator = new AndroidARMEmulator();
Memory memory = emulator.getMemory();
LibraryResolver resolver = new AndroidResolver(23);
memory.setLibraryResolver(resolver);
vm = emulator.createDalvikVM(null);
vm.setVerbose(false);
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/lianxi51/libnative-lib.so"), false);
dm.callJNI_OnLoad(emulator);
Clazz = vm.resolveClass("com/kanxue/algorithmbase/MainActivity");
KingTrace trace=new KingTrace(emulator);
long start=0x400121B8; //0x196c8 0x3bb4
long end=0x400121B8+0x1c1e;
trace.initialize(start,end,null);
emulator.getBackend().hook_add_new(trace,start,end,emulator);
}
public void Call_EncodeFromJni_32(){
String res=Clazz.callStaticJniMethodObject(emulator,"encodeFromJni_151(Ljava/lang/String;)Ljava/lang/String;","iUmDZItFtGUbYQNFHYyRIIBAuvfBx").toString();
System.out.print(res);
}
}

最后拿跑出来的日志筛了一下MD5的常量列表。结果都在里面。然后搜索MD5的常量找到关键函数sub_121b8。hook一下看看init的key是不是有修改

1
2
3
4
5
6
7
8
9
10
11
12
var base_addr=Module.getBaseAddress("libnative-lib.so");
var sub_121b8=base_addr.add(0x121b8+1);
Interceptor.attach(sub_121b8,{
onEnter:function(args){
console.log("onEnter sub_121b8");
console.log(hexdump(args[0],{length:0x30}));
console.log(hexdump(args[1],{length:0x30}));

},onLeave:function(retval){
console.log("onLeave sub_121b8");
}
})

输出结果可以看到是MD5的init没有修改的。

1
2
3
4
5
6
7
8
9
onEnter sub_121b8
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d258 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 .#Eg........vT2.
ff87d268 00 02 00 00 00 00 00 00 e3 e9 e6 f0 fd ed d7 e1 ................
ff87d278 e5 f1 e9 e6 ef 88 88 88 88 88 88 88 88 88 88 88 ................
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d270 e3 e9 e6 f0 fd ed d7 e1 e5 f1 e9 e6 ef 88 88 88 ................
ff87d280 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
ff87d290 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................

既然MD5没有修改。那就只能是hmac发生了变化。找一下hmac中的计算关键处。发现很有可能就是hmac发生了修改

image-20210114232846271

虽然这里看着好像是要修改0x36和0x5c为0x25和0xc。但是上面看着好像经过了复杂的运算。最终结果不一定。这里我们可以留意到。之前第一题的时候。我们hook了sub_AF84函数。后面会补充36和5c。正好就是这里异或的。所以这个例子我们只要找到和之前sub_AF84相同的函数。然后hook一下。看看后面补充的是什么。就直接修改即可。根据最后一个参数为0x40。可以很快找到对应的函数sub_11DF0。下面贴上hook代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
onEnter sub_11DF0
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d258 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 .#Eg........vT2.
ff87d268 00 00 00 00 00 00 00 00 98 d2 87 ff 9d 12 0d d7 ................
ff87d278 a1 43 27 ec dc d2 87 ff dc d2 87 ff dc d2 87 ff .C'.............
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d217 e3 e9 e6 f0 fd ed d7 e1 e5 f1 e9 e6 ef 88 88 88 ................
ff87d227 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
ff87d237 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
onEnter sub_11DF0
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d258 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 .#Eg........vT2.
ff87d268 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
ff87d278 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
ff87d1d6 0d 07 08 1e 13 03 39 0f 0b 1f 07 08 01 66 66 66 ......9......fff
ff87d1e6 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
ff87d1f6 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff

那么就可以验证试一下了。首先放上我整理好的连接https://github.com/dqzg12300/hmac_md5

然后简单贴一部分相关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string.h>
#include "hmac-md5.h"
int main() {
char* input="iUmDZItFtGUbYQNFHYyRIIBAuvfBx";
char* key="kanxue_imyang";
md5_digest_t out={0};
hmac_md5(input,strlen(input),key,strlen(key),out);
for(int i=0;i<sizeof(out);i++){
printf("%x ",out[i]);
}
return 0;
}

还有修改了hmac部分的

1
2
3
4
for (i=0; i<64; i++) {
k_ipad[i] ^= 0x88; //36
k_opad[i] ^= 0x66; //5c
}

最后贴上成功的测试结果。和抓到的结果一致。第二题搞定

1
51 86 88 64 4d e 5 51 da 5d 4c 98 83 cd cb 4e 

========================================================================================

练习三algorithmbase_52.apk

ida打开encodeFromJni_152函数就看到了字符串加密

image-20210115000818798

然后用unidbg解密后得到key

image-20210115000841545

然后我们先输出一下看看结果

1
input: TlmFvaUqfZaBROIZwzMTCa output: 1a03845278e8f101ec41e041e7cb6896b2d58268805045322488cb1685380083

发现这个输出比较长了。估计不是MD5算法了。但是从前面的代码来看。依然还是hmac的。根据输出结果判断。这个有可能是hmac+sha256。我们在网上随便再找找sha256的常量

1
2
3
4
5
6
7
8
9
10
11
12
var K = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ];
// initial hash value [§5.3.1]
var H = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];

然后用ida搜索一下。搜了好几个结果都是有找到的。我就只贴一个示意图了

image-20210115002128274

那么验证一下结果看看。结果和上面对的上了。第三题搞定

image-20210115002254506