【攻防世界】Moblie系列之app3

【攻防世界】Mobile系列之app3

这里下载的文件为ab文件,是由亚行创建的Android备份文件,需要对其进行转换处理成tar文件,这里需要下载一个abe-all.jar包才能进行解压

1
java -jar abe-all.jar unpack app3.ab app3 tar

将上面的tar文件解压后得到一些db文件和apk安装包,运行该安装包

点击登录按钮后会显示字符串并进入空白页面

使用jadx反编译该app,定位MainActivity类查看代码逻辑

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
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private SQLiteDatabase a;
private a b;
private Button c;

/* access modifiers changed from: protected */
@Override // android.support.v4.app.BaseFragmentActivityGingerbread, android.support.v7.app.AppCompatActivity, android.support.v4.app.FragmentActivity
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_main);
this.c = (Button) findViewById(R.id.add_data);
this.c.setOnClickListener(this);
SharedPreferences.Editor edit = getSharedPreferences("test", 0).edit();
edit.putString("Is_Encroty", "1");
edit.putString("Encryto", "SqlCipher");
edit.putString("ver_sion", "3_4_0");
//这里使用SqlCipher3_4_0对数据库文件进行加密
edit.apply();
a();
}

private void a() {
SQLiteDatabase.loadLibs(this);
this.b = new a(this, "Demo.db", null, 1);//创建Demo.db的数据库文件
ContentValues contentValues = new ContentValues(); //ContentValues存储文本类对象
contentValues.put("name", "Stranger");
contentValues.put("password", (Integer) 123456);
//将"name"和"password"字段数据插入数据库中
a aVar = new a();
String a2 = aVar.a(contentValues.getAsString("name"), contentValues.getAsString("password"));
this.a = this.b.getWritableDatabase(aVar.a(a2 + aVar.b(a2, contentValues.getAsString("password"))).substring(0, 7));//ae56f99作为数据库密码
this.a.insert("TencentMicrMsg", null, contentValues); //插入TencentMicrMsg数据表中
}

public void onClick(View view) {
if (view == this.c) {
Intent intent = new Intent();
intent.putExtra("name", "name");
intent.putExtra("password", "pass");
intent.setClass(this, AnotherActivity.class); //将name和pass传递给AnotherActivity组件
startActivity(intent);
}
}

这里重点分析这两行关键代码

1
2
3
String a2 = aVar.a(contentValues.getAsString("name"), contentValues.getAsString("password"));

this.a = this.b.getWritableDatabase(aVar.a(a2 + aVar.b(a2,contentValues.getAsString("password"))).substring(0, 7));

上面的aVar类为com.example.yaphetshan.tencentwelcome.a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.yaphetshan.tencentwelcome.a;

/* compiled from: Cipher */
public class a {
private String a = "yaphetshan";

public String a(String str, String str2) {
String substring = str.substring(0, 4);
return substring + str2.substring(0, 4);
}//将str的前五个字符和str2的前五个字符进行拼接

//下面两个函数都调用了b这个类
public String b(String str, String str2) {
new b();
return b.a(str);
}

public String a(String str) {
new b();
return b.b(str + this.a);
}
}

接下来我们继续分析b这个类,这个类就是对字符进行加密处理

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
package com.example.yaphetshan.tencentwelcome.a;

import java.security.MessageDigest;

/* compiled from: SHA1Manager */
public class b {
public static final String a(String str) {
char[] cArr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try {
byte[] bytes = str.getBytes(); //将str转换为字节数组
MessageDigest instance = MessageDigest.getInstance("MD5");
instance.update(bytes);//对字节数组进行md5处理
byte[] digest = instance.digest();//返回计算md5后的字符数组
int length = digest.length;
char[] cArr2 = new char[(length * 2)];
int i = 0;
for (byte b : digest) {
int i2 = i + 1;
cArr2[i] = cArr[(b >>> 4) & 15];
i = i2 + 1;
cArr2[i2] = cArr[b & 15];
}
return new String(cArr2);
} catch (Exception e) {
return null;
}
}
//b函数使用的是SHA-1摘要算法
public static final String b(String str) {
char[] cArr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try {
byte[] bytes = str.getBytes();
MessageDigest instance = MessageDigest.getInstance("SHA-1");
instance.update(bytes);
byte[] digest = instance.digest();
int length = digest.length;
char[] cArr2 = new char[(length * 2)];
int i = 0;
for (byte b : digest) {
int i2 = i + 1;
cArr2[i] = cArr[(b >>> 4) & 15];
i = i2 + 1;
cArr2[i2] = cArr[b & 15];
}
return new String(cArr2);
} catch (Exception e) {
return null;
}
}
}

逆向还原得到写入的解密字符串,代码如下

1
2
3
4
5
6
7
8
9
10
11
public class app3 {
public static void main(String[] args)
{
a str = new a();
String str1 = str.a("Stranger","123456");
String str2 = str.a((str1+str.b(str1,"123456"))).substring(0,7);
System.out.println(str2);
}


}

计算出如下密码字符串

1
ae56f99

程序接下来使用SqlCipher对数据库文件进行加密处理,这里使用工具查看经过SQLite处理后的数据库文件Encryto.db,使用上面的密码打开数据库,可以看到里面存储的字段,这里有个Flag字段**”VGN0ZntIM2xsMF9Eb19ZMHVfTG92M19UZW5jM250IX0=”**

这里的Flag字符串推测进行了Base64编码,对其进行解码处理得到原始字符串Tctf{H3ll0_Do_Y0u_Lov3_Tenc3nt!}

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信