Skip to content

Commit

Permalink
Merge pull request #69 from OpticFusion1/update
Browse files Browse the repository at this point in the history
Changes
  • Loading branch information
OpticFusion1 authored Apr 16, 2019
2 parents ec3951a + 6374ae6 commit c274458
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 50 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>optic_fusion1</groupId>
<artifactId>MCAntiMalware</artifactId>
<version>3.29</version>
<version>3.31</version>
<packaging>jar</packaging>
<build>
<plugins>
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/optic_fusion1/mcantimalware/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,32 @@
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import jline.console.ConsoleReader;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import optic_fusion1.mcantimalware.check.CheckManager;
import optic_fusion1.mcantimalware.check.CheckRegistery;
import optic_fusion1.mcantimalware.configuration.file.FileConfiguration;
import optic_fusion1.mcantimalware.configuration.file.YamlConfiguration;
import optic_fusion1.mcantimalware.logging.ConsoleLogManager;
import optic_fusion1.mcantimalware.logging.CustomLogger;
import optic_fusion1.mcantimalware.logging.LoggerOutputStream;
import optic_fusion1.mcantimalware.utils.ZipUtils;
import org.apache.commons.io.IOUtils;

public class Main implements Runnable {

Expand All @@ -36,6 +44,7 @@ public class Main implements Runnable {
private String[] args;
private static CustomLogger logger = CustomLogger.getLogger(Main.class);
private ConsoleReader reader;
private FileConfiguration checksumDatabase;

private void init() {
AntiMalware.setMain(this);
Expand Down Expand Up @@ -63,6 +72,9 @@ private void init() {
logger.exception(ex.toString());
}
}
downloadChecksumDatabase();
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleWithFixedDelay(this::downloadChecksumDatabase, 1, 4, TimeUnit.HOURS);
checkManager = new CheckManager(this);
new CheckRegistery(this).registerChecks();
OptionParser parser = new OptionParser() {
Expand Down Expand Up @@ -183,10 +195,30 @@ public File getScanDirectory() {
return scanDirectory;
}

public FileConfiguration getChecksumDatabase() {
return checksumDatabase;
}

public static void main(String[] args) {
Main main = new Main();
main.args = args;
new Thread(main).start();
}

private void downloadChecksumDatabase() {
try {
if (shouldLogDebugMessages()) {
logger.debug("DATABASE");
logger.debug(IOUtils.toString(new URL("https://raw.githubusercontent.com/OpticFusion1/MCAntiMalwareChecksumList/master/checksums.yml"), "UTF-8"));
}
logger.info("Gathering checksum database");
checksumDatabase = YamlConfiguration.loadConfiguration(IOUtils.toInputStream(IOUtils.toString(new URL("https://raw.githubusercontent.com/OpticFusion1/MCAntiMalwareChecksumList/master/checksums.yml"), "UTF-8"), "UTF-8"));
logger.info("Finished gathering checksum database");
} catch (MalformedURLException ex) {
logger.exception(ex);
} catch (IOException ex) {
logger.exception(ex);
}
}

}
136 changes: 87 additions & 49 deletions src/main/java/optic_fusion1/mcantimalware/check/CheckManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,36 @@
import java.awt.TrayIcon.MessageType;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipFile;
import optic_fusion1.mcantimalware.Main;
import optic_fusion1.mcantimalware.configuration.file.FileConfiguration;
import optic_fusion1.mcantimalware.configuration.file.YamlConfiguration;
import optic_fusion1.mcantimalware.logging.CustomLogger;
import org.apache.commons.codec.digest.DigestUtils;

public class CheckManager {

private List<Check> checks = new ArrayList<>();
private Main main;
private CustomLogger logger;
private FileConfiguration checksumDatabase;

public CheckManager(Main main) {
this.main = main;
this.logger = main.getLogger();
checksumDatabase = main.getChecksumDatabase();
}

public void reloadChecksumDatabase(){
checksumDatabase = main.getChecksumDatabase();
}

public List<Check> getChecks() {
return checks;
}
Expand All @@ -45,59 +58,79 @@ public void addCheck(Check check) {
checks.add(check);
}

public boolean processWithCheck(String checkName, String name, File file) {
logger.info("Checking to see if " + name + " is infected");
ZipFile zipFile = null;
try {
zipFile = new ZipFile(file);
} catch (IOException ex) {
logger.warning(ex.getMessage());
public boolean isInChecksumDatabase(File file) throws IOException {
JarFile jarFile = new JarFile(file);
JarEntry jarEntry = jarFile.getJarEntry("plugin.yml");
InputStream inputStream = jarFile.getInputStream(jarEntry);
FileConfiguration config = YamlConfiguration.loadConfiguration(inputStream);
if (!config.isSet("author") && !config.isSet("name")) {
if (main.shouldLogDebugMessages()) {
logger.debug("author & name config sections AREN'T set");
}
return false;
}
inputStream.close();
jarEntry = null;
jarFile.close();
String author = "";
String name = "";
if (config.isSet("author")) {
if (main.shouldLogDebugMessages()) {
logger.debug("Author: " + config.getString("author"));
}
author = config.getString("author");
}
if (config.isSet("name")) {
if (main.shouldLogDebugMessages()) {
logger.debug("Plugin Name: " + config.getString("name"));
}
name = config.getString("name");
}
if (zipFile == null) {
if (name.isEmpty()) {
return false;
}
for (Check check : checks) {
if (check.getName().equalsIgnoreCase(checkName)) {
logger.info(
"Checking if " + name + " is infected with " + check.getName() + "(" + check.getType() + ")");
if (check.process(name, zipFile)) {
String fullCheckName = check.getFileName().isEmpty() ? "" : " (" + check.getFileName() + ")";
String fullFileName = name + fullCheckName;
logger.malicious(
fullFileName + " MIGHT be infected with " + check.getName() + "(" + check.getType() + ") Class Path: " + check.getClassNodePath());
if (SystemTray.isSupported()) {
logger.malicious("SUPPORTED");
SystemTray tray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().createImage(Main.class.getResource("/index.jpg"));
TrayIcon trayIcon = new TrayIcon(image, "Malware Detected");
trayIcon.setImageAutoSize(true);
trayIcon.setToolTip(fullFileName + " MIGHT be infected");
try {
tray.add(trayIcon);
trayIcon.displayMessage("Malware Detected", fullFileName + " MIGHT be infected with " + check.getName() + "(" + check.getType() + ") Class Path: " + check.getClassNodePath(), MessageType.WARNING);
} catch (Exception ex) {
logger.malicious("ERROR", ex);
}
} else {
logger.malicious("NOT SUPPORTED");
}
if (main.shouldZipMaliciousPlugins()) {
if (!main.foundMaliciousPlugins()) {
main.setMaliciousPluginsFound(true);
}
main.addMaliciousPlugin(file);
}
} else {
String fullCheckName = check.getFileName().isEmpty() ? "" : " (" + check.getFileName() + ")";
String fullFileName = name + fullCheckName;
logger.info(fullFileName + " MIGHT not be infected with " + check.getName() + "(" + check.getType() + ")");
String fileChecksum = DigestUtils.md5Hex(Files.newInputStream(file.toPath()));
if (!author.isEmpty()) {
if (!config.isSet(author + "." + name)) {
if (main.shouldLogDebugMessages()) {
logger.debug(author + "." + name + " is not set");
}
return false;
}
List<String> checksums = checksumDatabase.getStringList(author + "." + name);
for (String checksum : checksums) {
if (main.shouldLogDebugMessages()) {
logger.debug("File checksum: " + fileChecksum + " Database checksum: " + checksum);
}
if (fileChecksum.equalsIgnoreCase(checksum)) {
logger.info(file.getName() + " is probably safe due to it being in the checksum database");
return true;
}
}
return false;
}
try {
zipFile.close();
} catch (IOException ex) {
logger.exception(ex.toString());
if(main.shouldLogDebugMessages()){
if(checksumDatabase != null){
logger.debug(checksumDatabase.saveToString());
}else{
logger.debug("Checksum database is null");
}
}
if (!checksumDatabase.isSet(name)) {
if (main.shouldLogDebugMessages()) {
logger.debug(name + " is not set");
}
return false;
}
List<String> checksums = checksumDatabase.getStringList(name);
for (String checksum : checksums) {
if (main.shouldLogDebugMessages()) {
logger.debug("File checksum: " + fileChecksum + " Database checksum: " + checksum);
}
if (fileChecksum.equalsIgnoreCase(checksum)) {
logger.info(file.getName() + " is probably safe due to it being in the checksum database");
return true;
}
}
return false;
}
Expand All @@ -111,9 +144,14 @@ public boolean process(String name, File file) {
logger.exception(ex.getMessage());
return false;
}
if (zipFile == null) {
return false;
try {
if (isInChecksumDatabase(file)) {
return true;
}
} catch (IOException ex) {
logger.exception(ex);
}
logger.info(file.getName() + " wasn't in the checksum database, so it will be scanned for malicious code");
for (Check check : checks) {
logger.info("Checking if " + name + " is infected with " + check.getName() + "(" + check.getType() + ")");
if (check.process(name, zipFile)) {
Expand Down

0 comments on commit c274458

Please sign in to comment.