diff --git a/src/main/java/org/krews/apollyon/ftp/FTPUploadService.java b/src/main/java/org/krews/apollyon/ftp/FTPUploadService.java index f26f7a2..b8dceff 100644 --- a/src/main/java/org/krews/apollyon/ftp/FTPUploadService.java +++ b/src/main/java/org/krews/apollyon/ftp/FTPUploadService.java @@ -1,27 +1,31 @@ package org.krews.apollyon.ftp; import com.eu.habbo.Emulator; +import org.krews.apollyon.utils.PngSignatureChecker; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; +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{ - String host = Emulator.getConfig().getValue("ftp.host"); - String user = Emulator.getConfig().getValue("ftp.user"); - String pass = Emulator.getConfig().getValue("ftp.password"); + 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"); - String uploadURL = String.format(ftpUrl, URLEncoder.encode(user, "UTF-8"), URLEncoder.encode(pass, "UTF-8"), host, uploadPath); + String uploadURL = String.format(ftpUrl, URLEncoder.encode(user, "UTF-8"), URLEncoder.encode(pass, "UTF-8"), host, uploadPath); - URL url = new URL(uploadURL); - URLConnection conn = url.openConnection(); - OutputStream outputStream = conn.getOutputStream(); - outputStream.write(image, 0, image.length); - outputStream.close(); + URL url = new URL(uploadURL); + URLConnection conn = url.openConnection(); + OutputStream outputStream = conn.getOutputStream(); + outputStream.write(image, 0, image.length); + outputStream.close(); + } } } diff --git a/src/main/java/org/krews/apollyon/incoming/CameraRoomPictureEvent.java b/src/main/java/org/krews/apollyon/incoming/CameraRoomPictureEvent.java index f44d5b9..8dd7fac 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,28 @@ 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); + ByteBuf imageCopy = image.copy(); - 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,14 +64,11 @@ 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 { - BufferedImage theImage = ImageIO.read(new ByteBufInputStream(image)); + } else { + BufferedImage theImage = ImageIO.read(new ByteBufInputStream(imageCopy)); 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 +80,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; + } + } +}