app3
附件地址:https://adworld.xctf.org.cn/media/task/attachments/12c5199c0b674da4be05747258218bbe.ab
@windy_ll师傅对这道题的题解已经很棒了。在这里我就再次参考@windy_ll师傅的wp复现一下。
复现
首先通过android-backup-extractor解开ab文件。可以得到以下内容。
存在两个db文件,打开均需要密码。
此时开始对base.apk尝试逆向。
首先还是看MainActivity,我们可以看到onCreate后,调用了a函数。
此时可以发现a函数为获取秘钥,解密数据库的关键点。
其首先创建了用户名与密码。然后通过tencentwelcome.a.a这个类对其进行加密,最终得到密码,传入b,解密数据库。
故我们需要解密传入到getWritableDatabase中的密码。
分析后,发现未调用so。所以我们可以直接提出关键的java代码。直接执行,即可获取密码。
以下为我们提出的tencentwelcome.a.a,并将MainActivity中的核心逻辑放到了main函数中。
// Test.java
public class Test {
private String a;
public Test() {
super();
this.a = "yaphetshan";
}
public String a(String arg4, String arg5) {
return arg4.substring(0, 4) + arg5.substring(0, 4);
}
public String a(String arg3) {
new b();
return b.b(arg3 + this.a);
}
public String b(String arg2, String arg3) {
new b();
return b.a(arg2);
}
//
public static void main(String args[]) {
Test k = new Test();
String v2 = k.a("Stranger", "123456");
String ccc = k.a(v2 + k.b(v2, "123456")).substring(0, 7);
System.out.println(ccc);
}
}
此时分析我们发现还需要一个b的依赖,故也提出来。
// b.java
import java.security.MessageDigest;
public class b {
public b() {
super();
}
public static final String a(String arg9) {
String v0_2;
int v0 = 0;
char[] v2 = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try {
byte[] v1 = arg9.getBytes();
MessageDigest v3 = MessageDigest.getInstance("MD5");
v3.update(v1);
byte[] v3_1 = v3.digest();
int v4 = v3_1.length;
char[] v5 = new char[v4 * 2];
int v1_1 = 0;
while(v0 < v4) {
int v6 = v3_1[v0];
int v7 = v1_1 + 1;
v5[v1_1] = v2[v6 >>> 4 & 15];
v1_1 = v7 + 1;
v5[v7] = v2[v6 & 15];
++v0;
}
v0_2 = new String(v5);
}
catch(Exception v0_1) {
v0_2 = null;
}
return v0_2;
}
public static final String b(String arg9) {
String v0_2;
int v0 = 0;
char[] v2 = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try {
byte[] v1 = arg9.getBytes();
MessageDigest v3 = MessageDigest.getInstance("SHA-1");
v3.update(v1);
byte[] v3_1 = v3.digest();
int v4 = v3_1.length;
char[] v5 = new char[v4 * 2];
int v1_1 = 0;
while(v0 < v4) {
int v6 = v3_1[v0];
int v7 = v1_1 + 1;
v5[v1_1] = v2[v6 >>> 4 & 15];
v1_1 = v7 + 1;
v5[v7] = v2[v6 & 15];
++v0;
}
v0_2 = new String(v5);
}
catch(Exception v0_1) {
v0_2 = null;
}
return v0_2;
}
}
将上述两个文件保存,然后运行即可。
javac Test.java
java Test
然后解密我们的数据库即可。
最终得到flag