Jump to content
Existing user? Sign In

Sign In



Sign Up

[Ruse] Block or Detect VPN / Proxy / TOR connections from logging in!


Flub

Recommended Posts

Hey guys!

I'm here with a little tutorial! 

The RSPS Scene has some notoriously shady characters. It's almost impossible to perm ban people these days because there's always a way to circumvent the standard IP / Mac bans.

Well, today you'll learn how to scan a users IP address and retrieve quality metrics such as;

  • If they're using a VPN
  • If they're on the TOR network
  • If they're using a Proxy
  • A 'Fraud Score' (Based on location, previous suspicious behaviour across the internet etc)
  • And plenty more such as their estimated location, ISP and timezone. 

So, let's get started!

First of all, you're going to need an amazing Java Library called Simple JSON <- Download here!

Once you've added the Jar to your project libraries, you're ready to start!

First of all, let's create a new java class dedicated to our new IP scanner.

All changes in this tutorial are done server sided, however it could easily be converted to a client side tool if you wanted to change logon behaviour based on the responses from the scanner.

In my example, I created IPVerification.java

An ideal location would be: 'src/com/ruse/net/login/'

The next step is to head over to IPQualityScore.com and select 'Get a free API key'

image

After you've signed up, find your API key.

Example: 'FnT1NcQRfDrhqDn43lb3srxnjOmZj2CC'

Now, back to IPVerification.java..

Go ahead and paste in the example from below. I have tried my best to annotate everything!

package com.platinum.net.login;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

import com.platinum.GameSettings;
import com.platinum.world.content.discord.DiscordMessenger;
import com.platinum.world.entity.impl.player.Player;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public final class IPVerification {

	private final static String API_KEY = "key here";
	private final static String baseURL = "https://ipqualityscore.com/api/json/ip/" + API_KEY + "/";
	
	public static void manualIPCheck(Player initiator, Player suspect) {
		try {
			//Getting the target IP Address as a string to use in the URL
			String IP = suspect.getHostAddress();
			//The URl that will show the required information.
			URL url = new URL(baseURL + IP);

			HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //Connecting to the URL
			conn.setRequestMethod("GET"); //Sending a 'GET' Request to the URL. This is the same thing that happens when you open a webpage on your PC
			conn.connect(); //Connecting to the session

			//Getting Response Code
			int responseCode = conn.getResponseCode();

			//Response code 200 means a webpage responded to our GET request successfully.
			if (responseCode != 200) {
				throw new RuntimeException("HttpResponseCode: " + responseCode);
			} else {
				Scanner sc = new Scanner(url.openStream()); //Scanner is a class which reads the results from a website response
				StringBuilder inline = new StringBuilder(); //Setting a blank string. We will add the responses to the string to build up our results
				while(sc.hasNext()) //While there are still responses, we add them to the blank string 'inline'
				{
					inline.append(sc.nextLine()); //Adding the response to nextline blank string
				}
				//System.out.println(inline); //If you want to see the full result in the console, uncomment this line (Good for debugging)
				sc.close(); //Closes the connection to prevent mem leaks!

				JSONParser parse = new JSONParser(); //Starting a new JSONParses session
				JSONObject obj = (JSONObject) parse.parse(inline.toString()); //Creating a new JSONObject and setting it equal to everything inside 'inline'

				//Using data from JSON
				String ip = obj.get("host").toString();
				boolean VPN = obj.get("vpn").toString().equals("true");
				boolean tor = obj.get("tor").toString().equals("true");
				boolean proxy = obj.get("proxy").toString().equals("true");
				boolean bot_status = obj.get("bot_status").toString().equals("true");
				int fraudScore = Integer.parseInt(obj.get("fraud_score").toString());
				String country = obj.get("country_code").toString();
				String region = obj.get("region").toString();
				String city = obj.get("city").toString();
				String isp = obj.get("ISP").toString();

				//Adding asterisks either side to make them bold in Discord
				String susUser = "**" + suspect.getUsername() + "**";
				String initUser = "**" + initiator.getUsername() + "**";

				//Formatting the results. \n is an expression that creates a new line. Purely for formatting because I have aids level OCD
				String results = "IP Scan on " + susUser + "\nIP: " + ip + "\nVPN: " + VPN + "\nTor: " + tor + "\nProxy: " + proxy + "\nBot Status: " + bot_status + "\nFraud Score: " + fraudScore + "\nCountry: " + country + "\nRegion: " + region + "\nCity: " + city + "\nISP: " + isp + "\nScan Requested by: " + initUser;
				System.out.println(results);
				DiscordMessenger.sendStaffMessage(results); //This is the location that I sent the results to, this should be changed to whatever is most relevant for you!
			}
		} catch (IOException | ParseException e) {
			e.printStackTrace();
		}
	}

	public static boolean autoIPCheck(Player suspect, String IP) {
		boolean shouldBlock = false;

		try {
			//The URl that will show the required information.
			URL url = new URL(baseURL + IP);

			HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //Connecting to the URL
			conn.setRequestMethod("GET"); //Sending a 'GET' Request to the URL. This is the same thing that happens when you open a webpage on your PC
			conn.connect(); //Connecting to the session

			//Getting Response Code
			int responseCode = conn.getResponseCode();

			//Response code 200 means a webpage responded to our GET request successfully.
			if (responseCode != 200) {
				throw new RuntimeException("HttpResponseCode: " + responseCode);
			} else {
				Scanner sc = new Scanner(url.openStream()); //Scanner is a class which reads the results from a website response
				StringBuilder inline = new StringBuilder(); //Setting a blank string. We will add the responses to the string to build up our results
				while(sc.hasNext()) {//While there are still responses, we add them to the blank string 'inline'
					inline.append(sc.nextLine()); //Adding the response to nextline blank string
				}
				//System.out.println(inline); //If you want to see the full result in the console, uncomment this line (Good for debugging)
				sc.close(); //Closes the connection to prevent mem leaks!

				JSONParser parse = new JSONParser(); //Starting a new JSONParses session
				JSONObject obj = (JSONObject) parse.parse(inline.toString()); //Creating a new JSONObject and setting it equal to everything inside 'inline'

				//Using data from JSON
				String ip = obj.get("host").toString();
				boolean VPN = obj.get("vpn").toString().equals("true");
				boolean tor = obj.get("tor").toString().equals("true");
				boolean proxy = obj.get("proxy").toString().equals("true");
				boolean bot_status = obj.get("bot_status").toString().equals("true");
				int fraudScore = Integer.parseInt(obj.get("fraud_score").toString());
				String country = obj.get("country_code").toString();
				String region = obj.get("region").toString();
				String city = obj.get("city").toString();
				String isp = obj.get("ISP").toString();
				//Adding asterisks either side to make them bold in Discord
				String susUser = "**" + suspect.getUsername() + "**";
				//Formatting the results. \n is an expression that creates a new line. Purely for formatting because I have aids level OCD
				String results = "LOGON BLOCKED FOR " + susUser + "\nIP: " + ip +"\nVPN: " + VPN + "\nTor: " + tor + "\nProxy: " + proxy + "\nBot Status: " + bot_status + "\nFraud Score: " + fraudScore + "\nCountry: " + country + "\nRegion: " + region + "\nCity: " + city + "\nISP: " + isp;

				if ((VPN || tor || (proxy && fraudScore > 90) || bot_status)
						&& !GameSettings.DEVELOPERSERVER
						&& !suspect.getRights().isSeniorStaff() //Excluding senior staff
						&& !suspect.getRights().isMember()) { //Only sending the info to staff if these prereqs are met
					DiscordMessenger.sendStaffMessage(results); //This is the location that I sent the results to, this should be changed to whatever is most relevant for you!
					shouldBlock = true;
				}
			}
		} catch (IOException | ParseException e) {
			e.printStackTrace();
		}
		return shouldBlock;
	}
}

