前言:
坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:https://www.52pojie.cn/thread-1582287-1-1.html
立帖为证!--------记录学习的点点滴滴
0x1 app1
1.jadx工具打开反编译目标apk文件,找到onclick事件,看到关键代码
public void onClick(View v) {
try {
String inputString = MainActivity.this.text.getText().toString();
PackageInfo pinfo = MainActivity.this.getPackageManager().getPackageInfo(BuildConfig.APPLICATION_ID, 16384);
String versionCode = pinfo.versionName;
int versionName = pinfo.versionCode;
for (int i = 0; i < inputString.length() && i < versionCode.length(); i++) {
if (inputString.charAt(i) != (versionCode.charAt(i) ^ versionName)) {
Toast.makeText(MainActivity.this, "再接再厉,加油~", 1).show();
return;
}
}
if (inputString.length() == versionCode.length()) {
Toast.makeText(MainActivity.this, "恭喜开启闯关之门!", 1).show();
return;
}
} catch (PackageManager.NameNotFoundException e) {
}
Toast.makeText(MainActivity.this, "年轻人不要耍小聪明噢", 1).show();
}
2.看到关键的比较是这一句:
inputString.charAt(i) != (versionCode.charAt(i) ^ versionName
3.再找到BuildConfig这个类,看到了VERSION_CODE和VERSION_NAME的值。
package com.example.yaphetshan.tencentgreat;
/* loaded from: classes.dex */
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";
}
4.转换成代码一跑,得到flag:W3l_T0_GAM3_0ne。
https://s1.ax1x.com/2022/04/15/LGMv9K.png![](https://s1.ax1x.com/2022/04/15/LGMv9K.png)
0x2 app2
1.还是jadx工具打开,看到提示信息,可以看到这里动态绑定SecondActivity。
public void onClick(View view) {
switch (view.getId()) {
case R.id.button1 /* 2131165187 */:
if (this.c.getText().length() == 0 || this.d.getText().length() == 0) {
Toast.makeText(this, "不能为空", 1).show();
return;
}
String obj = this.c.getText().toString();
String obj2 = this.d.getText().toString();
Log.e("test", obj + " test2 = " + obj2);
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("ili", obj);
intent.putExtra("lil", obj2);
startActivity(intent);
return;
default:
return;
}
}
2.在apk里面安装程序,可以看到是2个文本框,输入内容,结合上面的代码可以知道,文本框的内容最终会给到SecondActivity这个类,intent.putExtra添加进去。
3.说明关键在SecondActivity这个类,看看他的java源码,取出两个文本框的内容进行拼接执行doRawData函数,然后和VEIzd/V2UPYNdn/bxH3Xig==进行比较,按正常逻辑,肯定得相等才会让我成功吧。
String stringExtra = intent.getStringExtra("ili");
String stringExtra2 = intent.getStringExtra("lil");
if (Encryto.doRawData(this, stringExtra + stringExtra2).equals("VEIzd/V2UPYNdn/bxH3Xig==")) {
intent.setAction("android.test.action.MoniterInstallService");
intent.setClass(this, MoniterInstallService.class);
intent.putExtra("company", "tencent");
intent.putExtra("name", "hacker");
intent.putExtra("age", 18);
startActivity(intent);
startService(intent);
}
SharedPreferences.Editor edit = getSharedPreferences("test", 0).edit();
edit.putString("ilil", stringExtra);
edit.putString("lili", stringExtra2);
edit.commit();
4.Encryto整个类的方法实现都在native层,那接下来就打开IDA去看一看so层代码的实现,到底干了什么:
public class Encryto {
public static native int checkSignature(Object obj);
public static native String decode(Object obj, String str);
public static native String doRawData(Object obj, String str);
public static native String encode(Object obj, String str);
public native String HelloLoad();
static {
System.loadLibrary("JNIEncrypt");
}
}
5.进去后,找到doRawData函数,第一个参数JNIEnv *env手动改一下,再往下看到关键代码,AES加密,并且AES_128_ECB_PKCS5Padding_Encrypt这个函数名给了提示。
if ( checkSignature(env, a2, a3) == 1 )
{
strcpy((char *)v10, "thisisatestkey==");
v4 = (char *)(*env)->GetStringUTFChars(env, a4, 0);
v8 = (const char *)AES_128_ECB_PKCS5Padding_Encrypt(v4, (int)v10);
(*env)->ReleaseStringUTFChars(env, (jstring)a4, v4);
result = (*env)->NewStringUTF(env, v8);
}
6.这里找到在线AES解密网站,选择ECB模式,PKCS5Padding填充,输入密文VEIzd/V2UPYNdn/bxH3Xig==和密钥thisisatestkey==,解密,但是验证结果不对:
7.F5不准确吗?动态调试一下so文件看看,先回忆一下步骤:
1)adb shell,mount -o rw,remount / 重新挂载分区,不然一会文件上传失败
2)adb push android_x86_server /sbin 上传IDA dbgsrv目录下的 android_x86_server
3)chmod +x /sbin/android_x86_server,给它可执行权限,然后输入android_x86_server,运行起来了,默认监听23946端口。
4)adb forward tcp:23946 tcp:23946命令,将手机上的23946窗口,转发到我们电脑本地的23946端口
5)dumpsys activity top,显示顶层窗口,查看包名,入口界面等信息
6)adb shell am start -D -n包名/.入口界面 以调试方式启动
7)使用ida进行如下设置,然后F2下断点,附加目标程序
8)开始调试
说明:非反调试程序,567这几步可省略,直接IDA启动调试。
8.这里没有反调试,附加,直接启动都行,运行后断在了这:
9.可以看到先是一个签名校验函数,接着处理我刚输入的1111122222,加密后给到v8,然后result返回,没毛病啊,so没问题,再来看看java层有没有问题,JEB动态调试起来,输入tencent和aimage试试,可以看到这里比较应该是相等的,但就是不对,退出了:
10.翻阅大佬们的wp,安卓xml配置里面有个活动页面没有调用,输入am start -D -n com.tencent.testvuln/.FileDataActivity将<activity android:name="com.tencent.testvuln.FileDataActivity">这个页面拉起来,看看,直接得到了flag。
0x3 总结
1.多实战,熟能生巧。