aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--SECURITY.md2
-rw-r--r--build.gradle22
-rw-r--r--gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--src/main/java/gq/malwarefight/nosession/NoSessionLoadingPlugin.java13
-rw-r--r--src/main/java/gq/malwarefight/nosession/mixin/client/YggdrasilSessionMixin.java3
-rw-r--r--src/main/java/gq/malwarefight/nosession/tweaks/cleanup/CleanupTweaker.java1
-rw-r--r--src/main/java/gq/malwarefight/nosession/tweaks/initial/InitialTweaker.java37
-rw-r--r--src/main/java/gq/malwarefight/nosession/utils/Utils.java62
-rw-r--r--src/main/java/gq/malwarefight/tokenapp/Main.java3
-rw-r--r--src/main/java/gq/malwarefight/tokenapp/SocketThread.java4
-rw-r--r--src/main/resources/mixins.nosession.json2
12 files changed, 58 insertions, 97 deletions
diff --git a/README.md b/README.md
index 925d2a6..8345802 100644
--- a/README.md
+++ b/README.md
@@ -8,10 +8,10 @@ This mod doesn't make you 100% safe, but it makes it much harder to steal your s
[staying safe section](#staying-safe)
## Staying Safe
-In order to work around an unpatchable security vulnerability, rename the NoSession jar to !.jar so it can load its protection before any other mods.<br>
+In order to work around an unpatchable security vulnerability, rename the NoSession jar to !.jar, so it can load its protection before any other mods.<br>
You should also use [MultiMC](https://github.com/MultiMC/Launcher/) or one of its derivates [PolyMC](https://github.com/PolyMC/PolyMC) or [PrismLauncher](https://github.com/PrismLauncher/PrismLauncher), because they use launch Minecraft in a way that improves security.<br>
This only protects you from other mods. There are fake verification sites that can steal your session ID through that method.<br>
-Don't login with Microsoft OAuth to anything except maybe your Minecraft launcher. You may also want to verify the signature on any NoSession binary. It's signed with [pandaninjas' GPG key](https://raw.githubusercontent.com/pandaninjas/pandaninjas/main/pandaninjas-publickey.key).
+Don't log in with Microsoft OAuth to anything except maybe your Minecraft launcher. You may also want to verify the signature on any NoSession binary. It's signed with [pandaninjas' GPG key](https://raw.githubusercontent.com/pandaninjas/pandaninjas/main/pandaninjas-publickey.key).
See [ILikePlayingGames' SkyblockModSafety guide](https://github.com/ILikePlayingGames/SkyblockModSafety) for other information
diff --git a/SECURITY.md b/SECURITY.md
index 7d9b630..4a30fd7 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -15,7 +15,7 @@ Vulnerabilities that are out of scope are defined as those that NoSession itself
However, if you can produce a patch for an out-of-scope vulnerability, a bug bounty will be awarded as well.
-The bug bounty is a $5 USD Amazon Gift Card. I might run out, so it's awarded on a first come, first serve basis.
+The bug bounty is a $5 USD Amazon Gift Card. I might run out, so it's awarded on a first come, first served basis.
Report the bug bounty by sending a DM to PandaNinjas#3017 on Discord.<br>
If you would like, you can encrypt the message with my [public GPG key](https://raw.githubusercontent.com/pandaninjas/pandaninjas/main/pandaninjas-publickey.key)<br>
diff --git a/build.gradle b/build.gradle
index d7a1031..c54ce08 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,7 +13,6 @@ buildscript {
plugins {
id "java"
- id "com.github.johnrengelman.shadow" version "2.0.4"
}
apply plugin: 'net.minecraftforge.gradle.forge'
@@ -45,7 +44,7 @@ repositories {
}
dependencies {
- shade('org.spongepowered:mixin:0.7.10-SNAPSHOT') {
+ shade('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
exclude module: 'launchwrapper'
exclude module: 'guava'
exclude module: 'gson'
@@ -73,19 +72,16 @@ processResources {
rename '(.+_at.cfg)', 'META-INF/$1'
}
-shadowJar {
- dependencies {}
- configurations = [project.configurations.shade]
- duplicatesStrategy DuplicatesStrategy.EXCLUDE //prevent duplicates
- classifier "" //prevent creation of unshadowed jar
-}
-
-reobf {
- //reobfuscate the shadowed jar
- shadowJar {}
-}
jar {
+ dependsOn configurations.compile
+ from {
+ configurations.compile.collect {
+ it.isDirectory() ? it : zipTree(it)
+ }
+ }
+ exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA', 'dummyThing'
+
manifest {
attributes "ForceLoadAsMod": true,
"TweakOrder": 0,
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 357df5f..ce94abc 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip \ No newline at end of file
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip \ No newline at end of file
diff --git a/src/main/java/gq/malwarefight/nosession/NoSessionLoadingPlugin.java b/src/main/java/gq/malwarefight/nosession/NoSessionLoadingPlugin.java
index dd1c3e5..a7be261 100644
--- a/src/main/java/gq/malwarefight/nosession/NoSessionLoadingPlugin.java
+++ b/src/main/java/gq/malwarefight/nosession/NoSessionLoadingPlugin.java
@@ -5,7 +5,6 @@ import gq.malwarefight.nosession.utils.Utils;
import net.minecraft.launchwrapper.Launch;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
-import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
@@ -62,19 +61,7 @@ public class NoSessionLoadingPlugin implements IFMLLoadingPlugin {
Launch.classLoader.addURL(NoSessionLoadingPlugin.class.getProtectionDomain().getCodeSource().getLocation());
}
- public static void lock() {
- System.out.println("Waiting for lock");
- while (true) {
- File f = new File("/home/pandaninjas/lock");
- if (f.exists()) {
- f.delete();
- break;
- }
- }
- }
-
static {
- lock();
addSelfToClassLoader();
try {
Properties p = Utils.getJavaProperties();
diff --git a/src/main/java/gq/malwarefight/nosession/mixin/client/YggdrasilSessionMixin.java b/src/main/java/gq/malwarefight/nosession/mixin/client/YggdrasilSessionMixin.java
index 5451c26..25636f7 100644
--- a/src/main/java/gq/malwarefight/nosession/mixin/client/YggdrasilSessionMixin.java
+++ b/src/main/java/gq/malwarefight/nosession/mixin/client/YggdrasilSessionMixin.java
@@ -1,6 +1,5 @@
package gq.malwarefight.nosession.mixin.client;
-import com.google.common.primitives.Booleans;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
@@ -21,7 +20,7 @@ public class YggdrasilSessionMixin {
@Inject(method = "joinServer", at = @At("HEAD"), cancellable = true, remap = false)
public void joinServer(GameProfile profile, String authenticationToken, String serverId, CallbackInfo ci) throws AuthenticationException {
if (authenticationToken.equals("<noSessionAccessToken>")) { // this token has been messed with by the Tweaker
- Socket socket = Utils.getProperSocket();
+ Socket socket = Utils.getProperSocket(profile.getId());
try {
assert socket != null;
socket.getOutputStream().write(("login " + serverId + "\n").getBytes(StandardCharsets.UTF_8));
diff --git a/src/main/java/gq/malwarefight/nosession/tweaks/cleanup/CleanupTweaker.java b/src/main/java/gq/malwarefight/nosession/tweaks/cleanup/CleanupTweaker.java
index c0e2df4..a0d458b 100644
--- a/src/main/java/gq/malwarefight/nosession/tweaks/cleanup/CleanupTweaker.java
+++ b/src/main/java/gq/malwarefight/nosession/tweaks/cleanup/CleanupTweaker.java
@@ -37,6 +37,7 @@ public class CleanupTweaker implements ITweaker {
try {
Utils.setStaticValue(cls, "wrapperModMap", new HashMap<String, String>());
Utils.setStaticValue(cls, "wrapperParentMap", new HashMap<String, String>());
+ //noinspection UnstableApiUsage
Utils.setStaticValue(cls, "wrapperCache", CacheBuilder.newBuilder().maximumSize(30L).weakValues().build(new CacheLoader<String, byte[]>() {
public byte[] load(String file) throws Exception {
return (byte[]) makeWrapper.invoke(null, file);
diff --git a/src/main/java/gq/malwarefight/nosession/tweaks/initial/InitialTweaker.java b/src/main/java/gq/malwarefight/nosession/tweaks/initial/InitialTweaker.java
index e2ca1ae..21b2646 100644
--- a/src/main/java/gq/malwarefight/nosession/tweaks/initial/InitialTweaker.java
+++ b/src/main/java/gq/malwarefight/nosession/tweaks/initial/InitialTweaker.java
@@ -9,11 +9,11 @@ import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.Mixins;
import java.io.File;
-import java.io.IOException;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
public class InitialTweaker implements ITweaker {
@@ -30,22 +30,13 @@ public class InitialTweaker implements ITweaker {
*/
@Override
public final void acceptOptions(List<String> args, File gameDir, File assetsDir, String version) {
+ boolean isRelaunch = false; // is this invocation from a relaunch?
+ String uuid = null;
ArrayList<String> argsCopy = new ArrayList<>(args);
for (int i = 0; i < argsCopy.size(); i++) {
if (argsCopy.get(i).equals("--accessToken")) {
if (argsCopy.get(i + 1).equals("<noSessionAccessToken>")) {
- Runtime.getRuntime().addShutdownHook(
- new Thread(() -> {
- try {
- Socket socket = Utils.getProperSocket();
- socket.getOutputStream().write("fullquit\n".getBytes(StandardCharsets.UTF_8));
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- })
- );
- return; // don't do anything, the change has already been made
+ isRelaunch = true;
}
try {
Utils.setToken(args.get(i + 1));
@@ -53,8 +44,28 @@ public class InitialTweaker implements ITweaker {
throw new RuntimeException(e);
}
argsCopy.set(i + 1, "<noSessionAccessToken>");
+ } else if (argsCopy.get(i).equals("--uuid")) {
+ uuid = argsCopy.get(i + 1);
}
}
+ if (isRelaunch) {
+ String finalUuid = uuid;
+ if (finalUuid == null) {
+ return; // if we don't have a uuid, quit
+ }
+ Runtime.getRuntime().addShutdownHook(
+ new Thread(() -> {
+ try {
+ Socket socket = Utils.getProperSocket(UUID.fromString(finalUuid));
+ socket.getOutputStream().write("fullquit\n".getBytes(StandardCharsets.UTF_8));
+ socket.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ })
+ );
+ return; // don't do anything, the change has already been made
+ }
System.out.println("=======================");
System.out.println("NoSession: relaunching without the token");
System.out.println("=======================");
diff --git a/src/main/java/gq/malwarefight/nosession/utils/Utils.java b/src/main/java/gq/malwarefight/nosession/utils/Utils.java
index 139f1e8..7d3c4dd 100644
--- a/src/main/java/gq/malwarefight/nosession/utils/Utils.java
+++ b/src/main/java/gq/malwarefight/nosession/utils/Utils.java
@@ -20,19 +20,18 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.net.*;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Properties;
-import java.util.Random;
+import java.util.UUID;
public class Utils {
public static int PORT = -1;
- public static long ID = -1;
private static final int BASE_PORT = 47777;
public static byte[] read(InputStream i, Character delimiter) throws IOException {
@@ -60,23 +59,25 @@ public class Utils {
return new String(read(i, delimiter), StandardCharsets.UTF_8);
}
- public static Socket getProperSocket() {
+ public static Socket getProperSocket(UUID id) {
if (PORT == -1) {
Socket socket = null;
- int port = 0;
+ int port;
for (int i = BASE_PORT; i < BASE_PORT + 10; i++) {
try {
socket = new Socket();
socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), i));
- socket.getOutputStream().write("id\n".getBytes(StandardCharsets.UTF_8));
+ socket.getOutputStream().write("uuid\n".getBytes(StandardCharsets.UTF_8));
String value = readString(socket.getInputStream(), '\n');
- if (value.equals(Long.toString(ID))) {
+ if (UUID.fromString(value).equals(id)) {
port = i;
+ PORT = port;
break;
}
- } catch (Exception ignored) {}
+ } catch (Exception exception) {
+ socket = null;
+ }
}
- PORT = port;
return socket;
} else {
try {
@@ -85,7 +86,7 @@ public class Utils {
return socket;
} catch (IOException e) {
PORT = -1;
- return getProperSocket();
+ return getProperSocket(id);
}
}
}
@@ -141,37 +142,6 @@ public class Utils {
);
}
- public static boolean createLockFile(long value) {
- Path path = Paths.get(System.getProperty("java.io.tmpdir"), "NoSessionLock" + value);
- try {
- Files.createFile(path);
- } catch (FileAlreadyExistsException e) {
- LogManager.getLogger().info("You won the lottery! Two NoSession instances used the same ID. The chance that a new NoSession instance uses the same ID as an old one is (NoSession instances) / 2^64");
- return false;
- } catch (IOException e) {
- LogManager.getLogger().warn("Failed to create lockfile " + e.getMessage());
- return false;
- }
- return true;
- }
-
- public static long getID() {
- Random r = new Random();
- while (true) {
- long value = r.nextLong();
- if (createLockFile(value)) {
- Runtime.getRuntime().addShutdownHook(
- new Thread(() -> {
- try {
- Files.delete(Paths.get(System.getProperty("java.io.tmpdir"), "NoSessionLock" + value));
- } catch (Exception ignored) {}
- })
- );
- return value;
- }
- }
- }
-
public static Properties getJavaProperties() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Properties p = new Properties();
Method m = System.class.getDeclaredMethod("initProperties", Properties.class);
@@ -198,13 +168,11 @@ public class Utils {
}
public static void setToken(String token) throws IOException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, URISyntaxException {
- long value = getID();
- ID = value;
Properties p = getJavaProperties();
String cp = getClasspath(p);
System.out.println(cp);
ProcessBuilder processBuilder = new ProcessBuilder(
- getJavaExe(p), "-cp", getClasspath(p), Main.class.getName(), Long.toString(value)
+ getJavaExe(p), "-cp", getClasspath(p), Main.class.getName()
);
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT).redirectError(ProcessBuilder.Redirect.INHERIT);
Process c = processBuilder.start();
diff --git a/src/main/java/gq/malwarefight/tokenapp/Main.java b/src/main/java/gq/malwarefight/tokenapp/Main.java
index 62a4da3..ecea1f3 100644
--- a/src/main/java/gq/malwarefight/tokenapp/Main.java
+++ b/src/main/java/gq/malwarefight/tokenapp/Main.java
@@ -15,13 +15,13 @@ import java.util.UUID;
public class Main {
public static final int BASE_PORT = 47777;
- public static long ID;
public static YggdrasilMinecraftSessionService sessionService = null;
public static YggdrasilAuthenticationService authenticationService = null;
public static GameProfile gameProfile = null;
public static void setup() throws IOException {
String token = Utils.readString(System.in, '\n');
+ System.out.println(token);
YggdrasilAuthenticationService yas = new YggdrasilAuthenticationService(Proxy.NO_PROXY, token);
authenticationService = yas;
sessionService = (YggdrasilMinecraftSessionService) yas.createMinecraftSessionService();
@@ -40,7 +40,6 @@ public class Main {
}
public static void main(String[] args) {
- ID = Long.parseLong(args[0]);
try {
setup();
} catch (Exception e) {
diff --git a/src/main/java/gq/malwarefight/tokenapp/SocketThread.java b/src/main/java/gq/malwarefight/tokenapp/SocketThread.java
index de029c1..f2d0be7 100644
--- a/src/main/java/gq/malwarefight/tokenapp/SocketThread.java
+++ b/src/main/java/gq/malwarefight/tokenapp/SocketThread.java
@@ -50,8 +50,8 @@ public class SocketThread extends Thread {
sock.close();
} else if ("fullquit".equals(parts[0])) {
System.exit(0);
- } else if ("id".equals(parts[0])) {
- writeResponse(Long.toString(Main.ID), out);
+ } else if ("uuid".equals(parts[0])) {
+ writeResponse(Main.gameProfile.getId().toString(), out);
} else {
writeResponse("418 I'm a teapot", out);
}
diff --git a/src/main/resources/mixins.nosession.json b/src/main/resources/mixins.nosession.json
index 9570025..9483734 100644
--- a/src/main/resources/mixins.nosession.json
+++ b/src/main/resources/mixins.nosession.json
@@ -6,5 +6,5 @@
"client": [
"client.YggdrasilSessionMixin"
],
- "minVersion": "0.7.10"
+ "minVersion": "0.7.11"
} \ No newline at end of file