-
-
[原创]看雪CTF.TSRC 2018 团队赛 第五题 交响曲-穷举法-解答
-
发表于: 2018-12-9 17:52 2954
-
由ARSC文件可知失败显示" f a i l e d ! ! !",成功显示" s u c c e s s ! ! "
分析:
首先初始化了五个可疑的数组
OnCreate引用了b方法初始化字符串数组 this.l ,由下面代码可知当index=34时才有字符串其他的为空
由OnClick定位校验代码
使用JD-Core进行反编译
得到Java代码
观察:
int[] a = { 16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6 }; int[] b = { 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 }; int[] c = { 6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5 }; int[] d = { 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 }; String[] m = { "23to01", "01to03", "03to05", "05to07", "07to09", "09to11", "11to13", "13to15", "15to17", "17to19", "19to21", "21to23" };
private void b() { int i1 = 0; while (i1 <= 72) { if (i1 != 34) { this.l[i1] = getResources().getString(2131427374); } else { this.l[i1] = getResources().getString(2131427375); } i1 += 1; } }
private void a() { try { c(); if ((this.j != 0) && (this.i != 0) && (this.h != 0)) //j,i,h满足格式 { d(); a(e() + f() + g() + h());//成功 return; } this.n.setText(getString(2131427370)); //失败 return; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370));//失败 }
进入c()方法,该方法校验注册码格式是否正确
private void c() { try { str = ((EditText)findViewById(2131165227)).getText().toString(); //取出用户输入的注册码 this.j = 0; this.i = 0; this.h = 0; //注册码长度>4 if (str.length() <= 4) { break label223; } localObject = str.substring(0, 4);//取前四位(year) } catch (Exception localException) { for (;;) { String str; continue; label223: Object localObject = localException; continue; localObject = localException; } } this.j = Integer.parseInt((String)localObject); //year [0-189] [1983,2007] if ((this.j > 0) && (this.j < 189)) { this.j = 0; } if ((this.j <= 1983) || (this.j >= 2007)) { this.j = 0; } //注册码长度>6 if (str.length() > 6) { //取注册码4-6位(month) localObject = str.substring(4, 6); this.i = Integer.parseInt((String)localObject); //month[1-12] if ((this.i < 1) || (this.i > 12)) { this.i = 0; } localObject = str; //注册码长度>8 if (str.length() > 8) { //取注册码6-8位(day) localObject = str.substring(6, 8); } this.h = Integer.parseInt((String)localObject); //day[1-31] if ((this.h < 1) || (this.h > 31)) { this.h = 0; return; this.n.setText(getString(2131427370)); } return; } }
搜索成功的字符串id,可定位 a(int) : void
是设置成功信息的方法
只有paramInt=34时, this.l 的下标才会指向正确位置,成功信息才会被显示出来
private void a(int paramInt) { if ((paramInt <= 34) && (paramInt >= 34)) {} try { this.n.setText(String.format("%s%s", new Object[] { getString(2131427369), this.l[paramInt] })); //成功 ((Button)findViewById(2131165273)).setEnabled(false); return; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); return; this.n.setText(getString(2131427370)); }
paramInt 由g(),f(),e(),h()四个方法返回传入
用输入的key做前面初始化数组的下标
private int h() { try { str = ((EditText)findViewById(2131165227)).getText().toString(); str = str.substring(8, str.length()); i2 = this.f; i1 = 0; } catch (Exception localException) { for (;;) { String str; int i2; continue; i1 += 1; continue; int i1 = 0; } } if (i1 < this.m.length) { if (str.equals(this.m[i1])) { if ((i2 == 2) && (str.equals(this.m[6]))) { return 63; } this.k = this.a[i1]; i1 = 1; if (i1 == 0) { this.n.setText(getString(2131427370)); } i1 = this.k; return i1; this.n.setText(getString(2131427370)); return 0; } } private int e() { try { int i1 = this.g; i1 = this.d[((i1 - 1900) % 60)]; return i1; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); return 0; } private int f() { try { int i1 = this.f; i1 = this.c[(i1 - 1)]; return i1; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); return 0; } private int g() { try { int i1 = this.e; i1 = this.b[(i1 - 1)]; return i1; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); return 0; }
private void d()方法对this.j,this.i,this.e进行了校验修改
private void d() { try { if ((this.j == 1989) || (this.j == 2004)) { this.h = 31; } if ((this.i == 1) || (this.i == 4) || (this.i == 5) || (this.i == 7) || (this.i == 10) || (this.i == 11) || (this.i == 12)) { this.j = 1999; } if ((this.j <= 1994) && ((this.i == 2) || (this.i == 6) || (this.i == 8))) { this.i = 3; } if ((this.j >= 1996) && ((this.i == 2) || (this.i == 6) || (this.i == 8))) { this.i = 9; } if ((this.j == 1995) && ((this.h > this.i + 2) || (this.i == this.h))) { this.i = 6; } this.g = this.j; this.f = this.i; this.e = this.h; return; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); }
根据程序流程我们可以采用穷举
得到flag:1995020305to07
提交
year_d=[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 ] month_d=[ 6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5 ] day_d=[ 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 ] _d=[ 16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6 ] key=["23to01", "01to03", "03to05", "05to07", "07to09", "09to11", "11to13", "13to15", "15to17", "17to19", "19to21", "21to23" ] for y in range(1983,2007): for m in range(1,12): for d in range(1,30): for x in _d: a,b,c,e=y,m,d,x if(a in [1989,2004]): continue if(b in [1,4,5,6,7,10,11,12]): a=1999 if((a<=1994) and (b in [2,6,8])): b=3 if((a>=1996) and (b in [2,6,8])): b=9 if((a==1995) and (c>b+2 or b==c)): b=6 if year_d[(a-1900)%60]+month_d[b-1]+day_d[c-1]+e==34: print("%4d%02d%02d%s"%(y,m,d,key[_d.index(e)])) break
private void c() { try { str = ((EditText)findViewById(2131165227)).getText().toString(); //取出用户输入的注册码 this.j = 0; this.i = 0; this.h = 0; //注册码长度>4 if (str.length() <= 4) { break label223; } localObject = str.substring(0, 4);//取前四位(year) } catch (Exception localException) { for (;;) { String str; continue; label223: Object localObject = localException; continue; localObject = localException; } } this.j = Integer.parseInt((String)localObject); //year [0-189] [1983,2007] if ((this.j > 0) && (this.j < 189)) { this.j = 0; } if ((this.j <= 1983) || (this.j >= 2007)) { this.j = 0; } //注册码长度>6 if (str.length() > 6) { //取注册码4-6位(month) localObject = str.substring(4, 6); this.i = Integer.parseInt((String)localObject); //month[1-12] if ((this.i < 1) || (this.i > 12)) { this.i = 0; } localObject = str; //注册码长度>8 if (str.length() > 8) { //取注册码6-8位(day) localObject = str.substring(6, 8); } this.h = Integer.parseInt((String)localObject); //day[1-31] if ((this.h < 1) || (this.h > 31)) { this.h = 0; return; this.n.setText(getString(2131427370)); } return; } }
搜索成功的字符串id,可定位 a(int) : void
是设置成功信息的方法
只有paramInt=34时, this.l 的下标才会指向正确位置,成功信息才会被显示出来
private void a(int paramInt) { if ((paramInt <= 34) && (paramInt >= 34)) {} try { this.n.setText(String.format("%s%s", new Object[] { getString(2131427369), this.l[paramInt] })); //成功 ((Button)findViewById(2131165273)).setEnabled(false); return; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); return; this.n.setText(getString(2131427370)); }
paramInt 由g(),f(),e(),h()四个方法返回传入
用输入的key做前面初始化数组的下标
private int h() { try { str = ((EditText)findViewById(2131165227)).getText().toString(); str = str.substring(8, str.length()); i2 = this.f; i1 = 0; } catch (Exception localException) { for (;;) { String str; int i2; continue; i1 += 1; continue; int i1 = 0; } } if (i1 < this.m.length) { if (str.equals(this.m[i1])) { if ((i2 == 2) && (str.equals(this.m[6]))) { return 63; } this.k = this.a[i1]; i1 = 1; if (i1 == 0) { this.n.setText(getString(2131427370)); } i1 = this.k; return i1; this.n.setText(getString(2131427370)); return 0; } } private int e() { try { int i1 = this.g; i1 = this.d[((i1 - 1900) % 60)]; return i1; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); return 0; } private int f() { try { int i1 = this.f; i1 = this.c[(i1 - 1)]; return i1; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); return 0; } private int g() { try { int i1 = this.e; i1 = this.b[(i1 - 1)]; return i1; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); return 0; }
private void d()方法对this.j,this.i,this.e进行了校验修改
private void d() { try { if ((this.j == 1989) || (this.j == 2004)) { this.h = 31; } if ((this.i == 1) || (this.i == 4) || (this.i == 5) || (this.i == 7) || (this.i == 10) || (this.i == 11) || (this.i == 12)) { this.j = 1999; } if ((this.j <= 1994) && ((this.i == 2) || (this.i == 6) || (this.i == 8))) { this.i = 3; } if ((this.j >= 1996) && ((this.i == 2) || (this.i == 6) || (this.i == 8))) { this.i = 9; } if ((this.j == 1995) && ((this.h > this.i + 2) || (this.i == this.h))) { this.i = 6; } this.g = this.j; this.f = this.i; this.e = this.h; return; } catch (Exception localException) { for (;;) {} } this.n.setText(getString(2131427370)); }
根据程序流程我们可以采用穷举
得到flag:1995020305to07
提交
year_d=[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 ] month_d=[ 6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5 ] day_d=[ 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 ] _d=[ 16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6 ] key=["23to01", "01to03", "03to05", "05to07", "07to09", "09to11", "11to13", "13to15", "15to17", "17to19", "19to21", "21to23" ] for y in range(1983,2007): for m in range(1,12): for d in range(1,30): for x in _d: a,b,c,e=y,m,d,x if(a in [1989,2004]): continue if(b in [1,4,5,6,7,10,11,12]): a=1999 if((a<=1994) and (b in [2,6,8])): b=3 if((a>=1996) and (b in [2,6,8])): b=9 if((a==1995) and (c>b+2 or b==c)): b=6 if year_d[(a-1900)%60]+month_d[b-1]+day_d[c-1]+e==34: print("%4d%02d%02d%s"%(y,m,d,key[_d.index(e)])) break
搜索成功的字符串id,可定位 a(int) : void
是设置成功信息的方法
只有paramInt=34时, this.l 的下标才会指向正确位置,成功信息才会被显示出来
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
看原图
赞赏
雪币:
留言: