Merge remote-tracking branch 'origin/main'
All checks were successful
/ Build BaseBand DSM & Broadway (push) Successful in 2m40s
/ Build BaseBand Installer (push) Successful in 1m5s
/ Build BaseBand Loader (push) Successful in 1m38s
/ Build BaseBand Server (push) Successful in 1m46s

This commit is contained in:
Daniella / Tove 2024-06-12 13:50:25 +02:00
commit 066d2d2b9f
Signed by: TudbuT
GPG key ID: B3CF345217F202D3
7 changed files with 186 additions and 2 deletions

View file

@ -1,6 +1,9 @@
package de.com.baseband.launcher;
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.Util;
import de.tudbut.io.TypedInputStream;
@ -12,8 +15,11 @@ import de.tudbut.tools.encryption.Key;
import de.tudbut.tools.encryption.RawKey;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import org.spongepowered.asm.lib.ClassWriter;
import org.spongepowered.asm.lib.tree.*;
import oshi.SystemInfo;
import oshi.hardware.Processor;
import sun.instrument.InstrumentationImpl;
import java.io.BufferedReader;
import java.io.File;
@ -21,10 +27,14 @@ import java.io.FileReader;
import java.lang.reflect.Method;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import static org.spongepowered.asm.lib.Opcodes.*;
@Mod(modid = "baseband")
public class Loader implements Util {
@ -114,6 +124,24 @@ public class Loader implements Util {
tcn.set("username", key.decryptString(reader.readLine()));
tcn.set("password", key.decryptString(reader.readLine()));
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()));
return tcn;
}
@ -122,6 +150,8 @@ public class Loader implements Util {
throw new RuntimeException();
}
private static String getToken() {
String string = //this is intellij's fault I wanted a string-builder
Arrays.stream(systemInfo.getHardware().getProcessors()).map(Processor::getIdentifier).collect(Collectors.joining(";;")) +

View file

@ -3,5 +3,6 @@ package de.com.baseband.launcher.security;
import de.com.baseband.launcher.util.Util;
public interface SecurityImpl extends Util {
void run();
String getName();
boolean run();
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -4,7 +4,13 @@ import de.com.baseband.launcher.security.SecurityImpl;
public class TestImpl implements SecurityImpl {
@Override
public void run() {
public String getName() {
return "Test";
}
@Override
public boolean run() {
LOGGER.info("TestImpl");
return false; //nothing detected LOL
}
}

View file

@ -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);
}
}
}

View file

@ -2,10 +2,18 @@ package de.com.baseband.launcher.util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.security.SecureRandom;
public interface Util {
Logger LOGGER = LogManager.getLogger("BaseBand Loader");
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();
}