作者論壇帳號:windy_ll
一、題目來源題目來源:XCTF app3題目
二、解題過程1、下載好題目,下載完後發現是.ab後綴名的文件,如下圖所示:
2、什麼是.ab文件?.ab後綴名的文件是Android系統的備份文件格式,它分為加密和未加密兩種類型,.ab文件的前24個字節是類似文件頭的東西,如果是加密的,在前24個字節中會有AES-256的標誌,如果未加密,則在前24個字節中會有none的標誌,如下圖所示:
3、怎麼獲取.ab文件中的數據?在github上有個開源項目Android backup extractor可以將.ab文件轉換為.tar文件,然後用解壓軟體打開即可!!!項目地址:https://github.com/nelenkov/android-backup-extractor
4、使用ade.jar將1.ab文件轉為tar文件解壓發現有一個apk文件和兩個sqlite資料庫文件,將apk安裝到夜神中,發現沒什麼有用的東西,去查看資料庫,直接使用sqlitebrowser打開,提示需要密碼,看來資料庫多半被加密了,如下圖所示:
5、直接使用Androidkiller和JEB將該APK反編譯,發現了存在asset目錄和libs目錄,並且這兩個目錄下存放了和sqlitecipher相關的文件,可以推斷資料庫被sqlitecipher加密了,再搜索一下在夜神裡點擊登陸後彈出的信息Wait ....,發現該信息在AnotherActivity.java文件中,轉為java後,發現沒什麼有用的信息。。。
6、於是打開MainActivity.java文件,果然發現了一個函數a(),代碼如下:
private void a() {
SQLiteDatabase.loadLibs(((Context)this));
this.b = new a(((Context)this), "Demo.db", null, 1);
ContentValues v0 = new ContentValues();
v0.put("name", "Stranger");
v0.put("password", Integer.valueOf(123456));
com.example.yaphetshan.tencentwelcome.a.a v1 = new com.example.yaphetshan.tencentwelcome.a.a();
String v2 = v1.a(v0.getAsString("name"), v0.getAsString("password"));
this.a = this.b.getWritableDatabase(v1.a(v2 + v1.b(v2, v0.getAsString("password"))).substring(0, 7));
this.a.insert("TencentMicrMsg", null, v0);
}
第一行SQLiteDatabase.loadLibs(((Context)this));將所需要的sqlitecipher庫文件加載進來。
第二行實例化一個sqlitehelper類。
第三、四、五行實例化了一個ContentValues類並將鍵值對name:Stranger、password:123456放入其中。
第六行實例化了一個com.example.yaphetshan.tencentwelcome.a.a類。
第七行獲取了v2變量的值。
第八行調用了getWritableDatabase函數,傳進去的字符串參數即是資料庫解密的密鑰。
7、現在目標已經很明確了,就是獲取資料庫解密密鑰(猜一下flag就藏在加密的sqlite資料庫中),而該密鑰由com.example.yaphetshan.tencentwelcome.a.a裡面的方法生成,而這個類又調用了b.java裡面的方法,如圖所示:
8、a、b類裡面生成密鑰的算法涉及到了sha-1、md5等算法,沒必要去重新寫一編,搞清楚密鑰生成邏輯然後把b類裡面的兩個函數複製出來調用即可生成密鑰,簡單分析一下密鑰生成邏輯:首先得到變量v2,v2調用了a類中的a(String,String)方法獲取,該方法返回第一個參數前四個字符加第二個參數的前四個字符,而調用該方法傳進去的參數為(Stranger,123456),所以v2 = Stra1234,密鑰為v1.a(String).sunstring()(調用v1.a()方法然後將返回值截取前7位作為密鑰),關鍵就在傳進去的這個字符串,可以看到這個字符串是v2 + v1.b(v2,'123456'),而v1.b(String,String)這個函數將調用了b類的a(String)函數,傳進去的參數是變量v2,獲取到返回值後,我們就可以得到這個字符串,然後調用v1.a(String)函數得到密鑰,這個函數將傳進去的字符串加上yaphetshan字符串作為參數調用b類的b方法,其返回值取前7位即是密鑰,寫了一個java獲取密鑰的代碼,運行結果如下(ps:代碼粘貼在文末中):
9、獲取到密鑰後,使用sqlitebrowser打開加密資料庫,發現了一串Base64的字符串,解碼得到了flag
三、總結
剛下載下來題目發現一看後綴名就慌了,重來沒見過的文件了,百度了n久,終於弄懂了android備份文件和ssqlitecipher這兩個東西。
給大家分享一下有關這兩個東西的知識點我覺得寫的比較好的博客!!!
題目以及所用到的工具:百度網盤連結https://pan.baidu.com/s/1Wam_Hjg8rNlpqywVqqASpQ,密碼0y89
獲取密鑰java代碼如下:
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;
}
}
--官方論壇
www.52pojie.cn
--推薦給朋友
公眾微信號:吾愛破解論壇
或搜微信號:pojie_52