WhaleCTF平台Android部分题解
###android01
利用工具对该apk进行反编译,利用jd查看其java源码由于增加了混淆,且没有so文件,java文件较少,随意浏览了一下几个文件,意外发现一段要base64解密的数列:
public static String a()
{
return new String(Base64.decode(new byte[] { 97, 72, 82, 48, 99, 68, 111, 118, 76, 122, 81, 49, 76, 106, 77, 121, 76, 106, 81, 51, 76, 106, 107, 52 }, 0));
}
将上述数列转化为字符串,解密后竟然真的得到了IP。。。。。。
Android05
将apk反编译后用jd查看java源码–坑!!!
按照MainActivity.class中的源码分析:
public void onClick(View paramAnonymousView)
{
for (;;)
{
try
{
str = MainActivity.this.text.getText().toString();
PackageInfo localPackageInfo = MainActivity.this.getPackageManager().getPackageInfo("com.example.yaphetshan.tencentgreat", 16384);
paramAnonymousView = localPackageInfo.versionName;
int i = localPackageInfo.versionCode;
j = 0;
if ((j >= str.length()) || (j >= paramAnonymousView.length())) {
continue;
}
if (str.charAt(j) != (paramAnonymousView.charAt(j) ^ i))
{
Toast.makeText(MainActivity.this, "再接再厉,加油~", 1).show();
return;
}
}
catch (PackageManager.NameNotFoundException paramAnonymousView)
{
String str;
int j;
Toast.makeText(MainActivity.this, "年轻人不要耍小聪明噢", 1).show();
continue;
}
j++;
continue;
if (str.length() != paramAnonymousView.length()) {
continue;
}
Toast.makeText(MainActivity.this, "恭喜开启闯关之门", 1).show();
}
}
对上分析可得对字符串versionname的每个字节与versioncode进行异或即可得flag-----坑来了:我先对com.example.yaphetshan.tencentgreat和16384进行异或发现错误,然后找正确的versioncode,当在BuildConfig。class中找到正确versioncode时竟发现versionname也是错的 [/想哭]
public final class BuildConfig
{
public static final String APPLICATION_ID = "com.example.yaphetshan.tencentgreat";
public static final String BUILD_TYPE = "debug";
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String FLAVOR = "";
public static final int VERSION_CODE = 15;
public static final String VERSION_NAME = "X<cP[?PHNB<P?aj";
}
然后对上述两个进行异或即可得到答案了
Android09
1、将apk反编译并利用JD查看其java源码,并将apk在模拟器中运行
2、通过题意以及apk运行至submit之后获得结果页面,定位到关键词“local”、“24H”、“History”这几个固定字符串
3、通过APK改之理等搜索关键词,定位到名为HighScoresActivity.smali的文件,利用jd查看(history只是在其中进行了定义),出于对文件名的怀疑继续查看源码,发现了showGlobalList()方法,对其中的getGlobalScores()方法继续追踪,又对其内的Score类追踪,发现了getScore()方法:
public double getScore()
{
double d;
if (GET_SCORE_FLAG == 11) {
d = getvalue();
}
for (;;)
{
return d;
if (GET_SCORE_FLAG == 31) {
d = getScoreReal();
} else {
d = -1.0D;
}
}
}
public double getvalue()
{
return 20000.0D;
}
从上可见对与GET_SCORE_FLAG变量进行修改即可得到flag
Android13
1、对apk反编译后利用jd查看其java源码,定位到simple.class的check()方法[此处怀疑jd对smali的反汇编存在问题,直接对smali文件进行分析,emmm,一大堆的switch判断语句。(简单的理了一下,果断选择找大神的WP)
2、通过大神的WP,尝试利用jeb2.2.7(用2.3.7半天加载不出进程)对APK的动态分析(还有一个是log注入输出)
https://blog.csdn.net/whklhhhh/article/details/78025563
(https://bbs.ichunqiu.com/thread-25351-1-1.html)
3、成功debug(直接用的虚拟机,没有出现大佬WP中的问题)后下断点、我们将断点下载return之前,这样既保证数据处理完毕,寄存器中的值又没有初始化
4、在模拟器中随意输入并check即可查看到VM/locals窗口下的this/B数组中的值了,将前几个非0的十六进制转化为ascii码即为flag
###Android02
1.用jadx直接查看其java源码,发现他调用了名为msky的so中的rx3sdfx函数来获取默认的信息
2.提取并利用IDA查看其so文件并反汇编分析rx3sdfx函数的伪代码
3.在伪代码的后面发现大量的异或,将数值较小的异通过ascii码转换能够正常进行转换但大数值异或后不能转化(在这上面困惑了很久)后来凑巧发现它是将数值转化为16进制并两两拆分进行异或运算。(解释如下:)
v135 ^= 0x6B6B6B6Bu;
v136 ^= 0x6B6B6B6Bu;
v137 ^= 0x6Bu;
v138 ^= 0x6Bu;
v139 ^= 0x6Bu;
v6 = (*(int (__fastcall **)(int, int *))(*(_DWORD *)v3 + 668))(v3, &v135);
上述v136 = 1548966746;
正常异或-->结果:926429233
本题异或-->1548966746 == 0x5c535b5a 将0x5c、0x53...分别与0x6B进行异或得出结果
这题做出来还是凑巧的,表示能力还是不行啊
之后的学习目标–>手动脱壳