Cracking Minecraft Physics Mod
Circumventing verification using DNS manipulation
While browsing YouTube, I discovered the Minecraft Physics Mod, created by Haubna, which caught my interest and prompted me to try it out. I enjoyed the free version but was also curious about the paid version. Unfortunately, it was only available via a Patreon membership, so I looked for other sources online and eventually found a copy. When I launched the mod, A prompt asked me for a verification code, ensuring I paid for the mod.
Upon clicking the “Get Code” button, it directed me to a Patreon OAuth page that afterward would redirect me to https://minecraftphysicsmode.com/verification
.
I knew that it would be impossible to circumvent an OAuth request, so I chose to decompile the mod and examine its source code to determine if there were any possible ways to bypass the verification process.
It is important to note that both Minecraft and many of its mods are written in the Java programming language. The Minecraft Physics mod is one such example. Given the use of the right tools, decompiling the mod should be a straightforward task.
I used Recaf, a Java bytecode editor, which enables me to decompile, edit, recompile the code inside java files.
After conducting short a search, I located the Java class that handles the logic for the verification screen. Further exploration inside the class led me to find a function called verify
inside a class called VerificationScreen
that sends a HTTP request to a server.
private void verify(String changed) {
this.waitingForVerification = true;
this.queueNextVerification = false;
if (!changed.contains("https://") && !changed.contains("http://")) {
String mcName = getMinecraftName();
Thread thread = new Thread(() -> {
try {
String result = HttpRequest.get("http://verify.minecraftphysicsmod.com:4567/verify?code=" + changed + "&name=" + mcName);
verified = result.contains(changed + "verified");
if (verified) {
ConfigClient.verificationCode = changed;
ConfigClient.save();
this.localVerified = true;
} else {
this.errorMsg = result;
}
} catch (Exception var7) {
var7.printStackTrace();
this.errorMsg = var7.getMessage();
} finally {
this.waitingForVerification = false;
}
});
thread.setName("Verification Thread");
thread.setDaemon(true);
thread.start();
} else {
this.waitingForVerification = false;
}
}
The function in question takes a parameter called ‘changed’ which is the code entered by the user. Additionally, the function also retrieves the Minecraft username from the client. Subsequently, both the code and the username are sent to a web server server located at http://verify.minecraftphysicsmod.com:4567/verify
for verification. The usernames are sent most likely to disable codes that have possibly been leaked and used by multiple users.
When a correct code is sent to the server, the server will respond with the code and the string “verified” concatenated together.
Here is an example of what is happening:
Code | Server Response |
---|---|
123 | 123verified |
ThisIsARealCode | ThisIsARealCodeverified |
It is worth noting that the verification server uses HTTP instead of HTTPS, which makes it relatively simple to intercept DNS requests and redirect them to a web server that verifies each code it receives, without having to deal with the complexities of HTTPS certificates. So that’s exactly what I did. 😉
“I set up a web server using NodeJS and express.js that is able to verify any code it receives.”
const app = require("express")();
app.get("/verify", (req, res) => {
res.send(`${req.query.code}verified`);
});
app.listen(4567, () => {});
I am using Fedora Linux, I modified the /etc/hosts configuration file by adding an entry to resolve verify.minecraftphysicsmod.com
to my loopback address.
# Loopback entries; do not change.
# For historical reasons, localhost precedes localhost.localdomain:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# See hosts(5) for proper format and other examples:
# 192.168.1.10 foo.mydomain.org foo
# 192.168.1.13 bar.mydomain.org bar
127.0.0.1 verify.minecraftphysicsmod.com
After promptly refreshing my DNS records and double-checking that everything was configured properly, I launched Minecraft and waited with anticipation. Initially, I saw the verification screen again, but as soon as I brought the game window into focus, the verification screen disappeared and I was presented with the main menu of Minecraft!
Here is a screenshot of the mods configuration screen
But wait, There’s also another method. Earlier I mentioned that Recaf could edit and recompile the code inside Java files. Why run a verification server when you can edit the code?
The VerificationScreen
class imports a utility class called HttpRequest
. This class contains a function named get
, which takes in a URL as a parameter. The function sends an HTTP get request to the specified URL and returns the response from the web server.
package net.diebuddies.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpRequest {
public static String get(String urlToRead) throws IOException {
StringBuilder result = new StringBuilder();
URL url = new URL(urlToRead);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setRequestMethod("GET");
connection.setInstanceFollowRedirects(true);
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
try {
while((line = reader.readLine()) != null) {
result.append(line);
}
} catch (Throwable var8) {
try {
reader.close();
} catch (Throwable var7) {
var8.addSuppressed(var7);
}
throw var8;
}
reader.close();
return result.toString();
}
}
The get
function within the HttpRequest
class returns the string that the verify function uses to perform the verification logic. By altering the function to return verified
, it will trigger a successful verification, thereby disabling the verification screen.
public class HttpRequest {
public static String get(String urlToRead) throws IOException {
return "verified";
}
}
When you recompile the class and launch Minecraft, the verification screen will be bypassed instantly.
Please note that this post was made to demonstrate my discovery. If you follow these steps, don’t be a loser and pay for the mod beforehand. It’s a single guy working on the mod.