您的位置:首页 > 编程语言 > Java开发

攻防世界easyJava(re Moble)

2019-05-15 14:00 246 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41429081/article/details/90234730

easyJava

题目考察:jeb反编译工具的使用,逆向能力,本题是基于enigma密码机的一个加密,可以参考博客https://blog.csdn.net/kyoma/article/details/51857944,大致题目使用的加密就是这个原理。

题目分析

private static char a(String arg1, b arg2, a arg3) {
return arg3.a(arg2.a(arg1));
}

static Boolean a(String arg1) {
return MainActivity.b(arg1);
}

private static Boolean b(String arg8) {
Boolean v0_1;
int v0 = 0;
if(!arg8.startsWith("flag{")) {
v0_1 = Boolean.valueOf(false);
}
else if(!arg8.endsWith("}")) {
v0_1 = Boolean.valueOf(false);
}
else {
String v2 = arg8.substring(5, arg8.length() - 1);
b v4 = new b(Integer.valueOf(2));
a v5 = new a(Integer.valueOf(3));
StringBuilder v3 = new StringBuilder();
int v1 = 0;
while(v0 < v2.length()) {
v3.append(MainActivity.a(v2.charAt(v0) + "", v4, v5));
Integer v6 = Integer.valueOf(v4.b().intValue() / 25);
if(v6.intValue() > v1 && v6.intValue() >= 1) {
++v1;
}

++v0;
}

v0_1 = Boolean.valueOf(v3.toString().equals("wigwrkaugala"));
}

return v0_1;
}

protected void onCreate(Bundle arg3) {
super.onCreate(arg3);
this.setContentView(2130968603);
this.findViewById(2131427446).setOnClickListener(new View$OnClickListener(((Context)this)) {
public void onClick(View arg5) {
if(MainActivity.a(this.a.findViewById(2131427445).getText().toString()).booleanValue()) {
Toast.makeText(this.a, "You are right!", 1).show();
}
else {
Toast.makeText(this.a, "You are wrong! Bye~", 1).show();
new Timer().schedule(new TimerTask() {
public void run() {
System.exit(1);
}
}, 2000);
}
}
});
}

首先,拿到题目一个apk文件,拖入jeb反编译,得到的MainActivity的大致代码如下。第一步肯定是要看到最下面的onCreate()方法,观察题目大概是要我们干什么。

可以发现,他是将我们输入的东西,传入到a()方法中,然后若返回结果是true,那么,就会输出“you are right!”。很显然我们需要令他成立。

可以看到a()方法其实并没有什么,就是调用了一下b()方法,将我们输入的传了过去。

