攻防世界 XCTF 【Mobile】easyjava 题解

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

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

值得注意的东西:

js 复制代码
js复制代码包名:com.a.easyjava
Main Activity:com.a.easyjava.MainActivity

看看 MainActivity 怎么写的

java 复制代码
public void onCreate(Bundle bundle) {

    findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            if (MainActivity.b(((EditText) ((MainActivity) this).findViewById(R.id.edit)).getText().toString()).booleanValue()) {
                Toast.makeText(this, "You are right!", 1).show();
                return;
            }
            Toast.makeText(this, "You are wrong! Bye~", 1).show();
            new Timer().schedule(new TimerTask() { 
                public void run() {
                    System.exit(1);
                }
            }, 2000L);
        }
    });
}

MainActivity 里没啥特别的东西,就是 if 判断那里,将输入框里的东西传入 MainActivity.b() 函数里判断一下,如果正确就提示正确。

那么分析一下 b 函数内容吧

java 复制代码
public static Boolean b(String str) {
    if (str.startsWith("flag{") && str.endsWith("}")) {
        String substring = str.substring(5, str.length() - 1);
        b bVar = new b(2);
        a aVar = new a(3);
        StringBuilder sb = new StringBuilder();
        int i = 0;
        for (int i2 = 0; i2 < substring.length(); i2++) {
            sb.append(a(substring.charAt(i2) + "", bVar, aVar));
            Integer valueOf = Integer.valueOf(bVar.b().intValue() / 25);
            if (valueOf.intValue() > i && valueOf.intValue() >= 1) {
                i++;
            }
        }
        return Boolean.valueOf(sb.toString().equals("wigwrkaugala"));
    }
    return false;
}

这里就涉及到 a、b 类了,因为反编译的代码里面爆了好多红色代码错误,那么我们把代码复制到别的文件夹里去重新打开,尝试跑一下代码,我把这几个类都放到一个文件里去了

把爆红的地方改改,在不改变代码逻辑的基础上,修改一下代码的格式,差不多能运行就行

然后在 main 方法里面调用 b 方法,一步一步调试,去看看代码到底需要满足什么条件,这个过程就没法一一展示了,需要你自己去理解代码了。也不需要太仔细看。

仔细调试了一遍发现,这个判断是一位一位判断的,不像是 md5 那样位数是固定的,那么好办了,一种思路直接排列组合所有可能性直接爆破,但是 12 的 26 次方也太大了,内存不够, 咋办呢,再读读代码,猜测一下,能不能一位一位的去试试呢。

需要注意的是,这里的类大量使用了 static 这导致这些类的属性是不会在第二次运行的时候而重置的,所以你必须把 static 关键字给他取掉。(超级坑,如果不是程序会报错,我估计就没有这篇文章了😭)

java 复制代码
import java.util.ArrayList;

public class CTF {
    public static void main(String[] args) {
        String b = "abcdefghijklmnopqrstuvwxyz";
        char[] flag = {'a','a','a','a','a','a','a','a','a','a','a','a'};
        // 遍历 flag 的每一位,然后在 b 函数里输出结果,
        int i = 0; // 一步一步从 0 开始尝试,尝试出来一个就把 flag 改一个。
        for(int j =0;j<b.length();j++){
            flag[i] = b.charAt(j);
            String s = "flag{" + new String(flag) + "}";
            b(s);
        }

    }

    private static char a(String str, b bVar, a aVar) {
        return aVar.a(bVar.a(str));
    }

    public static Boolean b(String str) {
        if (str.startsWith("flag{") && str.endsWith("}")) {
            String substring = str.substring(5, str.length() - 1);
            b bVar = new b(2);
            a aVar = new a(3);
            StringBuilder sb = new StringBuilder();
            int i = 0;
            for (int i2 = 0; i2 < substring.length(); i2++) {
                sb.append(a(substring.charAt(i2) + "", bVar, aVar));
                Integer valueOf = Integer.valueOf(bVar.b().intValue() / 25);
                if (valueOf.intValue() > i && valueOf.intValue() >= 1) {
                    i++;
                }
            }

            // 这里打印出来看看结果
            System.out.println("输入的 falg:" + str + "输出结果: " + sb);
            return Boolean.valueOf(sb.toString().equals("wigwrkaugala"));
        }
        return false;
    }
}

class a {
    public  ArrayList<Integer> a = new ArrayList<>();
     String b = "abcdefghijklmnopqrstuvwxyz";
     Integer d = 0;
    Integer[] c = {7, 14, 16, 21, 4, 24, 25, 20, 5, 15, 9, 17, 6, 13, 3, 18, 12, 10, 19, 0, 22, 2, 11, 23, 1, 8};

