-
-
看雪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漏洞挖掘与利用;代码审计。
赞赏
他的文章
看原图