b()方法是这个MainActivity中主要的一段代码。他有三个判断,第一个判断开头是否为“flag{”,第二个判断是否以"}"结尾。第三个比较关键,他初始化了a类和b类型为v4 v5,同时分别传入构造函数2和3.然后把我们输入的字符串的每个字符和v4,v5传入带有三个形参的a()方法中。就是去执行a.a(b.a(“字符”)),返回结果是一个字符类型的值,将每个我们输入的值执行后返回,拼接起来和”wigwrkaugala“比较,若相等就是正确的了。

public class a {
public static ArrayList a;
static String b;
Integer[] c;
static Integer d;

static {
a.a = new ArrayList();
a.b = "abcdefghijklmnopqrstuvwxyz";
a.d = Integer.valueOf(0);
}

public a(Integer arg8) {
super();
this.c = new Integer[]{Integer.valueOf(7), Integer.valueOf(14), Integer.valueOf(16), Integer.valueOf(21), Integer.valueOf(4), Integer.valueOf(24), Integer.valueOf(25), Integer.valueOf(20), Integer.valueOf(5), Integer.valueOf(15), Integer.valueOf(9), Integer.valueOf(17), Integer.valueOf(6), Integer.valueOf(13), Integer.valueOf(3), Integer.valueOf(18), Integer.valueOf(12), Integer.valueOf(10), Integer.valueOf(19), Integer.valueOf(0), Integer.valueOf(22), Integer.valueOf(2), Integer.valueOf(11), Integer.valueOf(23), Integer.valueOf(1), Integer.valueOf(8)};
int v0;
for(v0 = arg8.intValue(); v0 < this.c.length; ++v0) {
a.a.add(this.c[v0]);
}

for(v0 = 0; v0 < arg8.intValue(); ++v0) {
a.a.add(this.c[v0]);
}
}

public char a(Integer arg5) {
char v0_1;
int v0 = 0;
Integer v1 = Integer.valueOf(0);
if(arg5.intValue() == -10) {
a.a();
v0_1 = " ".charAt(0);
}
else {
while(v0 < a.a.size() - 1) {
if(a.a.get(v0) == arg5) {
v1 = Integer.valueOf(v0);
}

++v0;
}

a.a();
v0_1 = a.b.charAt(v1.intValue());
}

return v0_1;
}

public static void a() {
a.d = Integer.valueOf(a.d.intValue() + 1);
if(a.d.intValue() == 25) {
int v0 = a.a.get(0).intValue();
a.a.remove(0);
a.a.add(Integer.valueOf(v0));
a.d = Integer.valueOf(0);
}
}
}

首先对于这个a类,我们在初始化的时候传入了3,可以看到在a的构造函数中,他实现的就是相当于enigma密码机转动了三格,然后在调用a方法的时候,最终返回的值v0_1就是"abcdefghijklmnopqrstuvwxyz"的第v0个,v0就是传入的Integer类型的值在ArrayList[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]中的索引值
同时可以发现在他给v0_1赋值前,调用了void a()方法,可以发现这个方法本身是实现对ArrayList的转动,但是由于可以发现他有一个判断条件,要令成员变量d为25的时候才执行,因为d初始赋值是0,而我们也不会调用25次,所以是不会触发到这里面的。

public class b {
public static ArrayList a;
static String b;
Integer[] c;
static Integer d;

static {
b.a = new ArrayList();
b.b = "abcdefghijklmnopqrstuvwxyz";
b.d = Integer.valueOf(0);
}

public b(Integer arg9) {
super();
this.c = new Integer[]{Integer.valueOf(8), Integer.valueOf(25), Integer.valueOf(17), Integer.valueOf(23), Integer.valueOf(7), Integer.valueOf(22), Integer.valueOf(1), Integer.valueOf(16), Integer.valueOf(6), Integer.valueOf(9), Integer.valueOf(21), Integer.valueOf(0), Integer.valueOf(15), Integer.valueOf(5), Integer.valueOf(10), Integer.valueOf(18), Integer.valueOf(2), Integer.valueOf(24), Integer.valueOf(4), Integer.valueOf(11), Integer.valueOf(3), Integer.valueOf(14), Integer.valueOf(19), Integer.valueOf(12), Integer.valueOf(20), Integer.valueOf(13)};
int v0;
for(v0 = arg9.intValue(); v0 < this.c.length; ++v0) {
b.a.add(this.c[v0]);
}

for(v0 = 0; v0 < arg9.intValue(); ++v0) {
b.a.add(this.c[v0]);
}
}

public Integer a(String arg5) {
int v0 = 0;
Integer v1 = Integer.valueOf(0);
if(b.b.contains(arg5.toLowerCase())) {
Integer v2 = Integer.valueOf(b.b.indexOf(arg5));
while(v0 < b.a.size() - 1) {
if(b.a.get(v0) == v2) {
v1 = Integer.valueOf(v0);
}

++v0;
}
}
else {
if(arg5.contains(" ")) {
v1 = Integer.valueOf(-10);
goto label_24;
}

v1 = Integer.valueOf(-1);
}

label_24:
b.a();
return v1;
}

public static void a() {
int v0 = b.a.get(0).intValue();
b.a.remove(0);
b.a.add(Integer.valueOf(v0));
b.b = b.b + "" + b.b.charAt(0);
b.b = b.b.substring(1, 27);
b.d = Integer.valueOf(b.d.intValue() + 1);
}

public Integer b() {
return b.d;
}
}

b类的话其实和a类是很相似的,在构造函数的初始化适合a类的初始化是一样的,不过我们一开始传的值是2,所以就是相当于转动了二格。

然后看到b类中关键的a方法的代码,可以知道传入的是我们输入的字符串的单个字符,返回的是一个Integer类型的值,在MainActivity中作为a类的a方法的传入值。

可以知道我们的返回v1是等于v0,v0是v2在ArrayList[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]中的索引
而v2就是我们输入字符在"abcdefghijklmnopqrstuvwxyz"中的索引

然后在给v1赋值后我们可以发现,他调用了b类的void a()方法,void a()方法是实现了对ArrayList的一次转动,以及对字符串"abcdefghijklmnopqrstuvwxyz"的一次转动

到这边就分析完了,只需要写出逆向的脚本就可以得到正确的输入了。

python脚本

from collections import deque#双端队列
alpha = deque("abcdefghijklmnopqrstuvwxyz")
t1 = deque([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])
t2 = deque([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])

ss = 'wigwrkaugala'
for _ in range(2):
t1.append(t1.popleft()) #实现转动
for _ in range(3):
t2.append(t2.popleft())
print(t1)
print(t2)

def dec(s):
i = t2[(ord(s) - ord('a'))] #ord(s) - ord('a')就可以得到在那个a到z的字符中的索引值
i = t1[(i)]
print(alpha[i], end='')
t1.append(t1.popleft())
alpha.append(alpha.popleft())
for s in ss: dec(s)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: