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

相关推荐
网络研究院7 小时前
Android 安卓内存安全漏洞数量大幅下降的原因
android·安全·编程·安卓·内存·漏洞·技术
l1x1n012 小时前
No.2 笔记 | 网络安全攻防:PC、CS工具与移动应用分析
安全·web安全
醉颜凉14 小时前
银河麒麟桌面操作系统V10 SP1:取消安装应用的安全授权认证
运维·安全·操作系统·国产化·麒麟·kylin os·安全授权认证
小小工匠18 小时前
Web安全 - 路径穿越(Path Traversal)
安全·web安全·路径穿越
不灭锦鲤20 小时前
ssrf学习(ctfhub靶场)
网络·学习·安全
网络研究院1 天前
如何安全地大规模部署 GenAI 应用程序
网络·人工智能·安全·ai·部署·观点
DonciSacer1 天前
TryHackMe 第6天 | Web Fundamentals (一)
安全
云卓科技1 天前
无人机之数据提取篇
科技·安全·机器人·无人机·制造
山兔11 天前
工控安全防护机制与技术
安全
HEX9CF1 天前
【CTF Web】Pikachu xss之href输出 Writeup(GET请求+反射型XSS+javascript:伪协议绕过)
开发语言·前端·javascript·安全·网络安全·ecmascript·xss