攻防世界-wp-MOBILE-新手区-2-app3

题目附件:

399649a0e89b46309dd5ae78ff96917a.ab

题目思路:

通过android-backup-extractor将 .ab 文件转换为 .tar 文件,然后将apk反编译,找到密钥加密函数进行逆向解密分析,获取到密钥后,使用sqlitebrowser打开加密数据库,解密base64数据即可。

解题过程:

.ab 后缀名的文件是 Android 系统的备份文件格式,它分为加密和未加密两种类型,.ab 文件的前 24 个字节是类似文件头的东西,如果是加密的,在前 24 个字节中会有 AES 256 的标志,如果未加密,则在前 24 个字节中会有 none 的标志,使用010编辑器打开可以看到

41 4E 44 52 4F 49 44 20 42 41 43 4B 55 50 0A 32  ANDROID BACKUP.2
0A 31 0A 6E 6F 6E 65 0A 78 DA E4 7A E5 5F 93 6F  .1.none.xÚäzå_“o

下载好android-backup-extractor后使用命令java -jar abe.jar unpack 399649a0e89b46309dd5ae78ff96917a.ab 1.tar生成1.tar文件,解压后发现apk文件,使用AndroidKiller和jeb将该 APK 反编译,发现了存在asset目录和libs目录,并且这两个目录下存放了和sqlitecipher相关的文件,可以推断数据库被sqlitecipher加密了,在右边窗口打开bytecode.decompiler.MainActivity文件,发现函数a

    private void a() {
        SQLiteDatabase.loadLibs(((Context)this));//将所需要的 sqlitecipher 库文件加载进来。
        this.b = new a(((Context)this), "Demo.db", null, 1);//实例化一个sqlitehelper类
        ContentValues v0 = new ContentValues();//实例化ContentValues类
        v0.put("name", "Stranger");//将键值对name:Stranger放入其中
        v0.put("password", Integer.valueOf(123456));//将键值对password:123456放入其中。
        com.example.yaphetshan.tencentwelcome.a.a v1 = new com.example.yaphetshan.tencentwelcome.a.a();//实例化com.example.yaphetshan.tencentwelc ome.a.a类
        String v2 = v1.a(v0.getAsString("name"), v0.getAsString("password"));//获取了v2变量的值。
        this.a = this.b.getWritableDatabase(v1.a(v2 + v1.b(v2, v0.getAsString("password"))).substring(0, 7));//调用getWritableDatabase函数,传进去的字符串参数即是数据库解密的密钥。
        this.a.insert("TencentMicrMsg", null, v0);
    }

数据库解密密钥由com.example.yaphetshan.tencentwelcome.a.a里面的方法生成,简单分析一下密钥生成逻辑:

在a函数7行代码,v2调用了a类中的第一个a(String, String)方法,具体方法可以看代码注释,最后返回v2=Stra1234

在a函数8行代码,先从内部看v2 + v1.b(v2, v0.getAsString("password"))调用了 b 类的a()函数,传进去的参数是变量v2和字符串’123456’,获取到返回值后,作为参数传给v1.a().substring(0, 7)函数,该函数调用了a类中的第二个a(String)方法,然后将返回值截取前 7 位作为密钥

b类里面生成密钥的算法涉及到了sha 1、md5等 算法,没必要去重新写一编,搞清楚密钥生成逻辑后把b类里面的两个函数复制出来调用即可

package com.example.yaphetshan.tencentwelcome.a;//a类
public class a {
    private String a;
    public a() {
        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);//返回传进去的字符串加上'yaphetshan'字符串作为参数调用b类的b方法
    }
    public String b(String arg2, String arg3) {
        new b();
        return b.a(arg2);
    }
}

b.java文件如下,运行b.java后得到KEY = ae56f99,获取到密钥后,使用sqlitebrowser的DB Browser (SQLCipher)打开加密数据库(加密设置为SQLCipher 3),浏览数据发现了一串Base64的字符串,base64解码得到了 flag

import java.security.MessageDigest; 
import java.util.*;
public class b {
    public b() {
        super();
    }
    public static void main(String[] args){
        String varV2 = "Stra1234";
        String varV1B = a(varV2);
        String varKey = varV2 + varV1B + "yaphetshan";
        System.out.print("KEY = ");
        System.out.print(b(varKey).substring(0,7));
    }
    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;
    }
}

Tctf{H3ll0_Do_Y0u_Lov3_Tenc3nt!}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Scorpio-m7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值