Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
066d2d2b9f
7 changed files with 186 additions and 2 deletions
|
@ -1,6 +1,9 @@
|
||||||
package de.com.baseband.launcher;
|
package de.com.baseband.launcher;
|
||||||
|
|
||||||
import de.com.baseband.launcher.classloader.CustomClassLoader;
|
import de.com.baseband.launcher.classloader.CustomClassLoader;
|
||||||
|
import de.com.baseband.launcher.security.SecurityImpl;
|
||||||
|
import de.com.baseband.launcher.security.impl.AntiInstrumentationImpl;
|
||||||
|
import de.com.baseband.launcher.security.impl.JVMArgImpl;
|
||||||
import de.com.baseband.launcher.util.RSAKey;
|
import de.com.baseband.launcher.util.RSAKey;
|
||||||
import de.com.baseband.launcher.util.Util;
|
import de.com.baseband.launcher.util.Util;
|
||||||
import de.tudbut.io.TypedInputStream;
|
import de.tudbut.io.TypedInputStream;
|
||||||
|
@ -12,8 +15,11 @@ import de.tudbut.tools.encryption.Key;
|
||||||
import de.tudbut.tools.encryption.RawKey;
|
import de.tudbut.tools.encryption.RawKey;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||||
|
import org.spongepowered.asm.lib.ClassWriter;
|
||||||
|
import org.spongepowered.asm.lib.tree.*;
|
||||||
import oshi.SystemInfo;
|
import oshi.SystemInfo;
|
||||||
import oshi.hardware.Processor;
|
import oshi.hardware.Processor;
|
||||||
|
import sun.instrument.InstrumentationImpl;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -21,10 +27,14 @@ import java.io.FileReader;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.spongepowered.asm.lib.Opcodes.*;
|
||||||
|
|
||||||
@Mod(modid = "baseband")
|
@Mod(modid = "baseband")
|
||||||
public class Loader implements Util {
|
public class Loader implements Util {
|
||||||
|
|
||||||
|
@ -114,6 +124,24 @@ public class Loader implements Util {
|
||||||
tcn.set("username", key.decryptString(reader.readLine()));
|
tcn.set("username", key.decryptString(reader.readLine()));
|
||||||
tcn.set("password", key.decryptString(reader.readLine()));
|
tcn.set("password", key.decryptString(reader.readLine()));
|
||||||
tcn.set("hardware-id", getToken());
|
tcn.set("hardware-id", getToken());
|
||||||
|
|
||||||
|
TCN antiDump = new TCN();
|
||||||
|
|
||||||
|
SecurityImpl[] securities = new SecurityImpl[] {
|
||||||
|
new AntiInstrumentationImpl(),
|
||||||
|
new JVMArgImpl()
|
||||||
|
};
|
||||||
|
|
||||||
|
for (SecurityImpl security : securities) {
|
||||||
|
antiDump.set(security.getName(), security.run());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//LOL
|
||||||
|
Class.forName("sun.instrument.InstrumentationImpl");
|
||||||
|
|
||||||
|
tcn.set("anti-dump", antiDump);
|
||||||
|
|
||||||
//LOGGER.info("MAGIC " + Base64.getEncoder().encodeToString(key.encryptString("Logging in with " + JSON.write(tcn)).getBytes()));
|
//LOGGER.info("MAGIC " + Base64.getEncoder().encodeToString(key.encryptString("Logging in with " + JSON.write(tcn)).getBytes()));
|
||||||
return tcn;
|
return tcn;
|
||||||
}
|
}
|
||||||
|
@ -122,6 +150,8 @@ public class Loader implements Util {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static String getToken() {
|
private static String getToken() {
|
||||||
String string = //this is intellij's fault I wanted a string-builder
|
String string = //this is intellij's fault I wanted a string-builder
|
||||||
Arrays.stream(systemInfo.getHardware().getProcessors()).map(Processor::getIdentifier).collect(Collectors.joining(";;")) +
|
Arrays.stream(systemInfo.getHardware().getProcessors()).map(Processor::getIdentifier).collect(Collectors.joining(";;")) +
|
||||||
|
|
|
@ -3,5 +3,6 @@ package de.com.baseband.launcher.security;
|
||||||
import de.com.baseband.launcher.util.Util;
|
import de.com.baseband.launcher.util.Util;
|
||||||
|
|
||||||
public interface SecurityImpl extends Util {
|
public interface SecurityImpl extends Util {
|
||||||
void run();
|
String getName();
|
||||||
|
boolean run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
package de.com.baseband.launcher.security.impl;
|
||||||
|
|
||||||
|
import de.com.baseband.launcher.security.SecurityImpl;
|
||||||
|
import de.com.baseband.launcher.util.Util;
|
||||||
|
import org.spongepowered.asm.lib.ClassWriter;
|
||||||
|
import org.spongepowered.asm.lib.tree.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.spongepowered.asm.lib.Opcodes.*;
|
||||||
|
|
||||||
|
public class AntiInstrumentationImpl implements SecurityImpl, Util {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "AntiInstrumentation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean run() {
|
||||||
|
byte[] classBytes = createDummyClass("sun.instrument.InstrumentationImpl");
|
||||||
|
|
||||||
|
try {
|
||||||
|
UNSAFE.defineClass("sun.instrument.InstrumentationImpl", classBytes, 0 , classBytes.length, null, null);
|
||||||
|
return isNotClassLoaded("sun.instrument.InstrumentationImpl");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] createDummyClass(String name) {
|
||||||
|
ClassNode classNode = new ClassNode();
|
||||||
|
classNode.name = name.replace('.', '/');
|
||||||
|
classNode.access = ACC_PUBLIC;
|
||||||
|
classNode.version = V1_8;
|
||||||
|
classNode.superName = "java/lang/Object";
|
||||||
|
|
||||||
|
List<MethodNode> methods = new ArrayList<>();
|
||||||
|
MethodNode clinit = new MethodNode(ACC_PUBLIC + ACC_STATIC, "<clinit>", "()V", null, null);
|
||||||
|
MethodNode init = new MethodNode(ACC_PUBLIC + ACC_STATIC, "<init>", "()V", null, null);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
InsnList insn = new InsnList();
|
||||||
|
insn.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
|
||||||
|
insn.add(new LdcInsnNode("This user tried to use "+name+"!"));
|
||||||
|
insn.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false));
|
||||||
|
insn.add(new TypeInsnNode(NEW, "java/lang/Throwable"));
|
||||||
|
insn.add(new InsnNode(DUP));
|
||||||
|
insn.add(new LdcInsnNode("Laugh at this user!"));
|
||||||
|
insn.add(new MethodInsnNode(INVOKESPECIAL, "java/lang/Throwable", "<init>", "(Ljava/lang/String;)V", false));
|
||||||
|
insn.add(new InsnNode(ATHROW));
|
||||||
|
|
||||||
|
clinit.instructions = insn;
|
||||||
|
init.instructions = insn;
|
||||||
|
|
||||||
|
methods.add(clinit);
|
||||||
|
methods.add(init);
|
||||||
|
classNode.methods = methods;
|
||||||
|
|
||||||
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||||
|
classNode.accept(classWriter);
|
||||||
|
return classWriter.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
//engrish
|
||||||
|
private static boolean isNotClassLoaded(String clazz) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
|
Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
|
||||||
|
m.setAccessible(true);
|
||||||
|
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||||
|
ClassLoader scl = ClassLoader.getSystemClassLoader();
|
||||||
|
return m.invoke(cl, clazz) == null && m.invoke(scl, clazz) == null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package de.com.baseband.launcher.security.impl;
|
||||||
|
|
||||||
|
import de.com.baseband.launcher.security.SecurityImpl;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class JVMArgImpl implements SecurityImpl {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "JVMArguments";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final List<String> BAD_INPUT_FLAGS = Arrays.asList(
|
||||||
|
"-XBootclasspath",
|
||||||
|
"-javaagent",
|
||||||
|
"-Xdebug",
|
||||||
|
"-agentlib",
|
||||||
|
"-Xrunjdwp",
|
||||||
|
"-Xnoagent",
|
||||||
|
"-verbose",
|
||||||
|
"-DproxySet",
|
||||||
|
"-DproxyHost",
|
||||||
|
"-DproxyPort",
|
||||||
|
"-Djavax.net.ssl.trustStore",
|
||||||
|
"-Djavax.net.ssl.trustStorePassword"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean run() {
|
||||||
|
Optional<String> inputFlag = ManagementFactory.getRuntimeMXBean().getInputArguments().stream()
|
||||||
|
.filter(input -> BAD_INPUT_FLAGS.stream().anyMatch(input::contains))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
return inputFlag.isPresent();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,13 @@ import de.com.baseband.launcher.security.SecurityImpl;
|
||||||
|
|
||||||
public class TestImpl implements SecurityImpl {
|
public class TestImpl implements SecurityImpl {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public String getName() {
|
||||||
|
return "Test";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean run() {
|
||||||
LOGGER.info("TestImpl");
|
LOGGER.info("TestImpl");
|
||||||
|
return false; //nothing detected LOL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package de.com.baseband.launcher.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
@SuppressWarnings("ALL")
|
||||||
|
public class Getter<T> {
|
||||||
|
private final Callable<T> callable;
|
||||||
|
|
||||||
|
public Getter(Callable<T> callable) {
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T get() {
|
||||||
|
try {
|
||||||
|
return callable.call();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,10 +2,18 @@ package de.com.baseband.launcher.util;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
public interface Util {
|
public interface Util {
|
||||||
Logger LOGGER = LogManager.getLogger("BaseBand Loader");
|
Logger LOGGER = LogManager.getLogger("BaseBand Loader");
|
||||||
SecureRandom RANDOM = new SecureRandom();
|
SecureRandom RANDOM = new SecureRandom();
|
||||||
|
|
||||||
|
Unsafe UNSAFE = new Getter<>(() -> { //uni what the FUCK
|
||||||
|
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
|
f.setAccessible(true);
|
||||||
|
return (Unsafe) f.get(null);
|
||||||
|
}).get();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue