攻防世界 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 关键字原因,无法运行两次,会抱错导致闪退。

相关推荐
用户962377954481 天前
VulnHub DC-3 靶机渗透测试笔记
安全
用户962377954481 天前
VulnHub DC-1 靶机渗透测试笔记
笔记·测试
数据组小组2 天前
免费数据库管理工具深度横评:NineData 社区版、Bytebase 社区版、Archery,2026 年开发者该选哪个?
数据库·测试·数据库管理工具·数据复制·迁移工具·ninedata社区版·naivicat平替
叶落阁主2 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
Apifox3 天前
【测试套件】当用户说“我只想跑 P0 用例”时,我们到底在说什么
单元测试·测试·ab测试
用户962377954484 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954484 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star4 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全