Skip to content

Commit

Permalink
Project source code upload
Browse files Browse the repository at this point in the history
  • Loading branch information
SoKnight committed Dec 10, 2021
1 parent 64efc0c commit 451faf8
Show file tree
Hide file tree
Showing 7 changed files with 345 additions and 0 deletions.
40 changes: 40 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Intellij IDEA
.idea/
*.iml
out/

# Compiled class files
*.class

# Logs
*.log

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

*~

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# Maven
target/
.mvn/

# Common working directory
run/
128 changes: 128 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>ru.easydonate</groupId>
<artifactId>exploitfix</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<name>EasyExploitFix</name>
<description>Easy way to fix the Log4j2 exploit for unsupported server software</description>

<properties>
<!-- Building -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>

<!-- Dependencies -->
<spigot.api.version>1.13-R0.1-SNAPSHOT</spigot.api.version>
<protocollib.version>4.8.0-SNAPSHOT</protocollib.version>
<log4j.core.version>2.14.1</log4j.core.version>
<lombok.version>1.18.22</lombok.version>

<!-- Maven plugins -->
<maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>
<maven.shade.plugin.version>3.2.4</maven.shade.plugin.version>
</properties>

<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>dmulloy2-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url>
</repository>
</repositories>

<dependencies>
<!-- Spigot API -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>${spigot.api.version}</version>
<scope>provided</scope>
</dependency>

<!-- ProtocolLib -->
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>${protocollib.version}</version>
<scope>provided</scope>
</dependency>

<!-- Log4j Core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.core.version}</version>
<scope>provided</scope>
</dependency>

<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<finalName>${project.name}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<!-- Maven compiler plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<!-- Maven shade plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven.shade.plugin.version}</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/maven/</exclude>
<exclude>META-INF/*.MF</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
27 changes: 27 additions & 0 deletions src/main/java/ru/easydonate/exploitfix/ExploitFixPlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ru.easydonate.exploitfix;

import org.bukkit.plugin.java.JavaPlugin;
import ru.easydonate.exploitfix.listener.ProtocolChatPacketListener;
import ru.easydonate.exploitfix.patcher.LoggerPatcher;

import java.util.regex.Pattern;

public final class ExploitFixPlugin extends JavaPlugin {

private static final Pattern DETECTOR_PATTERN = Pattern.compile("\\{*jndi:.*}");

@Override
public void onLoad() {
boolean hasPatched = new LoggerPatcher(this, DETECTOR_PATTERN).patch();
if(!hasPatched)
getServer().getPluginManager().disablePlugin(this);
}

@Override
public void onEnable() {
new ProtocolChatPacketListener(this, DETECTOR_PATTERN);

getLogger().info("Exploit protection has been enabled!");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package ru.easydonate.exploitfix.listener;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class ProtocolChatPacketListener extends PacketAdapter {

private final Pattern detectorPattern;

public ProtocolChatPacketListener(Plugin plugin, Pattern detectorPattern) {
super(plugin, ListenerPriority.LOWEST,
PacketType.Play.Client.CHAT,
PacketType.Play.Server.CHAT
);
this.detectorPattern = detectorPattern;

ProtocolLibrary.getProtocolManager().addPacketListener(this);
}

@Override
public void onPacketSending(PacketEvent event) {
if(event.getPacketType() != PacketType.Play.Server.CHAT)
return;

PacketContainer packet = event.getPacket();
WrappedChatComponent chatComponent = packet.getChatComponents().readSafely(0);
if(chatComponent == null)
return;

String componentJson = chatComponent.getJson();
BaseComponent[] componentsArray = ComponentSerializer.parse(componentJson);
String message = TextComponent.toPlainText(componentsArray);

Matcher matcher = detectorPattern.matcher(message.toLowerCase());
if(matcher.find()) {
event.setCancelled(true);
packet.getChatComponents().write(0, WrappedChatComponent.fromText(""));
}
}

@Override
public void onPacketReceiving(PacketEvent event) {
if(event.getPacketType() != PacketType.Play.Client.CHAT)
return;

PacketContainer packet = event.getPacket();
String message = packet.getStrings().read(0);

Matcher matcher = detectorPattern.matcher(message.toLowerCase());
if(matcher.find()) {
Player player = event.getPlayer();
getPlugin().getLogger().warning(player.getName() + " tried to use the Log4j2 exploit!");

event.setCancelled(true);
packet.getStrings().write(0, "");
}
}

}
23 changes: 23 additions & 0 deletions src/main/java/ru/easydonate/exploitfix/patcher/LoggerFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ru.easydonate.exploitfix.patcher;

import lombok.AllArgsConstructor;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.filter.AbstractFilter;

import java.util.regex.Pattern;

@AllArgsConstructor
public final class LoggerFilter extends AbstractFilter {

private final Pattern detectorPattern;

@Override
public Result filter(LogEvent event) {
String message = event.getMessage().getFormattedMessage();
if(message.contains("$") && detectorPattern.matcher(message.toLowerCase()).find())
return Result.DENY;

return super.filter(event);
}

}
47 changes: 47 additions & 0 deletions src/main/java/ru/easydonate/exploitfix/patcher/LoggerPatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package ru.easydonate.exploitfix.patcher;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.filter.AbstractFilterable;
import org.bukkit.plugin.Plugin;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public final class LoggerPatcher {

private final Plugin plugin;
private final LoggerFilter loggerFilter;

public LoggerPatcher(Plugin plugin, Pattern detectorPattern) {
this.plugin = plugin;
this.loggerFilter = new LoggerFilter(detectorPattern);
}

public boolean patch() {
try {
List<String> processedAppenders = patchAvailableLoggers();
plugin.getLogger().info("Logger filter has been applied for appenders: " + String.join(", ", processedAppenders));
return true;
} catch (Throwable throwable) {
plugin.getLogger().severe("Couldn't add filters to some logger(s).");
plugin.getLogger().severe("Logger version is probably incompatible!");
plugin.getLogger().severe("Details: " + throwable.getMessage());
return false;
}
}

private List<String> patchAvailableLoggers() {
Map<String, Appender> appenders = ((Logger) LogManager.getRootLogger()).getAppenders();

return appenders.values().stream()
.filter((appender -> appender instanceof AbstractFilterable))
.peek(appender -> ((AbstractFilterable) appender).addFilter(loggerFilter))
.map(Appender::getName)
.collect(Collectors.toList());
}

}
8 changes: 8 additions & 0 deletions src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: ${project.name}
main: ru.easydonate.exploitfix.ExploitFixPlugin
version: ${project.version}
author: SoKnight
load: STARTUP
depend: [ProtocolLib]
description: ${project.description}
api-version: 1.13

0 comments on commit 451faf8

Please sign in to comment.