holy __shit__
This commit is contained in:
Jess 2023-09-29 02:38:47 +01:00
parent 2eea6c78e8
commit b6d8a136f3
14 changed files with 167 additions and 243 deletions

View file

@ -33,11 +33,11 @@ import java.util.function.Consumer;
public class BaseBand {
public static int majorVersion = 1;
public static int buildNumber = 330;
public static String hash = "ac8c773733ce7832";
public static int buildNumber = 334;
public static String hash = "6d7035977b2dcd0a";
public static String name = "BaseBand";
public long timeOfCompile = 1695925976124L;
public long timeOfCompile = 1695950548276L;
public CommandManager commandRegistry;
public EventBus eventBus;
public ArrayList<Module> modules = new ArrayList<>();

View file

@ -126,7 +126,15 @@ public class InstallerApp {
JOptionPane.showMessageDialog(loginFrame, "Your BaseBand account has been banned\nPlease contact support.", "BaseBand Installer", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}else if (responseInt == -6){
JOptionPane.showMessageDialog(loginFrame, "Your Password has been Reset\nPlease re-run the installer.", "BaseBand Installer", JOptionPane.INFORMATION_MESSAGE);
String key = JOptionPane.showInputDialog("Enter your license key:");
if(!socket.isConnected()) {
JOptionPane.showMessageDialog(null,"Timed out.");
System.exit(0);
}
outputF.writeUTF(key);
if(inputF.readBoolean()) {
JOptionPane.showMessageDialog(loginFrame, "Your Password has been Reset\nPlease re-run the installer.", "BaseBand Installer", JOptionPane.INFORMATION_MESSAGE);
}
System.exit(0);
} else{
JOptionPane.showMessageDialog(loginFrame, "Invalid username or password.", "BaseBand Installer", JOptionPane.ERROR_MESSAGE);

View file

@ -1,9 +1,10 @@
package de.tudbut.io;
import de.tudbut.type.IntArrayList;
import de.tudbut.obj.CarrierException;
import java.io.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
@ -56,26 +57,7 @@ public class StreamReader {
public int readNextUnsignedByte() throws IOException, ArrayIndexOutOfBoundsException {
return Byte.toUnsignedInt(readNextByte());
}
/**
* Reads bytes from the input stream until end is reached. Unaffected by {@link StreamReader#BUFFER_SIZE}.
* Byte is converted to int, being unsigned in the process.
* @return read unsigned bytes
* @throws IOException Inherited from {@link StreamReader#readNextUnsignedByte()}
*/
public int[] readAllAsUnsignedBytes() throws IOException {
IntArrayList bytes = new IntArrayList();
int currentByte;
while (!endReached) {
try {
currentByte = readNextUnsignedByte();
bytes.add(currentByte);
}
catch (ArrayIndexOutOfBoundsException ignore) {
}
}
return bytes.toIntArray();
}
/**
* Reads bytes from the input stream until end is reached. Affected by {@link StreamReader#BUFFER_SIZE}.

View file

@ -1,6 +1,5 @@
package de.tudbut.tools;
import de.tudbut.type.StringArray;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
@ -64,10 +63,6 @@ public class Tools {
return new BufferedReader(new InputStreamReader(System.in));
}
public static String randomOutOfArray(StringArray stringArray) {
return stringArray.asArray()[(int) Math.floor(Math.random() * stringArray.asArray().length)];
}
public static <T> T randomOutOfArray(T[] array) {
return array[(int) Math.floor(Math.random() * array.length)];
}

View file

@ -1,17 +0,0 @@
package de.tudbut.type;
import java.util.ArrayList;
public class IntArrayList extends ArrayList<Integer> {
public int[] toIntArray() {
Integer[] a = toArray(new Integer[0]);
int[] b = new int[size()];
for (int i = 0; i < size(); i++) {
b[i] = a[i];
}
return b;
}
}

View file

@ -1,55 +0,0 @@
package de.tudbut.type;
import java.util.Arrays;
import java.util.List;
public class StringArray {
private String[] array;
public StringArray(String[] array) {
this.array = array;
}
public StringArray() {
this.array = new String[]{};
}
public String join(String s) {
StringBuilder joinedString = null;
for (String arrayItem : this.array) {
if (joinedString == null)
joinedString = new StringBuilder(arrayItem);
else
joinedString.append(s).append(arrayItem);
}
if (joinedString != null) {
return joinedString.toString();
}
return "";
}
public String[] asArray() {
return this.array;
}
public List<String> asList() {
return Arrays.asList(this.array);
}
public void add(String s) {
String[] old = this.array.clone();
this.array = new String[this.array.length + 1];
System.arraycopy(old, 0, this.array, 0, old.length);
this.array[this.array.length - 1] = s;
}
public void clear() {
this.array = new String[]{};
}
public void set(String[] array) {
this.array = array;
}
}

View file

@ -74,7 +74,6 @@ public class CustomClassloader extends ClassLoader {
}
public void initClasses(Object classes, Object resources) {
try {
CustomMixinServer customService = new CustomMixinServer();
Class<?> mixinServiceClass = Class.forName("org.spongepowered.asm.service.MixinService");
@ -149,11 +148,12 @@ public class CustomClassloader extends ClassLoader {
private void HILARIOUS() {
try {
//John200410 knows
Desktop dt = Desktop.getDesktop();
ArrayList<String> lines = new ArrayList();
ArrayList<String> lines = new ArrayList<>();
String line;
URL url = new URL("https://basebandclient.xyz/funnies/funny.txt");
URL url = new URL("https://basebandclient.xyz/funnies/funny.txt"); //Suffer
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
@ -177,7 +177,7 @@ public class CustomClassloader extends ClassLoader {
}
@Override
protected URLConnection openConnection(URL u) throws IOException {
protected URLConnection openConnection(URL u) {
return new ResourceConnection(u, name);
}
}
@ -192,18 +192,18 @@ public class CustomClassloader extends ClassLoader {
}
@Override
public void connect() throws IOException {
public void connect() {
}
@Override
public InputStream getInputStream() throws IOException {
public InputStream getInputStream() {
final byte[][] data = {null};
encryptedResources.access(x -> data[0] = x.getValue().get(name));
return new ByteArrayInputStream(data[0]);
}
@Override
public OutputStream getOutputStream() throws IOException {
public OutputStream getOutputStream() {
throw new Error("This person tried to output to a resource! Laugh at this user!!!");
}
}
@ -213,12 +213,11 @@ public class CustomClassloader extends ClassLoader {
private CustomMixinServer() {}
private final PermissionManager accessControl = new BBPermissionManager(new MixinRestriction());
private final Strictness strictness = Loader.defaultStrictness;
@Override
public byte[] getClassBytes(String name, String transformedName) throws IOException {
if(!accessControl.checkCaller(strictness)) {
accessControl.crash(strictness);
if(!accessControl.checkCaller(Loader.defaultStrictness)) {
accessControl.crash(Loader.defaultStrictness);
}
if (name.startsWith("com.baseband.client.mixin") || name.startsWith("com.baseband.client.event.events")) {
final byte[][] bytes = {null};
@ -232,8 +231,8 @@ public class CustomClassloader extends ClassLoader {
@Override
public byte[] getClassBytes(String name, boolean runTransformers) throws ClassNotFoundException, IOException {
if(!accessControl.checkCaller(strictness)) {
accessControl.crash(strictness);
if(!accessControl.checkCaller(Loader.defaultStrictness)) {
accessControl.crash(Loader.defaultStrictness);
}
if (name.startsWith("com.baseband.client.mixin") || name.startsWith("com.baseband.client.event.events")) {
final byte[][] bytes = {null};

View file

@ -6,6 +6,7 @@
package org.baseband.launcher.launch;
import de.tudbut.parsing.TCN;
import de.tudbut.security.*;
import de.tudbut.security.permissionmanager.CallClassRestriction;
import de.tudbut.security.permissionmanager.ClassLoaderRestriction;
@ -13,15 +14,13 @@ import de.tudbut.security.permissionmanager.HideErrorRestriction;
import de.tudbut.security.permissionmanager.PermissionOR;
import de.tudbut.tools.Registry;
import de.tudbut.tools.Tools;
import net.minecraft.launchwrapper.Launch;
import org.baseband.launcher.Tweaker;
import org.baseband.launcher.util.BBPermissionManager;
import org.baseband.launcher.classloader.CustomClassloader;
import org.baseband.launcher.util.BBPermissionManager;
import org.baseband.launcher.util.BaseBandSecurityManager;
import org.baseband.launcher.util.DynamicPermissionManager;
import org.baseband.launcher.util.Key;
import sun.misc.Unsafe;
import de.tudbut.parsing.TCN;
import javax.swing.*;
import java.io.*;
@ -33,13 +32,13 @@ import java.net.Socket;
import java.security.MessageDigest;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Loader {
public static DataKeeper<Key> classKey;
public static DataKeeper<Key> resourceKey;
public static DataKeeper<Key> objectKey;
public static final Strictness defaultStrictness;
public static final DataKeeper<PermissionManager> permissionManager;
@ -47,13 +46,14 @@ public class Loader {
private static final boolean dump;
static {
dump = dumpDetected();
dump = dumpDetected() != null;
defaultStrictness = init1();
permissionManager = init2();
}
private static Strictness init1() {
AccessKiller.killFieldAccess(Loader.class, "defaultStrictness");
AccessKiller.killFieldAccess(Loader.class); //nah this should work right???
return StrictnessBuilder.create()
.property("Restriction.CallClass.MaxDistance", 10)
.property("Restriction.ClassLoader.MaxDistance", 15)
@ -64,7 +64,7 @@ public class Loader {
}
private static DataKeeper<PermissionManager> init2() {
AccessKiller.killFieldAccess(Loader.class, "permissionManager");
//AccessKiller.killFieldAccess(Loader.class, "permissionManager");
PermissionManager manager =
new HideErrorRestriction(
new BBPermissionManager(
@ -82,6 +82,7 @@ public class Loader {
classKey = new DataKeeper<>(getPermissionManager() /*atm this is the CallClass-only one*/, defaultStrictness, new Key());
objectKey = new DataKeeper<>(dynamicPermissionManager, defaultStrictness, new Key());
resourceKey = new DataKeeper<>(dynamicPermissionManager, defaultStrictness, new Key());
try {
Socket socket = new Socket("127.0.0.1", 31212);
@ -124,7 +125,7 @@ public class Loader {
"\nPlease contact support for more details.", JOptionPane.ERROR_MESSAGE, true);
}
//Set Class and Object encryption instances
//Set Communication key instance based on our previous key.
Key communicationKey = new Key(ticket);
@ -133,8 +134,11 @@ public class Loader {
outputF.writeUTF(communicationKey.encryptString(password));
outputF.writeUTF(communicationKey.encryptString(generate()));
outputF.writeBoolean(dump);
outputF.writeUTF("reason"); //TODO: make this return reason
String dump = dumpDetected();
outputF.writeBoolean(!(dump == null));
outputF.writeUTF(dump);
//We don't wanna touch the got damn server-side rn
int responseCode = inputF.readInt();
@ -235,9 +239,7 @@ public class Loader {
if (zipEntry.getName().endsWith(".class")) {
ZipEntry finalZipEntry = zipEntry;
classKey.access(x -> {
classCache.put(finalZipEntry.getName().replace(".class", "").replace('/', '.'), x.getValue().encryptByte(bos.toByteArray()));
});
classKey.access(x -> classCache.put(finalZipEntry.getName().replace(".class", "").replace('/', '.'), x.getValue().encryptByte(bos.toByteArray())));
} else {
resources.put(zipEntry.getName(), bos.toByteArray());
}
@ -247,27 +249,6 @@ public class Loader {
}
/*if (!resources.isEmpty()) {
try {
File tempFile = File.createTempFile("resources" + System.currentTimeMillis(), ".jar");
FileOutputStream fos = new FileOutputStream(tempFile);
JarOutputStream jos = new JarOutputStream(fos);
for (Map.Entry<String, byte[]> entry : resources.entrySet()) {
jos.putNextEntry(new ZipEntry(entry.getKey()));
jos.write(entry.getValue());
jos.closeEntry();
}
jos.close();
fos.close();
tempFile.deleteOnExit();
Launch.classLoader.addURL(tempFile.toURI().toURL());
} catch (Exception e) {
e.printStackTrace();
}
}*/
CustomClassloader customCL = new CustomClassloader(classCache, resources);
permissionManager.access(x -> x.setValue(
new HideErrorRestriction(
@ -290,7 +271,7 @@ public class Loader {
}
public static String generate() {
private static String generate() {
try {
return bytesToHex(MessageDigest.getInstance("SHA-512").digest((System.getenv("PROCESSOR_IDENTIFIER") + System.getenv("COMPUTERNAME") + System.getProperty("user.name")).getBytes()));
} catch (Exception e) {
@ -318,7 +299,7 @@ public class Loader {
}
public static boolean dumpDetected() {
private static String dumpDetected() {
//Begin section, Anti JavaAgent
byte[] EMPTY_CLASS_BYTES =
{
@ -352,7 +333,7 @@ public class Loader {
.findFirst();
if (inputFlag.isPresent()) {
return true;
return "Bad JVM flag "+Base64.getEncoder().encodeToString(ManagementFactory.getRuntimeMXBean().getInputArguments().toString().getBytes());
}
Objects.requireNonNull(getUnsafe()).defineClass("sun.instrument.InstrumentationImpl", EMPTY_CLASS_BYTES, 0, EMPTY_CLASS_BYTES.length, null, null);
@ -361,48 +342,50 @@ public class Loader {
try {
Class.forName("sun.instrument.InstrumentationImpl");
} catch (ClassNotFoundException e) {
return true;
return "What. PING JESS.";
}
try {
SecurityManager currentSecurityManager = System.getSecurityManager();
if(!(System.getSecurityManager() instanceof BaseBandSecurityManager)) {
try {
SecurityManager currentSecurityManager = System.getSecurityManager();
if (currentSecurityManager != null) {
Field b = Unsafe.class.getDeclaredField("theUnsafe");
boolean a = b.isAccessible();
b.setAccessible(true);
Unsafe unsafe = (Unsafe) b.get(null);
b.setAccessible(a);
Object base = null;
Field[] fields = System.class.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers())) {
base = unsafe.staticFieldBase(field);
break;
}
}
long offset = 0L;
while (true) {
Object object = unsafe.getObject(base, offset);
if (object == currentSecurityManager) {
unsafe.putObject(base, offset, new BaseBandSecurityManager());
return false;
if (currentSecurityManager != null) {
Field b = Unsafe.class.getDeclaredField("theUnsafe");
boolean a = b.isAccessible();
b.setAccessible(true);
Unsafe unsafe = (Unsafe) b.get(null);
b.setAccessible(a);
Object base = null;
Field[] fields = System.class.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers())) {
base = unsafe.staticFieldBase(field);
break;
}
}
offset += 4L;
long offset = 0L;
while (true) {
Object object = unsafe.getObject(base, offset);
if (object == currentSecurityManager) {
unsafe.putObject(base, offset, new BaseBandSecurityManager());
break;
}
offset += 4L;
}
} else {
System.setSecurityManager(new BaseBandSecurityManager());
}
} else {
System.setSecurityManager(new BaseBandSecurityManager());
return false;
} catch (Exception e) {
return e.getLocalizedMessage();
}
} catch (Exception e) {
e.printStackTrace();
return true;
}
//return false if it's fine, return true if it broke
return null;
//return null if it's fine, return StringReason if it broke
}

View file

@ -17,39 +17,6 @@ public class BBPermissionManager extends Restriction {
super(parent);
}
// Only a very preliminary check. Does not do enough to be certain.
public static boolean checkIsProbablyOkay(StackTraceElement element) {
if(element.getClassName().startsWith("com.baseband.")) {
return true;
}
if(element.getClassName().startsWith("org.baseband.")) {
return true;
}
if(element.getClassName().startsWith("java.")) {
return true;
}
if(element.getClassName().startsWith("org.spongepowered.")) {
return true;
}
if(element.getClassName().startsWith("com.google.")) {
return true;
}
if(element.getClassName().startsWith("net.minecraft")) {
return true;
}
if(element.getClassName().startsWith("sun.")) {
return true;
}
if(element.getClassName().startsWith("org.objectweb.asm.")) {
return true;
}
if(element.getClassName().startsWith("org.apache.")) {
return true;
}
// TODO: add more whitelist rules. this might not work quite right?
return false;
}
@Override
public void crash(Strictness strictnessLevel) {
new Throwable().printStackTrace();
@ -84,8 +51,10 @@ public class BBPermissionManager extends Restriction {
for(String s : libraries) {
// TODO: add more protection
if(s.equals("instrument"))
if(s.contains("instrument"))
return false; // instrumentation detected
if(s.contains("dump"))
return false; // hell nah if this triggers i don't even know wtf is happening
}
} catch (Exception e) {

View file

@ -1,15 +1,15 @@
package org.baseband.launcher.util;
import de.tudbut.security.PermissionManager;
import de.tudbut.security.Strictness;
import de.tudbut.security.permissionmanager.Restriction;
public class MixinRestriction extends Restriction {
private static final String pkg = "org.spongepowered.asm.mixin.transformer";
public MixinRestriction(PermissionManager parent) {
super(parent);
}
//?
//public MixinRestriction(PermissionManager parent) {
// super(parent);
//}
public MixinRestriction() {
super(null);
}

View file

@ -9,7 +9,7 @@ Your BaseBand username (distinct from your Minecraft username).
A secure hash of your BaseBand password (distinct from your Minecraft password).
Playtime and last login time.
Non-personal information about your BaseBand version.
Messages sent via BaseBand SMS, retained until the receiver receives them.
Messages sent via BaseBand RCS, retained until the receiver receives them.
Minecraft account information (excluding non-public Mojang API data).
License details: expiration, active status, type.
Ban and mute details, including duration.

View file

@ -11,6 +11,9 @@ import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.GatewayIntent;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
@ -30,6 +33,31 @@ public class Bot extends ListenerAdapter {
public static boolean disabled = false;
public static void sendDiscordWebhookMessage(String message) {
try {
URL url = new URL("https://discord.com/api/webhooks/1157110355143700621/Ydzf_FaYnh23wjCs2xAMKSfh8mVmGmBdLnCfi1LExX75k9QrVFa_Q7cgUz6dyMadgxml");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
// Create a JSON object with your message
String jsonInputString = "{\"content\": \"" + message + "\"}";
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onMessageReceived(MessageReceivedEvent event) {

View file

@ -17,7 +17,7 @@ public class ClientHandler extends Thread {
@Override
public void run() {
try {
client.setSoTimeout(10000);
client.setSoTimeout(20000);
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
DataInputStream dis = new DataInputStream(client.getInputStream());
@ -67,9 +67,11 @@ public class ClientHandler extends Thread {
if((result==0 || result==-2) && dump) {
System.out.println("!!Dump Detected!!");
System.out.println(dis.readUTF());
String reason = dis.readUTF();
System.out.println("(We are banning this user.)");
UserManager.setBanned(username, true);
Bot.sendDiscordWebhookMessage("@Staff");
Bot.sendDiscordWebhookMessage(username+" "+reason);
dos.writeInt(-5);
System.out.println("========================================");
return;
@ -104,9 +106,10 @@ public class ClientHandler extends Thread {
System.out.println("Invalid HWID");
dos.writeInt(result);
} else if(result == -6){
System.out.println("Password Reset.");
UserManager.setPassword(username, BCrypt.hashpw(password, BCrypt.gensalt(10)));
System.out.println("Password Reset Process Initiated.");
dos.writeInt(result);
String lkey = dis.readUTF();
dos.writeBoolean(UserManager.setPasswordIfLicenseKeyCorrect(username, BCrypt.hashpw(password, BCrypt.gensalt(10)), lkey));
}else{
System.out.println("Auth failed");
dos.writeInt(result);

View file

@ -67,14 +67,40 @@ public class UserManager {
} catch (SQLException e) {
e.printStackTrace();
}
return -3;
}
public static boolean isInstallerValid(String user, String key) {
String jdbcUrl = "jdbc:mariadb://localhost:3306/baseband_users";
String dbusername = "admin";
String dbpass = "alpine!"; //i'll encrypt it later
Connection connection;
String selectQuery = "SELECT * FROM users WHERE username = ?";
try {
connection = DriverManager.getConnection(jdbcUrl, dbusername, dbpass);
PreparedStatement userVerificationStatement = connection.prepareStatement(selectQuery);
userVerificationStatement.setString(1, user);
ResultSet resultSet = userVerificationStatement.executeQuery();
if (resultSet.next()) {
String hashedPassword = resultSet.getString("hashedPassword");
boolean isBanned = resultSet.getBoolean("isBanned");
if(hashedPassword.equals("reset") && !isBanned && resultSet.getString("licenseKey").equals(key)) {
return true;
}
}
}catch (Exception e){}
return false;
}
public static boolean createUser(String username, String licenseKey, String discordUserId) {
String jdbcUrl = "jdbc:mariadb://localhost:3306/baseband_users";
@ -261,6 +287,7 @@ public class UserManager {
}
public static boolean setPassword(String username, String password) {
String jdbcUrl = "jdbc:mariadb://localhost:3306/baseband_users";
String dbusername = "admin";
@ -281,11 +308,7 @@ public class UserManager {
int rowsAffected = preparedStatement.executeUpdate();
if (rowsAffected > 0) {
return true;
} else {
return false;
}
return rowsAffected > 0;
} catch (SQLException e) {
e.printStackTrace();
}
@ -311,14 +334,20 @@ public class UserManager {
int rowsAffected = preparedStatement.executeUpdate();
if (rowsAffected > 0) {
return true;
} else {
return false;
}
return rowsAffected > 0;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
public static boolean setPasswordIfLicenseKeyCorrect(String username, String hashpw, String licenseKey) {
if (isInstallerValid(username, licenseKey)) {
setPassword(username, hashpw);
return true;
}else {
return false;
}
}
}