好的。因此,TryHackme是一个尝试在实验室用手教黑客的网站。他们有一个名为JVM逆向工程的房间,用户可以在这里反向工程Java应用程序,特别是我要求您查看的代码是用于任务5的。
任务5要求用户破解使用简单异或密码加密的密码。您可以自己逆向设计应用程序,但以下是重要的部分:
首先,它们的xor密码被定义为以下String:
// Decompiled from the task #5 challenge.
private static String xor(String var0) {
char[] var1 = var0.toCharArray();
char[] var2 = new char[var1.length];
for(int var3 = 0; var3 < var2.length; ++var3) {
char var4 = var1[var3];
var2[var3] = (char)(var4 ^ var3 % 3);
}
return new String(var2);
}其次,如果输入密码的XOR等于xor的correctPassword (即等于aRa2lPT6A6gIqm4RE的字符串),则密码是正确的。
我的解决方案是使用我自己修改和应用的道金斯黄鼠狼版本来“进化”,因为没有一个更好的术语,一个解决方案的“密码”可能是什么。在查看我的代码时,我希望能得到更好的反馈。以下是你在反馈中要考虑的一些问题:
以下是我的代码:
/*
* An application to crack an XOR cipher using Dawkins' weasel
* By A. S. "Aleksey" Ahmann <hackermaneia@riseup.net>
* - Githubs: https://github.com/Alekseyyy
* - TryHackMe: https://tryhackme.com/p/EntropyThot
*
* Note that some parts of this programme are borrowed from o-
* -ther sources. Most notably, the "xor" function that retur-
* -ns a String is the result of decompiling the .class file
* of TryHackMe's problem. P1's random string generator is ba-
* -sed off of the following website:
* - https://www.baeldung.com/java-random-string
*/
import java.io.*;
import java.util.*;
public class Dawkins {
private static final String correctPassword = "aRa2lPT6A6gIqm4RE";
public static void main(String[] args) {
Random random = new Random();
int counter = 1;
char[] target = correctPassword.toCharArray();
char[] solution = new char[target.length];
System.out.println("==========================================================");
System.out.println("= A crude, amateurish implementation of Dawkins' ");
System.out.println("= weasel to crack the TryHackMe XOR cipher ");
System.out.println("= By A. S. \"Aleksey\" Ahmann <hackermaneia@riseup.net> ");
System.out.println("= - https://github.com/Alekseyyy ");
System.out.println("= - https://tryhackme.com/p/EntropyThot ");
System.out.println("==========================================================\n");
boolean done = false;
while (!done) {
// [P1] Generate random string (of course the length of random string should = correctPassword)
// - this "seed" is based off of the following: https://www.baeldung.com/java-random-string
char[] seed = random.ints(48, 123)
.filter(k -> (k <= 57 || k >= 65) && (k <= 90 || k >= 97))
.limit(target.length)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString().toCharArray();
// [P2] Put the random string through the xor cipher, and split it into char array of course
char[] nextGen = xor(new String(seed)).toCharArray();
// [P3] Save the matching characters as "offspring"
boolean emptySlots = false;
for (int k = 0; k < solution.length; k++) {
if (solution[k] != Character.MIN_VALUE) {
continue;
}
else {
emptySlots = true;
if (nextGen[k] == target[k]) {
solution[k] = seed[k];
}
}
}
System.out.printf("Generation %d: %s\n", counter, new String(solution));
counter++;
if (!emptySlots) {
done = true;
}
}
System.out.printf("Solution: %s\n", new String(solution));
}
// From the decompile dump of "BasicStringObfuscation.class"
private static String xor(String var0) {
char[] var1 = var0.toCharArray();
char[] var2 = new char[var1.length];
for(int var3 = 0; var3 < var2.length; ++var3) {
char var4 = var1[var3];
var2[var3] = (char)(var4 ^ var3 % 3);
}
return new String(var2);
}
}
```发布于 2022-10-06 16:01:35
免责声明:我不是Java专家,我可能忽略了代码的一些要点。
当迭代solution的字符以检查它是否有效时,我们依赖于它以前的值,而不是我们可能给它的值。
因此,即使我们可以直接停止,我们也会经历一次额外的迭代。
这是我的建议
// [P3] Save the matching characters as "offspring"
boolean solutionIsValid = true;
for (int i = 0; i < solution.length; i++) {
if (solution[i] == Character.MIN_VALUE) {
if (cipheredSeed[i] == target[i]) {
solution[i] = seed[i];
} else {
solutionIsValid = false;
}
}
}我抓住这个机会:
大量时间用于生成随机值,对它们进行加密并检查加密值,但大多数字符被加密、错误和/或未使用。
因为每个字符都是独立加密的(否则,这里的整个逻辑都会失败),逐字符前进可能会更快。
这提供了如下内容:
/*
* An application to crack an XOR cipher using Dawkins' weasel
* By A. S. "Aleksey" Ahmann <hackermaneia@riseup.net>
* - Githubs: https://github.com/Alekseyyy
* - TryHackMe: https://tryhackme.com/p/EntropyThot
*
* Note that some parts of this programme are borrowed from o-
* -ther sources. Most notably, the "xor_str" function that retur-
* -ns a String is the result of decompiling the .class file
* of TryHackMe's problem. P1's random string generator is ba-
* -sed off of the following website:
* - https://www.baeldung.com/java-random-string
*/
import java.io.*;
import java.util.*;
public class Dawkins {
private static final String correctPassword = "aRa2lPT6A6gIqm4RE";
public static void main(String[] args) {
char[] target = correctPassword.toCharArray();
char[] solution = new char[target.length];
System.out.println("==========================================================");
System.out.println("= A crude, amateurish implementation of Dawkins' ");
System.out.println("= weasel to crack the TryHackMe XOR cipher ");
System.out.println("= By A. S. \"Aleksey\" Ahmann <hackermaneia@riseup.net> ");
System.out.println("= - https://github.com/Alekseyyy ");
System.out.println("= - https://tryhackme.com/p/EntropyThot ");
System.out.println("==========================================================\n");
for (int i = 0; i < solution.length; i++) {
// Loop over candidates
for (char c = 48; c <= 123; c++) {
if ((c <= 57 || c >= 65) && (c <= 90 || c >= 97)) {
// Check if valid
if (xor_c(c, i) == target[i]) {
solution[i] = c;
}
}
}
}
// TODO: Handle cases when 0 or many characters are found
System.out.printf("Solution: %s\n", new String(solution));
}
// From the decompile dump of "BasicStringObfuscation.class" and then refactored
private static char xor_c(char c, int index) {
return (char)(c ^ index % 3);
}
private static String xor_str(String s) {
char[] input = s.toCharArray();
char[] output = new char[input.length];
for(int i = 0; i < output.length; ++i) {
output[i] = xor_c(input[i], i);
}
return new String(output);
}
}然后,如果我们准备接受xor_c中的实际逻辑,则可以通过执行与操作相反的操作直接计算解决方案值。在这种特殊情况下,破译函数实际上也是用来加密的函数。这种想法并不能概括为任意的密码函数。
https://codereview.stackexchange.com/questions/280060
复制相似问题