buu-java逆向 题解
前置知识点
是什么
前置知识点学习了:
- 这篇博客 https://www.cnblogs.com/gzgb/p/7388536.html
- 和一些百科与实践
java是一门半解释半执行的语言,.java后缀的java源码可以理解为全解释的解释型代码,而javac编译器可以将.java后缀的代码(也就是日常所说的java代码)编译成java虚拟机可以直接使用的半编译的代码后缀为 .class,因为java虚拟机每次在运行 .java文件的时候都需要经历javac这一步,因此将java代码提前编译成javac文件无疑会提高代码编译执行速度。
- .java文件:直接写的java原代码
- .jar文件:将一系列.java文件和一些配置文件集合的一个文件夹封装成文件的形式,提高项目集成度,类似php的.phar文件
.class文件:将java原代码使用javac编译产生的字节码(jdk环境中默认安装javac编译器)
javac 文件路径.java
javap -c -verbose 文件路径.class
(javap不自带)
怎么做
回到正题,而作为ctf逆向来说直接阅读字节码显然是不现实,我们可以使用更为方便的官方的一些软件来直接反编译呈现代码。
经过查询,最为方便的要数JD-GUI
项目地址:http://java-decompiler.github.io/
因为没有java项目开发或者学习经验,因此直接采用集成度更高的
JD-GUI
。如果有相关经验的,可以采用相关的插件来使自己的编辑器支持这些功能也是可以的。
正式解题
得到反编译代码
使用JD-GUI
打开这个文件,可以得到如下已经反编译的代码,简单加上注释
import java.util.ArrayList;
import java.util.Scanner;
public class Reverse {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Please input the flag );
String str = s.next();
System.out.println("Your input is );
System.out.println(str);
char[] stringArr = str.toCharArray();
Encrypt(stringArr);//传入输入值进行验证
}
public static void Encrypt(char[] arr) {
ArrayList<Integer> Resultlist = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
int result = arr[i] + 64 ^ 0x20;//逐个进行加密后保存到Resultlist数组中
Resultlist.add(Integer.valueOf(result));
}
int[] KEY = {
180, 136, 137, 147, 191, 137, 147, 191, 148, 136,
133, 191, 134, 140, 129, 135, 191, 65 };
ArrayList<Integer> KEYList = new ArrayList<>();
for (int j = 0; j < KEY.length; j++)
KEYList.add(Integer.valueOf(KEY[j])); //把KEY的值保存到KEYLIST中
System.out.println("Result:");
if (Resultlist.equals(KEYList)) {//比对KEYList和输入值一次加密后的值相等的话输入值就是flag了
System.out.println("Congratulations");
} else {
System.err.println("Error");
}
}
}
解读加密过程
因为已知加密后应该是
int[] KEY = {
180, 136, 137, 147, 191, 137, 147, 191, 148, 136,
133, 191, 134, 140, 129, 135, 191, 65 };
并且加密运算是这样的
int result = arr[i] + 64 ^ 0x20;//逐个进行加密后保存到Resultlist数组中
很容易得到求出arr[i]
也就是答案的算法
逆向反加密代码
这里为了方便使用python写
# arr[i] = result - 64 ^ 0x20
result = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65 ]
flag = ""
for i in result:
flag += chr(i - 64 ^ 0x20)
print(flag)
输出的结果就是:This_is_the_flag_!
如图也就是flag了