攻防世界 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
相关推荐
TG_yunshuguoji1 小时前
阿里云国际代理商:如何实现配置跨区域复制?
安全·阿里云·云计算
kali-Myon5 小时前
NewStarCTF2025-Week2-Pwn
算法·安全·gdb·pwn·ctf·栈溢出
胡耀超5 小时前
数据安全指南-合规治理 2025 等保2.0测评实施 全球数据保护法规对比 数据分类分级管理 ISO27001与SOC2认证 跨境数据传输合规
安全·数据安全·等保·跨境数据传输合规·数据分类分级管理·等保2.0测评实施·iso27001与soc2认证
腾视科技8 小时前
让安全驾驶有“AI”相伴|腾视科技DMS视频监控一体机,守护每一次出行
人工智能·科技·安全
Better Bench8 小时前
ubuntu20.04安全的安装可穿墙的远程软件parsec
安全·ubuntu·远程·parsec
德迅云安全-小潘10 小时前
蜜罐技术重塑网络安全新格局
安全
缘友一世10 小时前
漏洞扫描POC和web漏洞扫描工具
网络·安全·web安全
程序员二黑10 小时前
自动化测试入门:从零开始搭建你的第一个WebUI项目
单元测试·测试·ab测试
合作小小程序员小小店13 小时前
Web渗透之身份认证与访问控制缺陷(越权(水平垂直),访问控制(没有验证),脆弱验证(Cookie,JWT,Session等))
安全·web安全·网络安全·asp.net·网络攻击模型
2401_8854055116 小时前
定位守护童年,科技构筑安全屏障
科技·物联网·安全·小程序·宠物·web app·智能手表