Be sure that the JSONParser and JSONObject methods are imported from the SimpleJson lib 'org.json.simple.*'

An example command where you'd use the method..

if (command[0].equals("checkip")) {
            try {
                Player target = World.getPlayerByName(wholeCommand.substring(command[0].length() + 1));
                assert target != null;
                IPVerification.manualIPCheck(player, target);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

Of course you can use this anywhere, including in your login responses if you wanted to block access to anyone using a VPN!

Here's the final result send into Discord.

image

Now, blocking VPN Logins..

Under ConnectionHandler.java you'll find the 'getResponse' method.

Add in: 

if (IPVerification.autoIPCheck(player, host) && !GameSettings.DEVELOPERSERVER){
			PlayerPunishment.addBannedIP(host); //Also ban the IP once flagged
			return LoginResponses.LOGIN_REJECT_VPN;
		}
//Remove the !GameSettings.DEVELOPERSERVER if you don't have that.
//The autocheck method ignores local IP addresses anyway.

Next, you'll want to repurpose an unused LoginResponse found in 'LoginResponses.java'

I used response code 10.

Refactor it to match the 'LOGIN_REJECT_VPN' response name featured above! (Ctrl + F6 whilst the old name is highlighted)

OBwo6SV.png

 

Finally, in Client.java, search for loginCode == (The number you chose)

Then update the message :)

if (loginCode == 10) { //VPN Block
				loginMessages = new String[] { "VPN or Proxy Dedected!", "You cannot login using either!" };
				return;
			}

 

 

Link to comment
Share on other sites

  • 3 months later...
  • 4 weeks later...
  • 3 months later...
  • 1 year later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Contact

ltlimes

RSPS Partners

RedemptionRSPS

What is a RSPS?

A RSPS, also known as RuneScape private server, is an online game based on RuneScape, and controlled by independent individuals.

Popular RSPS Servers

oldschoolrsps Runewild RedemptionRSPS

Disclaimer

Runesuite is not affiliated with runescape, jagex, rune-server and runelocus in any way & exists solely for educational purposes.

×
×
  • Create New...