Vaccine will do a deeper jar scan, looking for suspicious class loading.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,5 @@
|
|||||||
rootProject.name = 'Sentinel'
|
plugins {
|
||||||
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = 'Sentinel'
|
||||||
|
|||||||
@@ -18,18 +18,9 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public class NBTStorage implements JsonSerializable<NBTStorage> {
|
public class NBTStorage implements JsonSerializable<NBTStorage> {
|
||||||
|
|
||||||
// Mapping from file name to owner UUID (as a String)
|
|
||||||
public Map<String, String> caughtItems = new HashMap<>();
|
public Map<String, String> caughtItems = new HashMap<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores an ItemStack's serialized NBT to a unique file
|
|
||||||
* and maps the generated file name to the owner UUID.
|
|
||||||
*
|
|
||||||
* @param item the ItemStack to store
|
|
||||||
* @param owner the owner's UUID
|
|
||||||
*/
|
|
||||||
public void storeItem(ItemStack item, UUID owner) {
|
public void storeItem(ItemStack item, UUID owner) {
|
||||||
// Generate a unique file name with a .nbt extension
|
|
||||||
File storageDir = new File(Sentinel.getInstance().getDirector().io.getDataFolder(), "storage/nbt");
|
File storageDir = new File(Sentinel.getInstance().getDirector().io.getDataFolder(), "storage/nbt");
|
||||||
String fileName = UUID.randomUUID().toString() + ".nbt";
|
String fileName = UUID.randomUUID().toString() + ".nbt";
|
||||||
File file = new File(storageDir, fileName);
|
File file = new File(storageDir, fileName);
|
||||||
@@ -41,7 +32,6 @@ public class NBTStorage implements JsonSerializable<NBTStorage> {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
// Add mapping: file name -> owner UUID (as string)
|
|
||||||
caughtItems.put(fileName, owner.toString());
|
caughtItems.put(fileName, owner.toString());
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
@@ -63,7 +53,7 @@ public class NBTStorage implements JsonSerializable<NBTStorage> {
|
|||||||
while ((content = fis.read()) != -1) {
|
while ((content = fis.read()) != -1) {
|
||||||
b64.append((char) content);
|
b64.append((char) content);
|
||||||
}
|
}
|
||||||
//ServerUtils.verbose("Getting item with fis: " + b64);
|
|
||||||
return deserializeItem(b64.toString());
|
return deserializeItem(b64.toString());
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Sentinel.getInstance().getDirector().io.nbtStorage.caughtItems.remove(fileName);
|
Sentinel.getInstance().getDirector().io.nbtStorage.caughtItems.remove(fileName);
|
||||||
@@ -86,15 +76,12 @@ public class NBTStorage implements JsonSerializable<NBTStorage> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// Serialize ItemStack to a Map
|
|
||||||
Map<String, Object> serializedItem = item.serialize();
|
Map<String, Object> serializedItem = item.serialize();
|
||||||
|
|
||||||
// Save the Map into a YAML configuration
|
|
||||||
YamlConfiguration config = new YamlConfiguration();
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
config.set("item", serializedItem);
|
config.set("item", serializedItem);
|
||||||
String yamlString = config.saveToString();
|
String yamlString = config.saveToString();
|
||||||
|
|
||||||
// Encode YAML string to Base64
|
|
||||||
return Base64.getEncoder().encodeToString(yamlString.getBytes(StandardCharsets.UTF_8));
|
return Base64.getEncoder().encodeToString(yamlString.getBytes(StandardCharsets.UTF_8));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -107,24 +94,19 @@ public class NBTStorage implements JsonSerializable<NBTStorage> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// Decode Base64 to YAML string
|
|
||||||
byte[] decodedData = Base64.getDecoder().decode(data);
|
byte[] decodedData = Base64.getDecoder().decode(data);
|
||||||
String yamlString = new String(decodedData, StandardCharsets.UTF_8);
|
String yamlString = new String(decodedData, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
// Load YAML configuration from string
|
|
||||||
YamlConfiguration config = new YamlConfiguration();
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
config.loadFromString(yamlString);
|
config.loadFromString(yamlString);
|
||||||
|
|
||||||
// Extract the serialized Map from the configuration
|
|
||||||
ConfigurationSection itemSection = config.getConfigurationSection("item");
|
ConfigurationSection itemSection = config.getConfigurationSection("item");
|
||||||
if (itemSection == null) {
|
if (itemSection == null) {
|
||||||
return null; // Invalid data
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert ConfigurationSection to a nested Map
|
|
||||||
Map<String, Object> serializedItem = itemSection.getValues(true);
|
Map<String, Object> serializedItem = itemSection.getValues(true);
|
||||||
|
|
||||||
// Deserialize the Map back into an ItemStack
|
|
||||||
return ItemStack.deserialize(serializedItem);
|
return ItemStack.deserialize(serializedItem);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package me.trouper.sentinel.server.events.violations.players;
|
||||||
|
|
||||||
|
public class EthanolPacket {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -69,4 +69,10 @@ public final class BackdoorDetection {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ethanolCheck() {
|
||||||
|
if (System.getProperty("ethanol.running") != null) {
|
||||||
|
Sentinel.getInstance().getLogger().severe("Detected Ethanol running on your server! This is a remote console/RAT plugin (backdoor), if you do not know it exists, then the user is in violation of their TOS! Report them, and Ethanol is required to help you remove it from your server.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package me.trouper.sentinel.startup;
|
||||||
|
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
|
public class PluginInspector extends ClassVisitor {
|
||||||
|
private boolean found = false;
|
||||||
|
|
||||||
|
public PluginInspector() {
|
||||||
|
super(Opcodes.ASM9);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||||
|
if ("java/net/URLClassLoader".equals(superName)) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
super.visit(version, access, name, signature, superName, interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitLdcInsn(Object value) {
|
||||||
|
if (value instanceof String && ((String) value).contains("java.net.URLClassLoader")) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
super.visitLdcInsn(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFound() {
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,13 +66,4 @@ public final class FileUtils {
|
|||||||
|
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deleteDirectory(File file) {
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
for (File child : file.listFiles()) {
|
|
||||||
deleteDirectory(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return file.delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user