android-app-100-wp

0x00

​ 之前一直没做过真正的apk的题目,今天遇到了。首先有:

image-20221115200743862

​ 在网上搜了搜,直接用jadx反编译,得到:

image-20221115201530923

image-20221115205323773

​ 查了一下,Build.SERIAL这个方法被弃用了,使用手机试了一下,一直显示:

image-20221115210228077

​ 直接看wp,师傅们说发现有native方法之后,看到代码里有System.loadLibrary("adnjni");,可以猜测到IsCorrect函数定义在了这里面,用ida打开后的确有adnjni.so这样一个文件,发现IsCorrect函数:

image-20221115211236999

​ 猜测要与这个字符串比较,试一试,发现:

image-20221115211529057

​ 还是不行,猜测是那个弃用方法的问题,换个mumu模拟器,得到:

image-20221115225608286

0x01

​ 仔细分析函数流程:

image-20221115233817193

  1. 得到int processObjectArrayFromNativeint this.a.d,之后计算processObjectArrayFromNative+this.a.d+空格转字符串的md5值。
  2. 遍历对上述结果转化成stringBuffer然后输出。

​ 分析this.a.processObjectArrayFromNative函数,可以简化为:

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
v3 = -1661035768
v25 = 0
v22 = 0
while True:
while True:
while True:
while v3 <= -1303766071:
v3 = 2063008300
if v3 > 441419317:
break
v3 = 1800572839
if not v25:
v3 = 441419318

if v3 > 867851767:
break
v3 = 1405326207
if v3 <= 1405326206:
break
if v3 == 1405326207:
v26 = v22
v3 = 867851768
elif v3 == 1800572839:
v22 = 92060626
v3 = 441419318
else:
v22 = 0
v3 = -18897425
v25 = 1
print(v26)
# v26 = 92060626

​ 因此可以写脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Test {
public static void main(String []args) {
int v1 = 114366;
int v26 = 92060626;
String str = String.valueOf(v1 + v26) + " ";
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(str.getBytes());
byte[] digest = messageDigest.digest();
StringBuffer stringBuffer = new StringBuffer();
for (byte b : digest) {
stringBuffer.append(Integer.toString((b & 255) + 256, 16).substring(1));
}
System.out.println(stringBuffer.toString());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

}
}
// 833489ef285e6fa80690099efc5d9c9d

0x02

​ 看别的师傅的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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import frida, sys


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


jscode = """
setImmediate(function () {
Java.perform(function () {
console.log("start");
//so层hook
//导出函数
//var exports = Module.enumerateExportsSync("libadnjni.so");
//for(var i=0;i<exports.length;i++){
// send("name:"+exports[i].name+" address:"+exports[i].address);
// }
var str = Java.use("java.lang.String");
//遍历模块找基址
// Process.enumerateModules({
// onMatch: function (exp) {
// send(exp.name)
// if (exp.name == 'libadnjni.so') {
// send('enumerateModules find');
// send(exp.name + "|" + exp.base + "|" + exp.size + "|" + exp.path);
// send(exp);
// return 'stop';
// }
// },
// onComplete: function () {
// send('enumerateModules stop');
// }
// });

//通过模块名直接查找基址
//var soAddr = Module.findBaseAddress("libadnjni.so");
var soAddr = Module.findBaseAddress("libmedia_jni.so");
send("soAddr:" + soAddr);

var parray=0x48c+1;
var pcorrect=0x74c+1;
// hook导出函数 通过函数名

//Module.findExportByName 找到的函数地址无效
// var farray=Module.findExportByName("libadnjni.so", "Java_com_example_ctf2_MainActivity_processObjectArrayFromNative")
// send("findExportByName farray() by Module.findExportByName:" +farray);
var farray=new NativePointer(soAddr).add(parray);
//NativePointer 简写ptr
send("findExportByName farray() by ptr:" +farray );

Interceptor.attach(farray, {
onEnter: function (args) {
var s = Java.cast(args[2], str);
send("array() jstring:" + s );
},
onLeave: function (retval) {
send("array() return:" + retval);
}
});

// hook导出函数 通过函数名
// var fcorrect=Module.findExportByName("libadnjni.so", "Java_com_example_ctf2_MainActivity_IsCorrect");
// send("findExportByName correct() by Module.findExportByName:" +fcorrect );
var fcorrect=new NativePointer(soAddr).add(pcorrect);
send("findExportByName correct() by ptr:" +fcorrect );
Interceptor.attach(fcorrect, {
onEnter: function (args) {
var s = Java.cast(args[2], str);
send("fcorrect() jstring:" + s );
},
onLeave: function (retval) {
send("fcorrect() return:" + retval);
}
});

});
});
"""
# print(jscode)

