-
-
[原创]看雪CTF.TSRC 2018 团队赛 第五题 交响曲-穷举法-解答
-
发表于: 2018-12-9 17:52 3246
-
由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 的下标才会指向正确位置,成功信息才会被显示出来
[培训]科锐软件逆向54期预科班、正式班开始火爆招生报名啦!!!
赞赏
赞赏
雪币:
留言: