首页
社区
课程
招聘
看雪CTF.TSRC 2018 团队赛 第五题 交响曲
2018-12-10 22:29 2260

看雪CTF.TSRC 2018 团队赛 第五题 交响曲

2018-12-10 22:29
2260

第五题 交响曲

观察

题目给了个 apk,里面无 native code,看上去无加固。用 demo 版的 JEB 可以直接 decompile 得到代码。

分析

观察可以发现输入必须是一个 1984 年至 2006 年之间的日期加上 12 种后缀之一组成的字符串,之后进行了一堆奇奇怪怪的变换,成功条件为这些函数返回值加起来是 34。

解决

由于解空间太小,把 check 代码复制出来直接枚举一遍就行。

class CrackMe {
    int[] a;
    int[] daySBox;
    int[] monthSBox;
    int[] yearSBox;
    int modified_day;
    int modified_month;
    int modified_year;
    int day;
    int month;
    int year;
    int k;
    String[] l;
    String[] m;

    public CrackMe() {
        super();
        this.a = new int[]{16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6};
        this.daySBox = new int[]{5, 10, 8, 15, 16, 15, 8, 16, 8, 16, 9, 17, 8, 17, 10, 8, 9, 18, 5, 15, 10, 9, 8, 9, 15, 18, 7, 8, 16, 6};
        this.monthSBox = new int[]{6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5};
        this.yearSBox = new int[]{7, 7, 9, 12, 8, 7, 13, 5, 14, 5, 9, 17, 5, 7, 12, 8, 8, 6, 19, 6, 8, 16, 10, 6, 12, 9, 6, 7, 12, 5, 9, 8, 7, 8, 15, 9, 16, 8, 8, 19, 12, 6, 8, 7, 5, 15, 6, 16, 15, 7, 9, 12, 10, 7, 15, 6, 5, 14, 14, 9};
        this.l = new String[73];
        this.m = new String[]{"23to01", "01to03", "03to05", "05to07", "07to09", "09to11", "11to13", "13to15", "15to17", "17to19", "19to21", "21to23"};
    }

    public boolean doCheck(int year, int month, int day, String suffix) {
        this.parseInput(year, month, day);
        if(this.year != 0 && this.month != 0 && this.day != 0) {
            this.checkDate();
            return this.sYear() + this.sMonth() + this.sDay() + this.check2(suffix) == 34;
        }
        return false;
    }
    private void parseInput(int year, int month, int day) {
        this.year = 0;
        this.month = 0;
        this.day = 0;
        this.year = year;
        if(this.year > 0 && this.year < 189) {
            this.year = 0;
        }

        if(this.year <= 1983 || this.year >= 2007) {  // [1984, 2006]
            this.year = 0;
        }

        this.month = month;
        if(this.month < 1 || this.month > 12) {  // [1, 12]
            this.month = 0;
        }

        this.day = day;
        if(this.day >= 1 && this.day <= 31) {  // [1, 31]
            return;
        }

        this.day = 0;
    }

    private void checkDate() {
        if(this.year == 1989 || this.year == 2004) {
            this.day = 31;
        }

        if(this.month == 1 || this.month == 4 || this.month == 5 || this.month == 7 || this.month == 10 || this.month == 11 || this.month == 12) {
            this.year = 1999;
        }

        int k8 = 8;
        int k6 = 6;
        int k2 = 2;
        if(this.year <= 1994 && (this.month == k2 || this.month == k6 || this.month == k8)) {
            this.month = 3;
        }

        if(this.year >= 1996 && (this.month == k2 || this.month == k6 || this.month == k8)) {
            this.month = 9;
        }

        if(this.year == 1995 && (this.day > this.month + k2 || this.month == this.day)) {
            this.month = k6;
        }

        this.modified_year = this.year;
        this.modified_month = this.month;
        this.modified_day = this.day;
    }

    private int sYear() {
        return this.yearSBox[(this.modified_year - 1900) % 60];
    }

    private int sMonth() {
        return this.monthSBox[this.modified_month - 1];
    }

    private int sDay() {
        try {
            return this.daySBox[this.modified_day - 1];
        } catch (Exception e) {
            return 233;
        }
    }

    private int check2(String input) {
        int month = this.modified_month;
        int day_in_the_year = 0;
        int v0 = 0;
        while(true) {
            if(day_in_the_year >= this.m.length) {
                break;
            }
            else if(input.equals(this.m[day_in_the_year])) {
                if(month == 2 && (input.equals(this.m[6]))) {
                    return 63;
                }

                this.k = this.a[day_in_the_year];
                v0 = 1;
                break;
            }
            else {
                ++day_in_the_year;
                continue;
            }
        }

        if(v0 == 0) {
            return 63;
        }

        return this.k;
    }
}

class Main {
    public static void main(String[] args) {
        String[] suffix = new String[]{"23to01", "01to03", "03to05", "05to07", "07to09", "09to11", "11to13", "13to15", "15to17", "17to19", "19to21", "21to23"};
        CrackMe cm = new CrackMe();
        for (int year = 1984; year <= 2006; year++) {
            for (int month = 1; month <= 12; month++) {
                for (int day = 1; day <= 31; day++) {
                    for (int i = 0; i < suffix.length; i++) {
                        if (cm.doCheck(year, month, day, suffix[i])) {
                            System.out.printf("%04d%02d%02d%s", year, month, day, suffix[i]);
                        }
                    }
                }
            }
        }
    }
}

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回