攻防世界 XCTF 【Mobile】基础 android

首先下载 apk,然后使用 JADX 直接反编译,然后保存一下,使用 IDEA 打开即可

解法 一

可以看到,主 activity 是 MainActivity。我们安装 apk 后打开图像界面对照代码看看。

java 复制代码
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.acticity_main_1);
    this.passWord = (EditText) findViewById(R.id.passWord);
    this.login = (Button) findViewById(R.id.button);
    this.login.setOnClickListener(new View.OnClickListener() { // from class: com.example.test.ctf02.MainActivity.1
        @Override // android.view.View.OnClickListener
        public void onClick(View v) {
            String str = MainActivity.this.passWord.getText().toString();
            Check check = new Check();
            if (check.checkPassword(str)) {
                Toast.makeText(MainActivity.this, "Good,Please go on!", 0).show();
                Intent intent = new Intent(MainActivity.this, MainActivity2.class);
                MainActivity.this.startActivity(intent);
                MainActivity.this.finish();
                return;
            }
            Toast.makeText(MainActivity.this, "Failed", 0).show();
        }
    });
}

这里可以看到,当我们点击按钮的时候,系统会获取我们输入的字符串,然后放到 checkPassword() 这个函数里去,如果检测通过的话,就会开启 MainActivity2。

那么我们看一下 checkPassword() 是什么

java 复制代码
public static boolean checkPassword(String str) {
    char[] pass = str.toCharArray();
    if (pass.length != 12) {
        return false;
    }
    for (int len = 0; len < pass.length; len++) {
        pass[len] = (char) (((255 - len) - 100) - pass[len]);
        if (pass[len] != '0' || len >= 12) {
            return false;
        }
    }
    return true;
}

简单看看,调试一下,其实也不难,就是控制必须是 12 长度,然后每一位字符都必须经过处理后是 '0',其实就是一个一元一次方程,简单写个逆函数即可:

java 复制代码
public static void main(String[] args) {
    char[] pass = new char[12];

    for(int i=0; i<12; i++){
        pass[i] = (char) ((255 - i - 100) - 48);
    }

    System.out.println(Arrays.toString(pass));

}

跑一遍就能得出答案了:

java 复制代码
kjihgfedcba`

OK,输入密码后就进入了第二个页面,我们对照代码看看需要干什么。

java 复制代码
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_2);
    init();
    this.button.setOnClickListener(new View.OnClickListener() { 
        @Override // android.view.View.OnClickListener
        public void onClick(View v) {
            String str = MainActivity2.this.editText.getText().toString();
            Intent intent = new Intent(str);
            MainActivity2.this.sendBroadcast(intent);
        }
    });
}

可以看到,当点击按钮的时候,获取收入的文本的值,然后发送广播。

发送广播?为啥要发送广播呢?发送广播干啥呢?

好吧,其实在看 AndroidManifest.xml 的时候,还可以看到这里注册了一个广播接受者 receiver 实现类是 GetAndChange,接受的关键词是 android.is.very.fun

也就是说,广播的关键字是 android.is.very.fun

那么我们输入android.is.very.fun就行了

确认即可,flag 就出来了

解法二

我们这里直接去看看这个接受广播的类,内部是如何实现的呢?

java 复制代码
public class GetAndChange extends BroadcastReceiver {
    @Override // android.content.BroadcastReceiver
    public void onReceive(Context context, Intent intent) {
        Intent intent1 = new Intent(context, NextContent.class);
        context.startActivity(intent1);
    }
}

当接受广播后,开启一个 activiye ,目标类是 NextContent

那么看看,NextContent 类如何实现的

java 复制代码
public class NextContent extends AppCompatActivity {
    ImageView imageView;
    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_next_content);
        init();
        Change();
    }

    public void init() {
        this.imageView = (ImageView) findViewById(R.id.imageview);
    }

    public void Change() {
        String strFile = getApplicationContext().getDatabasePath("img.jpg").getAbsolutePath();
        try {
            File f = new File(strFile);
            if (f.exists()) {
                f.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            InputStream is = getApplicationContext().getResources().getAssets().open("timg_2.zip");
            FileOutputStream fos = new FileOutputStream(strFile);
            byte[] buffer = new byte[1024];
            while (true) {
                int count = is.read(buffer);
                if (count <= 0) {
                    break;
                }
                fos.write(buffer, 0, count);
            }
            fos.flush();
            fos.close();
            is.close();
        } catch (Exception e2) {
            e2.printStackTrace();
        }
        this.imageView.setImageBitmap(BitmapFactory.decodeFile(strFile));
    }
}

主要看 Change() 方法,这里新建一个 img.jpg 的图像对象,然后读取资源 timg_2.zip 的内容,写到 img.jpg 中去,然后显示这个图片就完事了。

好吧,也就是说我们完全可以自己去改个文件名就行了。

直接在反编译的文件内容中找到 /resources/assets/timg_2.zip 重命名为 img.jpg 即可

解法 三

由解法一可得,其实只要发起一个广播,然后广播的关键词为 android.is.very.fun ,软件自动就展示 falg 了,那么使用 adb 发起一个广播。

打开 app ,然后使用命令即可

java 复制代码
./adb shell am broadcast -a android.is.very.fun
相关推荐
CV-杨帆2 小时前
大模型在题目生成中的安全风险研究综述
人工智能·深度学习·安全
猫耳君3 小时前
汽车功能安全 Functional Safety ISO 26262 测试之一
测试开发·安全·汽车·功能安全·汽车测试·汽车电子测试
ZYMFZ3 小时前
Linux系统 SELinux 安全管理与故障排查
linux·运维·安全
BillKu3 小时前
Vue3 中使用 DOMPurify 对渲染动态 HTML 进行安全净化处理
前端·安全·html
草莓熊Lotso6 小时前
《从 0 建立测试开发认知:先搞懂 “是什么”,再学 “怎么做”》
经验分享·笔记·其他·测试
云边云科技15 小时前
门店网络重构:告别“打补丁”,用“云网融合”重塑数字竞争力!
大数据·人工智能·安全·智能路由器·零售
lingggggaaaa17 小时前
小迪安全v2023学习笔记(八十一讲)—— 框架安全&ThinkPHP&Laravel&Struts2&SpringBoot&CVE复现
笔记·学习·struts·安全·网络安全·laravel
NewCarRen17 小时前
汽车EPAS ECU功能安全建模分析:Gamma框架+深度概率编程落地ISO 26262(含寿命预测案例)
安全·汽车
cat_with_cat18 小时前
测试:BUG篇
bug·测试
Amy1870211182318 小时前
中线安防保护器,也叫终端电气综合治理保护设备为现代生活筑起安全防线
人工智能·安全·智慧城市