# 启动时hook
# devices=frida.get_usb_device()
# pid=devices.spawn(['com.example.goal'])
# session=devices.attach(pid)
# devices.resume(pid) #创建完脚本, 恢复进程运行
# script=session.create_script(jscode)

# 命令行frida -U -f com.example.goal --no-pause -l <hook.js>

# 运行中hook
# process = frida.get_remote_device().attach('Sharif_CTF')

process = frida.get_usb_device().attach(2164)
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running test')
script.load()
sys.stdin.read()

# ef57f3fe3cf603c03890ee588878c0ec

'''
[*] Running test
start
[*] soAddr:0xcd562000
[*] findExportByName farray() by ptr:0xcd56248d
[*] findExportByName correct() by ptr:0xcd56274d
[*] array() jstring:Serial Number
[*] array() return:0x0
[*] fcorrect() jstring:Serial Number
[*] fcorrect() return:0x0


[*] array() jstring:ef57f3fe3cf603c03890ee588878c0ec
[*] array() return:0x57cbbd2
[*] fcorrect() jstring:ef57f3fe3cf603c03890ee588878c0ec
[*] fcorrect() return:0x1
'''

​ 没跑出来,主要是没找到libadnjni.so,很奇怪。

知识点1:

  1. 常见的安卓逆向工具

  2. jadx-gui。方便的jadx工具,可以直接反编译apk。

知识点2:

​ frida 是一款基于 python+javascript 的 hook 框架,可运行在 android、ios、linux、win等各个平台,主要使用的动态二进制插桩技术。

​ 插桩技术是指将额外的代码注入程序中以收集运行时的信息,可分为源代码插桩 SCI 和二进制插桩 BI。

  • 源代码插桩 SCI

    Source Code Instrumentation,额外代码注入到程序源代码中。

  • 二进制插桩 BI

    Binary Instrumentation,额外代码注入到二进制可执行文件中。

    1. 静态二进制插桩 SBI,Static Binary Instrumentation,在程序执行前插入额外的代码和数据,生成一个永久改变的可执行文件。
    2. 动态二进制插桩 DBI,Dynamic Binary Instrumentation,在程序运行时实时插入额外代码和数据,对可执行文件没有任何永久改变。

知识点3:adb(android debug)使用

​ 配置查看:https://blog.csdn.net/yi_rui_jie/article/details/115462824

​ 链接mumu模拟器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
adb connect 127.0.0.1:7555 # 7555为mumu模拟器端口号
adb disconnect 127.0.0.1:7555 # 断开连接
adb shell # 进入shell
cat /proc/cpuinfo # adb查看电脑cpu架构
getprop ro.product.cpu.abi # 查看模拟器cpu架构
adb push file /data/local/tmp/ # 将文件push 进手机的指定目录下
adb -s emulator-5554 shell # 多个设备进入某一指定设备
su # 切换获取手机的root权限
adb forward tcp:27042 tcp:27042 # 进行端口转发(新打开一个cmd)
adb forward tcp:27043 tcp:27043 # 进行端口转发(新打开一个cmd)
frida-ps -U # 查看手机启动的进程(查看到则运行成功,frida安装完毕!)
frida-ps -U -a # 不仅输出进程名称,还输出进程的Identifier
frida -U -f 进程的Identifier -l xx.js # 将xx.js注入到进程中
adb devices # 查看adb连接的设备
linux 在命令的后面加一个 & 的作用是在后台执行

留言

2022-11-15

© 2024 wd-z711

⬆︎TOP