From 0d904ed7bd4e982e15378f8bb300ce5244c02f99 Mon Sep 17 00:00:00 2001 From: Remco Date: Wed, 18 Nov 2020 13:39:48 +0100 Subject: [PATCH] Fixed exploit in CameraRoomPictureEvent and did some refactoring --- .../krews/apollyon/ftp/FTPUploadService.java | 7 ++- .../incoming/CameraRoomPictureEvent.java | 44 +++++++++---------- .../apollyon/utils/PngSignatureChecker.java | 20 +++++++++ 3 files changed, 45 insertions(+), 26 deletions(-) create mode 100644 src/main/java/org/krews/apollyon/utils/PngSignatureChecker.java diff --git a/src/main/java/org/krews/apollyon/ftp/FTPUploadService.java b/src/main/java/org/krews/apollyon/ftp/FTPUploadService.java index 135253e..b8dceff 100644 --- a/src/main/java/org/krews/apollyon/ftp/FTPUploadService.java +++ b/src/main/java/org/krews/apollyon/ftp/FTPUploadService.java @@ -1,6 +1,7 @@ package org.krews.apollyon.ftp; import com.eu.habbo.Emulator; +import org.krews.apollyon.utils.PngSignatureChecker; import java.io.IOException; import java.io.OutputStream; @@ -12,10 +13,8 @@ import java.util.Arrays; public class FTPUploadService { private static final String ftpUrl = "ftp://%s:%s@%s/%s;type=i"; - public static void uploadImage(byte[] image, String uploadPath) throws IOException{ - byte[] pngSignature = new byte[] { -119, 80, 78, 71, 13, 10, 26, 10 }; - - if (Arrays.equals(Arrays.copyOfRange(image, 0, 8), pngSignature)) { + public static void uploadImage(byte[] image, String uploadPath) throws IOException { + if (PngSignatureChecker.isPngFile(image)) { String host = Emulator.getConfig().getValue("ftp.host"); String user = Emulator.getConfig().getValue("ftp.user"); String pass = Emulator.getConfig().getValue("ftp.password"); diff --git a/src/main/java/org/krews/apollyon/incoming/CameraRoomPictureEvent.java b/src/main/java/org/krews/apollyon/incoming/CameraRoomPictureEvent.java index f44d5b9..1c7c01d 100644 --- a/src/main/java/org/krews/apollyon/incoming/CameraRoomPictureEvent.java +++ b/src/main/java/org/krews/apollyon/incoming/CameraRoomPictureEvent.java @@ -1,21 +1,19 @@ package org.krews.apollyon.incoming; import com.eu.habbo.Emulator; -import com.eu.habbo.habbohotel.catalog.CatalogManager; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.outgoing.camera.CameraURLComposer; import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; -import javafx.scene.Camera; import org.krews.apollyon.ftp.FTPUploadService; +import org.krews.apollyon.utils.PngSignatureChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; -import java.awt.image.DataBufferByte; import java.io.File; import java.io.IOException; import java.lang.IllegalArgumentException; @@ -26,23 +24,27 @@ public class CameraRoomPictureEvent extends MessageHandler { @Override public void handle() { if (!this.client.getHabbo().hasPermission("acc_camera")) { - this.client.sendResponse(new GenericAlertComposer(Emulator.getTexts().getValue("camera.permission"))); - return; - } + this.client.sendResponse(new GenericAlertComposer(Emulator.getTexts().getValue("camera.permission"))); + return; + } - Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); - if (room == null) - return; + if (room == null) + return; - final int count = this.packet.readInt(); + final int count = this.packet.readInt(); - ByteBuf image = this.packet.getBuffer().readBytes(count); + ByteBuf image = this.packet.getBuffer().readBytes(count); - if (image == null) - return; + if (image == null) + return; - try { + try { + byte[] imageBytes = new byte[image.readableBytes()]; + image.readBytes(imageBytes); + + if (PngSignatureChecker.isPngFile(imageBytes)) { this.packet.readString(); this.packet.readString(); this.packet.readInt(); @@ -61,13 +63,10 @@ public class CameraRoomPictureEvent extends MessageHandler { lol.lastRanTimestamps.put(this.client.getHabbo(), Emulator.getIntUnixTimestamp()); try { - if(Emulator.getConfig().getInt("ftp.enabled") == 1) { - byte[] imageBytes = new byte[image.readableBytes()]; - image.readBytes(imageBytes); + if (Emulator.getConfig().getInt("ftp.enabled") == 1) { FTPUploadService.uploadImage(imageBytes, Emulator.getConfig().getValue("imager.location.output.camera") + URL); FTPUploadService.uploadImage(imageBytes, Emulator.getConfig().getValue("imager.location.output.camera") + URL_small); - } - else { + } else { BufferedImage theImage = ImageIO.read(new ByteBufInputStream(image)); ImageIO.write(theImage, "png", new File(Emulator.getConfig().getValue("imager.location.output.camera") + URL)); ImageIO.write(theImage, "png", new File(Emulator.getConfig().getValue("imager.location.output.camera") + URL_small)); @@ -80,8 +79,9 @@ public class CameraRoomPictureEvent extends MessageHandler { } this.client.sendResponse(new CameraURLComposer(URL)); - } finally { - image.release(); } + } finally { + image.release(); } - } \ No newline at end of file + } +} diff --git a/src/main/java/org/krews/apollyon/utils/PngSignatureChecker.java b/src/main/java/org/krews/apollyon/utils/PngSignatureChecker.java new file mode 100644 index 0000000..14b330e --- /dev/null +++ b/src/main/java/org/krews/apollyon/utils/PngSignatureChecker.java @@ -0,0 +1,20 @@ +package org.krews.apollyon.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + +public class PngSignatureChecker { + private static final Logger LOGGER = LoggerFactory.getLogger(PngSignatureChecker.class); + private static byte[] signature = new byte[] { -119, 80, 78, 71, 13, 10, 26, 10 }; + + public static boolean isPngFile(byte[] file) { + if (Arrays.equals(Arrays.copyOfRange(file, 0, 8), signature)) { + return true; + } else { + LOGGER.warn("[Apollyon] Someone tried to exploit the camera by uploading a malicious file!"); + return false; + } + } +}