android安全题目KGB Messenger 解题
最近发现一个有趣的题目KGB Messenger然后试着做下。
题目链接: kgb_messenger
大佬的解题步骤: 安卓逆向学习 之 KGB Messenger的writeup(1) 安卓逆向学习 之 KGB Messenger的writeup(2) 安卓逆向学习之KGBMessenger的writeup(3)
工具: jadx frida
题目: Challenges 你是国际秘密情报局的逆向工程师。今天早上,你的团队负责人指派你检查一个有问题的APP。据传有个特工斯特林·阿切尔曾与一些克格勃间谍接触并使用了这个APP。你的工作是对这个APP进行逆向,以核实谣言。 Alerts(Medium) 当我们app时,app总是给我们这些讨厌的警报。我们应该调查。 Login (Easy) 这是一个侦察挑战。密码中的所有字符都是小写的。 Social Engineering (Hard) 看来有人不善于保守秘密。他们可能容易受到社会工程的影响。我该说什么?
总共有3个地方需要解决 1.alert弹框 2.成功登录 3.社会工程?
解题: Alerts(Medium) 1.安装app打开会弹出This app can only run on Russian devices. 无法正常进入app
使用jadx打开app进行反编译,搜索该字符串
分析代码逻辑直接hook System.getProperty(“user.home”)=Russia就可以进行绕过 frida代码
function main(){
Java.perform(function(){
Java.use("java.lang.System").getProperty.overload('java.lang.String').implementation = function(arg1){
console.log(arg1)
return "Russia";
}
})
}
setImmediate(main);
//frida -U -f com.tlamb96.spetsnazmessenger --no-pause -l kgb-messenger.js
绕过之后还有个弹框提示Must be on the user whitelist. 搜索关键字
...
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView((int) R.layout.activity_main);
String property = System.getProperty("user.home");
String str = System.getenv("USER");
if (property == null || property.isEmpty() || !property.equals("Russia")) {
m4456a("Integrity Error", "This app can only run on Russian devices.");
} else if (str == null || str.isEmpty() || !str.equals(getResources().getString(R.string.User))) {
m4456a("Integrity Error", "Must be on the user whitelist.");
} else {
C0000a.m0a(this);
startActivity(new Intent(this, LoginActivity.class));
}
}
...
分析代码同理可得System.getenv这个函数等于R.string.User就可以了,然后去找R.string.User的值
RkxBR3s1N0VSTDFOR180UkNIM1J9Cg== frida代码
Java.use("java.lang.System").getenv.overload('java.lang.String').implementation = function(arg1){
console.log(arg1)
return "RkxBR3s1N0VSTDFOR180UkNIM1J9Cg==";
}
绕过两个弹框就出现了登录界面 RkxBR3s1N0VSTDFOR180UkNIM1J9Cg==这个base64是第一个flag FLAG{57ERL1NG_4RCH3R} 使用cyberchef进行解密
Login (Easy)
随便输入登录会提示User not recognized.搜索字符串到登录的Activity
public void onLogin(View view) {
EditText editText = (EditText) findViewById(R.id.login_username);
EditText editText2 = (EditText) findViewById(R.id.login_password);
this.f2542n = editText.getText().toString();
this.f2543o = editText2.getText().toString();
if (this.f2542n != null && this.f2543o != null && !this.f2542n.isEmpty() && !this.f2543o.isEmpty()) {
if (!this.f2542n.equals(getResources().getString(R.string.username))) {
Toast.makeText(this, "User not recognized.", 0).show();
editText.setText("");
editText2.setText("");
} else if (!m4455j()) {
Toast.makeText(this, "Incorrect password.", 0).show();
editText.setText("");
editText2.setText("");
} else {
m4454i();
startActivity(new Intent(this, MessengerActivity.class));
}
}
}
分析代码逻辑克制username是R.string.username的值 在strings.xml找到codenameduchess 使用命令进行输入
adb shell input text codenameduchess
密码在m4455j方法里
private boolean m4455j() {
String str = "";
for (byte b : this.f2541m.digest(this.f2543o.getBytes())) {
str = str + String.format("%x", new Object[]{Byte.valueOf(b)});
}
return str.equals(getResources().getString(R.string.password));
}
this.f2541m = MessageDigest.getInstance("MD5");
分析代码可知密码是输入值进行md5后等于R.string.password 找到84e343a0486ff05530df6c705c8bb4 在进行反md5 在网上直接可以搜到值 guest
登录成功后会弹出第2个flag
Social Engineering (Hard) 会发现有个对话框 随便输入什么没有回复,猜测是要回复某些特定的内容才可以
找到MessengerActivity类onSendMessage方法有flag字段 分析代码
...
public void onSendMessage(View view) {
EditText editText = (EditText) findViewById(R.id.edittext_chatbox);
String obj = editText.getText().toString();
if (!TextUtils.isEmpty(obj)) {
this.f2547o.add(new C0829a(R.string.user, obj, m4460j(), false));
this.f2546n.mo2625c();
if (m4457a(obj.toString()).equals(this.f2548p)) {
Log.d("MessengerActivity", "Successfully asked Boris for the password.");
this.f2549q = obj.toString();
this.f2547o.add(new C0829a(R.string.boris, "Only if you ask nicely", m4460j(), true));
this.f2546n.mo2625c();
}
if (m4458b(obj.toString()).equals(this.f2550r)) {
Log.d("MessengerActivity", "Successfully asked Boris nicely for the password.");
this.f2551s = obj.toString();
this.f2547o.add(new C0829a(R.string.boris, "Wow, no one has ever been so nice to me! Here you go friend: FLAG{" + m4459i() + "}", m4460j(), true));
this.f2546n.mo2625c();
}
this.f2545m.mo2466b(this.f2545m.getAdapter().mo2610a() - 1);
editText.setText("");
}
}
...
private String m4457a(String str) {
char[] charArray = str.toCharArray();
for (int i = 0; i < charArray.length / 2; i++) {
char c = charArray[i];
charArray[i] = (char) (charArray[(charArray.length - i) - 1] ^ '2');
charArray[(charArray.length - i) - 1] = (char) (c ^ 'A');
}
return new String(charArray);
}
....
private String f2548p = "V@]EAASB\u0012WZF\u0012e,a$7(&am2(3.\u0003";
分析代码可得输入的值经过m4457a方法后需要等于f2548p 然后需要反运算f2548p的值 分析m4457a代码charArray前一半异或了2 后一半从最后一位开始异或了A 直接复制java代码在在线平台运行代码在线平台 java代码
class Untitled {
public static void main(String[] args) {
System.out.println("hello https://tool.lu/");
String str="V@]EAASB\u0012WZF\u0012e,a$7(&am2(3.\u0003";
char[] charArray = str.toCharArray();
for (int i = 0; i < charArray.length / 2; i++) {
char c = charArray[i];
charArray[i] = (char) (charArray[(charArray.length - i) - 1] ^ 'A');
charArray[(charArray.length - i) - 1] = (char) (c ^ '2');
}
System.out.println( new String(charArray));
}
}
输出Boris, give me the password
adb shell
input text "Boris, give me the password"
然后分析获得flag的方法
···
private String m4458b(String str) {
char[] charArray = str.toCharArray();
for (int i = 0; i < charArray.length; i++) {
charArray[i] = (char) ((charArray[i] >> (i % 8)) ^ charArray[i]);
}
for (int i2 = 0; i2 < charArray.length / 2; i2++) {
char c = charArray[i2];
charArray[i2] = charArray[(charArray.length - i2) - 1];
charArray[(charArray.length - i2) - 1] = c;
}
return new String(charArray);
}
···
private String f2550r = "\u0000dslp}oQ\u0000 dks$|M\u0000h +AYQg\u0000P*!M$gQ\u0000";
...
分析算法 输入的值先进行右移坐标除以8然后在自己异或 然后在进行位置倒序 进行爆破 python 获取字符
>>> import string
>>> string.printable
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
java代码:
public class Test {
public static void main(String [] args){
String key = "\000dslp}oQ\000 dks$|M\000h +AYQg\000P*!M$gQ\000";
search(key);
}
private static void search(String paramString) {
char [] charArray = paramString.toCharArray();
for (int i2 = 0; i2 < charArray.length / 2; i2++) {
char c = charArray[i2];
charArray[i2] = charArray[(charArray.length - i2) - 1];
charArray[(charArray.length - i2) - 1] = c;
}
String test = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r";
char [] arrayOftest = test.toCharArray();
char [] arrayOfparam = charArray;
for(int i = 0 ; i < arrayOfparam.length; i++)
{
for(int j = 0; j < arrayOftest.length ; j++ ){
char c = arrayOftest[j];
c = (char)(char)((c >> (i % 8) )^ c);
if(c == arrayOfparam[i]){
System.out.print(arrayOftest[j]);
break;
}
}
}
}
}
执行结果 aay I PaEASE have the aassworda 输入后得到flag
相关文章
- Android ConstraintLayout布局详解[通俗易懂]
- android 混淆规则作用,Android代码混淆详解
- android toast显示时间,Android Toast自定义显示时间「建议收藏」
- eclipse中android开发_Android开发教程
- 开发时遇到监听的事件处理机制和SoundPool播放音效解决方法以及外部类的使用【Android】
- 【Android 安全】DEX 加密 ( Proguard 简介 | 默认 ProGuard 分析 )
- 【Android 安全】DEX 加密 ( Application 替换 | 分析 Service 组件中调用 getApplication() 获取的 Application 是否替换成功 )
- 【Android 安全】DEX 加密 ( Application 替换 | 分析 BroadcastReceiver 组件中调用 getApplication() 获取的 Application )
- 【Android 热修复】热修复原理 ( 热修复框架简介 | 将 Java 字节码文件打包到 Dex 文件 )
- 【Android 安全】使用 360 加固宝加固应用 ( 加固工具准备 | 生成签名 APK | 加固操作 | 反编译验证加固效果 )
- 【Android 插件化】Hook 插件化框架 ( 创建插件应用 | 拷贝插件 APK | 初始化插件包 | 测试插件 DEX 字节码 )
- 【ijkplayer】编译 Android 版本的 ijkplayer ③ ( 执行 compile-ffmpeg.sh clean 命令 | 下载并配置 android-ndk-r10e )
- 【Android NDK 开发】CMake 中查找链接 Android 自带动态库位置说明 ( ndk-bundleplatformsandroid-29arch-armusrlib )
- 【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ⑤ ( 优化 Gradle 构建脚本 | 构建脚本结构 | 闭包定义及用法 | 依赖配置 | android 块配置 )
- Android 12正在增强相机和麦克风隐私权限 可直接阻止这些硬件被调用
- Connecting Android to Oracle: The Ultimate Guide for Seamless Integration.(android连接oracle)
- 高通CPU现漏洞:全球9亿部Android设备受影响
- Google明年将出两款智能手表,率先用上Android Wear 2.0
- 解析android中隐藏与显示软键盘及不自动弹出键盘的实现方法
- Android模拟器(JAVA)与C++socket通讯分享
- android线性布局LinearLayout实例代码
- Android去掉自定义dialog的白色边框的简单方法