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.

The verification screen

Upon clicking the “Get Code” button, it directed me to a Patreon OAuth page that afterward would redirect me to https://minecraftphysicsmode.com/verification.

The OAuth URL

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.

Screenshot of Recaf

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!

Minecraft's main menu

Here is a screenshot of the mods configuration screen

Minecraft Physics Mod configuration

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.

Successful Compilation


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.

© David Stephenson

Creative Commons by-nc-nd 4.0 International License
Acknowledgements