攻防世界 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
相关推荐
龙亘川1 天前
一网统管AI平台民生业务实践:基于城市数字底座赋能公积金业务服务升级
大数据·安全·智慧城市·开源软件·数据可视化·政务
kybs19911 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
LorryJovens1 天前
【LAAP科研】双系统具身AGI范式研究——基于LAAP认知架构与Jev概率决策模型的系统性技术调研与范式验证
人工智能·gpt·安全·架构
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
山东科恩光电1 天前
提升安全性的关键技术:安全触边在工业自动化中的应用解析
安全
LONGZETECH1 天前
一线职教实测:风光 580 汽车故障诊断仿真系统,破解实车实训四大核心痛点
人工智能·学习·安全·架构·汽车
Mikko71 天前
jackson-databind 升到 2.21.6 就安全了吗?jackson-core 是另一个坐标,它那条 high 全局库至今没收
java·后端·安全·json
赛博守夜人1 天前
反舞弊系列之十四:商业地产与零售招商中的“转租差价与免租期寻租”
安全
xiaoqiMikko1 天前
你升的是 jackson-databind,中招的是 jackson-core:一个超长 JSON key 就能吃掉 200MB 堆
java·安全