攻防世界 XCTF 【Mobile】RememberOther 题解

正常下载附件,解压后,拖到 JADX-gui 中去反编译一下,然后保存到文件夹里去,用 IDEA 打开,方便我们编辑。

打开之后,观察一下 AndroidManifest.xml 里面都有什么。

也没啥值得说的东西,直接看 MainActivity 就行了

java 复制代码
    public void onCreate(Bundle savedInstanceState) {
        ...
        
        this.edit_userName = (EditText) findViewById(R.id.edit_username);
        this.edit_sn = (EditText) findViewById(R.id.edit_sn);
        this.btn_register = (Button) findViewById(R.id.button_register);
        this.btn_register.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if (!MainActivity.this.checkSN(MainActivity.this.edit_userName.getText().toString().trim(), MainActivity.this.edit_sn.getText().toString().trim())) {
                    Toast.makeText(MainActivity.this, (int) R.string.unsuccessed, 0).show();
                    return;
                }
                Toast.makeText(MainActivity.this, (int) R.string.successed, 0).show();
                MainActivity.this.btn_register.setEnabled(false);
                MainActivity.this.setTitle(R.string.registered);
            }
        });
    }

代码很简单,获取 edit_userName 和 edit_sb 的值,然后放到 checkSN 函数里对比一下,如果错误就输出 unsuccessed 如果正确就显示 successed

简单看看 checkSN 函数的内容吧。

java 复制代码
    public boolean checkSN(String userName, String sn) {
        try {
            if (userName.length() == 0 && sn.length() == 0) {
                return true;
            }
            if (userName == null || userName.length() == 0) {
                return false;
            }
            if (sn == null || sn.length() != 16) {
                return false;
            }
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.reset();
            digest.update(userName.getBytes());
            byte[] bytes = digest.digest();
            String hexstr = toHexString(bytes, BuildConfig.FLAVOR);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hexstr.length(); i += 2) {
                sb.append(hexstr.charAt(i));
            }
            String userSN = sb.toString();
            return userSN.equalsIgnoreCase(sn);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return false;
        }
    }

啊, 这,看第一个分支,如果 userName 和 sn 长度都是 0 ,那么直接就放回 true 了,这是第一种通过检测的方法。

继续往下看,就是将 userName 进行一次 MD5,然后再调用 toHexString 函数,然后进行对比即可,看一下 toHexString 函数的具体内容

java 复制代码
    private static String toHexString(byte[] bytes, String separator) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(b & 255);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex).append(separator);
        }
        return hexString.toString();
    }

就是经过了一个 b & 255 位运算而已

那么逻辑也很简单,直接复制代码然后稍微改改,调试一下,可以看到 admin 对应的注册码是 222275aa4840481c

填入用户名和注册码,发现确实可以通过验证,然后弹出提示:md5:b3241668ecbeb19921fdac5ac1aafa69, 当然按照前面说的,这里用户名和注册码都为空的时候也是可以通过验证的。

其实,阅读完代码,这里直接去 strings.xml 中也是可以直接看到 successed 对应的字符的

那么去解密一下 MD5

尴尬,还要购买,那去看看其他师傅的结果吧,解出来是 YOU_KNOW_ 这里想起来,下载题目附件后解压后还附带了一个 docx 文档

文档里写的不懂安卓,那么看起来 YOU_KNOW_ 好像还缺了点什么,那么大概是说 你懂安卓了呗,所以猜测正确的flag 应该是 YOU_KNOW_ANDROID, 提交这个 flag 即可。

相关推荐
会飞的老朱18 分钟前
从被动应对到主动防控:大型制造集团安全管理数字化升级实践
人工智能·安全·制造·oa协同办公
大飞哥~BigFei2 小时前
新版chrome浏览器安全限制及解决办法
java·前端·chrome·安全·跨域
Gobysec2 小时前
Goby 漏洞安全通告|MindsDB /api/sql/query 未授权访问漏洞(CVE-2025-68472)
数据库·sql·安全
S0linteeH2 小时前
SafetyCulture (原名 iAuditor)
安全
pusheng20253 小时前
守护能源与数据的安全防线:从UL 2075标准解析储能及数据中心氢探技术的演进
前端·安全
寰宇视讯3 小时前
脑科技走进日常 消费级应用开启新蓝海,安全与普惠成关键
人工智能·科技·安全
智驱力人工智能3 小时前
矿山皮带锚杆等异物识别 从事故预防到智慧矿山的工程实践 锚杆检测 矿山皮带铁丝异物AI预警系统 工厂皮带木桩异物实时预警技术
人工智能·算法·安全·yolo·目标检测·计算机视觉·边缘计算
databook4 小时前
【总结整理】软件测试的反模式
单元测试·测试
石像鬼₧魂石4 小时前
WPScan 实战完整笔记(含环境搭建 + 避坑指南 + 命令手册)
数据库·安全
MicroTech20255 小时前
后量子密码算法集成:微算法科技(NASDAQ: MLGO)构建区块链安全防护的量子盾牌
科技·安全·区块链