1. 这一题下载下来是个jar文件,感觉很android关系不大,但还是放在了mobile这个分类下了
2. 直接java jar运行,提示需要输入密码
# java -jar 169e139f152e45d5ae634223fe53e6be.jar
Enter password:
1234
Incorrect password
Enter password:
3. jadx 打开jar文件
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
CheckInterface checkerObject = loadCheckerObject();
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("Enter password:");
String line = stdin.readLine();
if (checkerObject.checkPassword(line)) {
System.out.println("Well done, that is the correct password");
System.exit(0);
} else {
System.out.println("Incorrect password");
}
}
}
private static CheckInterface loadCheckerObject() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, ClassFormatError, InstantiationException, IllegalAccessException {
CheckPassword mycl = new CheckPassword();
InputStream in = CheckPassword.class.getClass().getResourceAsStream("/ClassEnc");
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] bytes = new byte[512];
while (true) {
int len = in.read(bytes);
if (len > -1) {
bout.write(bytes, 0, len);
} else {
byte[] myClassBytesEnc = bout.toByteArray();
in.close();
SecretKeySpec secretKeySpec = new SecretKeySpec(hexStringToByteArray(hexKey), "AES");
Cipher decAEScipher = Cipher.getInstance("AES");
decAEScipher.init(2, secretKeySpec);
byte[] myClassBytes = decAEScipher.doFinal(myClassBytesEnc);
CheckInterface passCheckObject = (CheckInterface) mycl.defineClass(null, myClassBytes, 0, myClassBytes.length).newInstance();
return passCheckObject;
}
}
}
从这里可以看出,checkerObject 对象是通过classloader加载外部文件来获得的,外部文件还需要通过AES进行解密,那么我们只需要获得这个解密后的文件,就可以查看他的逻辑了
4 将代码复制出来,放到IDEA里运行
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
/* renamed from: CheckPassword reason: default package */
/* loaded from: 169e139f152e45d5ae634223fe53e6be.jar:CheckPassword.class */
public class CheckPassword extends ClassLoader {
static String hexKey = "bb27630cf264f8567d185008c10c3f96";
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
CheckInterface checkerObject = loadCheckerObject();
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("Enter password:");
String line = stdin.readLine();
if (checkerObject.checkPassword(line)) {
System.out.println("Well done, that is the correct password");
System.exit(0);
} else {
System.out.println("Incorrect password");
}
}
}
private static CheckInterface loadCheckerObject() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, ClassFormatError, InstantiationException, IllegalAccessException {
CheckPassword mycl = new CheckPassword();
InputStream in = CheckPassword.class.getClass().getResourceAsStream("/ClassEnc");
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] bytes = new byte[512];
while (true) {
int len = in.read(bytes);
if (len > -1) {
bout.write(bytes, 0, len);
} else {
byte[] myClassBytesEnc = bout.toByteArray();
in.close();
SecretKeySpec secretKeySpec = new SecretKeySpec(hexStringToByteArray(hexKey), "AES");
Cipher decAEScipher = Cipher.getInstance("AES");
decAEScipher.init(2, secretKeySpec);
byte[] myClassBytes = decAEScipher.doFinal(myClassBytesEnc);
writeToFile(myClassBytes);
CheckInterface passCheckObject = (CheckInterface) mycl.defineClass(null, myClassBytes, 0, myClassBytes.length).newInstance();
return passCheckObject;
}
}
}
private static void writeToFile(byte[] bytes) throws IOException {
Files.write(Paths.get("./file.class"), bytes);
}
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}
直接得到file.class, 使用IDEA打开会自动反编译成源代码,获得了MD5后的字符串fa3733c647dca53a66cf8df953c2d539
md5解密工具 https://www.cmd5.com/ 中查询得到flag monkey99