    public a(Integer num) {
        for (int intValue = num.intValue(); intValue < this.c.length; intValue++) {
            a.add(this.c[intValue]);
        }
        for (int i = 0; i < num.intValue(); i++) {
            a.add(this.c[i]);
        }
    }

    public  void a() {
        Integer num = d;
        d = Integer.valueOf(d.intValue() + 1);
        if (d.intValue() == 25) {
            int intValue = a.get(0).intValue();
            a.remove(0);
            a.add(Integer.valueOf(intValue));
            d = 0;
        }
    }

    public char a(Integer num) {
        Integer num2 = 0;
        if (num.intValue() == -10) {
            a();
            return " ".charAt(0);
        }
        for (int i = 0; i < a.size() - 1; i++) {
            if (a.get(i) == num) {
                num2 = Integer.valueOf(i);
            }
        }
        a();
        return b.charAt(num2.intValue());
    }
}

class b {
    public  ArrayList<Integer> a = new ArrayList<>();
     String b = "abcdefghijklmnopqrstuvwxyz";
     Integer d = 0;
    Integer[] c = {8, 25, 17, 23, 7, 22, 1, 16, 6, 9, 21, 0, 15, 5, 10, 18, 2, 24, 4, 11, 3, 14, 19, 12, 20, 13};

    public b(Integer num) {
        for (int intValue = num.intValue(); intValue < this.c.length; intValue++) {
            a.add(this.c[intValue]);
        }
        for (int i = 0; i < num.intValue(); i++) {
            a.add(this.c[i]);
        }
    }

    public  void a() {
        int intValue = a.get(0).intValue();
        a.remove(0);
        a.add(Integer.valueOf(intValue));
        b += "" + b.charAt(0);
        b = b.substring(1, 27);
        Integer num = d;
        d = Integer.valueOf(d.intValue() + 1);
    }

    public Integer a(String str) {
        int i = 0;
        if (b.contains(str.toLowerCase())) {
            Integer valueOf = Integer.valueOf(b.indexOf(str));
            for (int i2 = 0; i2 < a.size() - 1; i2++) {
                if (a.get(i2) == valueOf) {
                    i = Integer.valueOf(i2);
                }
            }
        } else {
            i = str.contains(" ") ? -10 : -1;
        }
        a();
        return i;
    }

    public Integer b() {
        return d;
    }
}

好像确实是我猜想的那样,后面的就算是错误的也不影响我们验证前面的。那就好,直接手动去试试得了。

先修改 i = 0;发现 v 对应的是 w

ok,flag 第一位设置为 v ,然后 i = 1;继续尝试

ok ,可以看到第二位应该是 ve 对应 wi,

.........

以此类推即可找到正确的 flag

最后发现有多个 flag 都是符合的, 一共有 10 个,都能得到结果,这就尴尬了,提交哪一个呢。

发现官方提交 flag 的时候只有一个判断为正确。

java 复制代码
flag{venividivicr}
flag{venividivici}
flag{venividivkci}
flag{venividivkcr}  // 这个是题目要提交的。
flag{venividivkci}
flag{venividivkcr}
flag{veniviaivicr}
flag{veniviaivici}
flag{veniviaivkci}
flag{veniviaivkcr}

这里需要注意一点,app 安装到手机上去之后,因为 static 关键字原因,无法运行两次,会抱错导致闪退。

相关推荐
前端页面仔28 分钟前
易语言是什么?易语言能做什么?
开发语言·安全
大话性能5 小时前
Mysql 百万级数据迁移实战笔记
测试
Guheyunyi8 小时前
监测预警系统重塑隧道安全新范式
大数据·运维·人工智能·科技·安全
IT科技那点事儿9 小时前
引领AI安全新时代 Accelerate 2025北亚巡展·北京站成功举办
人工智能·安全
乾巫宇宙国监察特使12 小时前
Python的设计模式
python·测试
恰薯条的屑海鸥14 小时前
零基础在实践中学习网络安全-皮卡丘靶场(第十四期-XXE模块)
网络·学习·安全·web安全·渗透测试
20242817李臻14 小时前
20242817李臻-安全文件传输系统-项目验收
数据库·安全
DevSecOps选型指南1 天前
2025软件供应链安全最佳实践︱证券DevSecOps下供应链与开源治理实践
网络·安全·web安全·开源·代码审计·软件供应链安全
ABB自动化1 天前
for AC500 PLCs 3ADR025003M9903的安全说明
服务器·安全·机器人
恰薯条的屑海鸥1 天前
零基础在实践中学习网络安全-皮卡丘靶场(第十六期-SSRF模块)
数据库·学习·安全·web安全·渗透测试·网络安全学习