The Solar (s0lar.net) Minecraft Plugin Malware: How It Works, Detection and Cleanup
Analysis of malware that spreads through Paper/Spigot plugin files and turns servers into bots. How it works, how to check a server, and how to clean it.

In October 2026, one of our servers, Realms, turned out to carry malware inside its plugin files. The explanation for players is in our Realms incident notice. This post is for fellow Minecraft server owners and developers: how the malware works, how to check your server, and how to clean it.
Other networks have reported the same malware, including in MCAntiMalware issue #778, Plattio's write-up (five affected networks in Germany), and crashdemons' analysis. Our contribution is the dynamic analysis: we ran it on an isolated machine and recorded what it actually sends to the attacker's server.
In Short
- A small loader is inserted into one class of a plugin file that keeps working normally. The file date does not change.
- When the plugin loads, the loader downloads an encrypted second plugin from
s0lar.net, decrypts it, and loads it withPluginManager.loadPlugin(). It never appears in theplugins/folder. - The second plugin (named "DataFixerUpper") registers the server as a bot, uploads every plugin file and the server jar to the attacker to infect them, steals the DiscordSRV bot token, uploads
latest.log, and waits for commands. - A copy of the payload is saved in
logs/under a name that looks like a normal log plus an invisible U+200B character.

Two Loader Versions
Our server had both at once. Our first cleanup only caught the first one, so check for both.
| Hex version | Base64 version | |
|---|---|---|
| Hidden strings | XOR-ed hex text (564A4A4E4D041111 = https://) |
Base64 in the constant pool (czBsYXIubmV0 = s0lar.net) |
| Injected code | Extra method (e.g. setupServerIntegration) |
Hidden int getSemanticsId() or getTelemetryId() method (bridge + synthetic flags) and an int field |
| Call site | Inside an existing method | 9-byte prologue at the start of one method: aload_0; invokevirtual getSemanticsId; aload_0; swap; putfield |
| Server jar | Not seen | patchLibs() in io/papermc/paperclip/Main.class, called first in main() |
| On our server | 55 plugin files | 52 plugin files (including .bak copies) and server.jar |
The Base64 version had been on our server since at least 30 May 2026.
What Gets Sent to the Attacker
We ran the infected plugin on a rented, single-use VPS, behind a firewall that only allowed connections to s0lar.net through a recording proxy, with bait files (a fake Discord token, a fake database password). All traffic except the jar uploads is Base64 of a 16-byte IV plus AES-256-CBC ciphertext, and the replies are disguised as nginx "404 Not Found" pages with the data in an HTML comment <!-- B: ... -->.
| Request | Content (decrypted) |
|---|---|
GET /routes/0/d.php |
Download the second plugin |
POST /routes/0/a.php |
Registration: port, OS, host plugin name, MOTD |
POST /routes/0/b.php |
Server info: hostname, port, world, plugin list, online players |
POST /routes/0/e.php |
Upload a jar (plugins and paper.jar) to be infected, then fetch the result |
POST /routes/0/v.php |
DiscordSRV bot token and the OS user name |
POST /routes/0/s.php |
The latest.log file |
POST /a |
Wait for commands (long poll, about 100 seconds) |
Before contacting the attacker, the second plugin checks internet access via cloudflare.com, google.com, bstats.org and github.com. If that fails, it stays quiet.
According to crashdemons' analysis, the second plugin also has hidden commands through chat and books that can run console commands for accounts the attacker's server authorises. The bot settings the attacker's server sent us contained one Minecraft account UUID: d7b77c65-23fe-4159-b73c-50fc3d2c293d. The malware also looks up the UUID e19212b9-53d8-44cd-8eac-41c85f8b0e28. Either may be a stolen account, so consider banning both UUIDs.
One warning from another report: without the correct a: header, the attacker's server sends a different, destructive payload (it wipes the server). Do not try to download the payload from a production server.
How to Check Your Server

Run in the server folder (Linux):
# 1. Payload copy: any file whose name ends in the invisible U+200B character
find . -name "*$(printf '\342\200\213')" -ls
# 2. Infected jars (both versions), including server.jar and .bak / .disabled / -jar copies
P='564A4A4E4D041111|czBsYXIubmV0|aHR0cHM6Ly9zMGxhci5uZXQ|bmV0LnMwbGFyLlNvbGFyTG9hZGVy'
find . \( -name '*.jar*' -o -name '*-jar' \) -type f -print0 | while IFS= read -r -d '' j; do
unzip -p "$j" 2>/dev/null | grep -a -q -E "$P" && echo "INFECTED: $j"
done
The second command found all 107 infected files we tested from our server and 0 of 1,073 clean files on our other servers. Run it without a file pattern as shown: some unzip builds do not match '*.class' inside folders and then miss most infected files. Do not add the method name getSemanticsId to this quick check, because legitimate plugins (for example DriveBackupV2 and Geyser) use the same name.
On a running server, a plugin named DataFixerUpper in /plugins is also a strong sign.
How to Clean Up
- Stop the server. The bot can re-infect files while it runs.
- Block outbound connections to
s0lar.netand198.167.197.169if your host allows it. - Replace every jar, including
server.jarand anything inlibraries/,cache/andversions/, with official copies. Also move.bakand.disabledcopies out of the server folder. Do not reuse jars from the infected server or its backups without checking them with the command above. - Delete the
logs/*.log.gz+ U+200B file after keeping a copy as evidence. - Change every secret the server could read: Discord bot tokens, database passwords, the RCON password, BungeeGuard tokens / forwarding secrets, panel API keys and git tokens.
- Check operators and permissions (
ops.json, LuckPerms) for accounts you do not recognise. - Check other servers that share files or staff with the infected one, and check developer machines: we found copies of infected jars in local project folders, including in a git repo. The second plugin also carries code for opening Windows-encrypted data (DPAPI), which is commonly used to steal browser passwords and cookies, so do not run suspicious jars on a Windows PC.
For paid plugins without a clean copy, the Base64-version injection can be removed exactly: delete the hidden method, its field and the 9-byte prologue. On 28 jars that had official copies, the result of this cleanup was identical to the official jar (same methods and instructions).
Indicators of Compromise (IoC)
| Type | Value |
|---|---|
| Domain | s0lar.net (registered 27 June 2025) |
| IP | 198.167.197.169 |
| Paths | /routes/0/{a,b,d,e,s,v}.php, /a |
| Files | logs/<date>-<n>.log.gz + U+200B, short-lived /tmp/<digits>.jar |
| Hidden plugin | DataFixerUpper, main com.mojang.datafixers.util.impl.EntityBrainFixer |
| Jar markers | 564A4A4E4D041111, czBsYXIubmV0, aHR0cHM6Ly9zMGxhci5uZXQ, bmV0LnMwbGFyLlNvbGFyTG9hZGVy, cC5Bc3luY1RpbWluZ3M |
| Second plugin SHA-256 | 3bd14a1dece3fd17c867b49c135282d304703ff1f19558abe7cba97c22023058 |
| Minecraft UUIDs | d7b77c65-23fe-4159-b73c-50fc3d2c293d, e19212b9-53d8-44cd-8eac-41c85f8b0e28 |
We reported the attacker's domain, server and DNS to their providers on 17 October 2026.
Closing
If your server turns out to be infected, you are not alone, and it does not mean you were careless: this malware is built so that plugins keep working and file dates do not change. Our full technical report can be requested at [email protected]. If you find another version, let us or the community know in the public reports above.
Summary
| Aspect | Detail |
|---|---|
| What | A loader in plugin files that loads a hidden bot plugin from s0lar.net |
| Affects | Paper, Spigot, Purpur and Folia servers |
| Steals | The DiscordSRV bot token, latest.log, every jar file (to infect it) |
| Main signs | logs/*.log.gz + U+200B file, DataFixerUpper plugin, Base64/hex markers in jars |
| Cleanup | Stop the server, replace every jar including server.jar, delete the payload copy, change every secret |
About the Author
Sen
Founder, Owner, and Developer
Kaizen Network Contributor