Skip to content

Commit

Permalink
Introduce server query padding
Browse files Browse the repository at this point in the history
For compatibility with security patches to future game servers versions
this adds a 1200 byte padding to all requests packets as defined in the
following HLDS mailing list post:

https://www.mail-archive.com/[email protected]/msg01194.html

See koraktor/steam-condenser#331
  • Loading branch information
koraktor committed Nov 19, 2020
1 parent d96ec04 commit e03cdf6
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
/*
* This code is free software; you can redistribute it and/or modify it under
* the terms of the new BSD License.
*
* Copyright (c) 2008-2011, Sebastian Staudt
* Copyright (c) 2008-2020, Sebastian Staudt
*/

package com.github.koraktor.steamcondenser.steam.packets;
Expand All @@ -13,7 +13,7 @@
* @author Sebastian Staudt
* @see com.github.koraktor.steamcondenser.steam.servers.GameServer#updateServerInfo
*/
public class A2S_INFO_Packet extends SteamPacket {
public class A2S_INFO_Packet extends QueryPacket {

/**
* Creates a new A2S_INFO request object
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
/*
* This code is free software; you can redistribute it and/or modify it under
* the terms of the new BSD License.
*
* Copyright (c) 2008-2012, Sebastian Staudt
* Copyright (c) 2008-2020, Sebastian Staudt
*/

package com.github.koraktor.steamcondenser.steam.packets;
Expand All @@ -20,7 +20,7 @@
* @author Sebastian Staudt
* @see com.github.koraktor.steamcondenser.steam.servers.GameServer#updatePlayers
*/
public class A2S_PLAYER_Packet extends SteamPacket {
public class A2S_PLAYER_Packet extends QueryPacket {

/**
* Creates a new A2S_PLAYER request object without a challenge number
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
/*
* This code is free software; you can redistribute it and/or modify it under
* the terms of the new BSD License.
*
* Copyright (c) 2008-2011, Sebastian Staudt
* Copyright (c) 2008-2020, Sebastian Staudt
*/

package com.github.koraktor.steamcondenser.steam.packets;
Expand All @@ -21,7 +21,7 @@
* @author Sebastian Staudt
* @see com.github.koraktor.steamcondenser.steam.servers.GameServer#updateRules
*/
public class A2S_RULES_Packet extends SteamPacket {
public class A2S_RULES_Packet extends QueryPacket {

/**
* Creates a new A2S_RULES request object including the challenge number
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* This code is free software; you can redistribute it and/or modify it under
* the terms of the new BSD License.
*
* Copyright (c) 2020, Sebastian Staudt
*/

package com.github.koraktor.steamcondenser.steam.packets;

import java.util.Arrays;

import org.apache.commons.lang3.ArrayUtils;

/**
* This is used as a wrapper to create padding of request packets to a minimum
* size of 1200 bytes. This was introduced in November 2020 as a
* counter-measure to DoS attacks on game servers.
*
* @author Sebastian Staudt
*/
class QueryPacket extends SteamPacket {

// The minimum package size as defined by Valve
private static final int STEAM_GAMESERVER_MIN_CONNECTIONLESS_PACKET_SIZE = 1200;

static byte[] addPadding(byte[] data) {
if (data.length < STEAM_GAMESERVER_MIN_CONNECTIONLESS_PACKET_SIZE - 5) {
byte[] padding = new byte[STEAM_GAMESERVER_MIN_CONNECTIONLESS_PACKET_SIZE - 5 - data.length];
return ArrayUtils.addAll(data, padding);
} else {
return data;
}
}

/**
* Creates a new query packet including data padding
*
* @param data The data of the original query
*/
QueryPacket(byte header, byte[] data) {
super(header, addPadding(data));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* This code is free software; you can redistribute it and/or modify it under
* the terms of the new BSD License.
*
* Copyright (c) 2020, Sebastian Staudt
*/

package com.github.koraktor.steamcondenser.steam.packets;

import java.util.Arrays;

import org.apache.commons.lang3.ArrayUtils;

import org.junit.Test;

import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.core.Is.*;
import static org.hamcrest.core.IsEqual.*;

public class QueryPacketTest {

@Test
public void testPadding() {
QueryPacket packet = new QueryPacket((byte) 0x21, new byte[] { 0x22, 0x23, 0x24, 0x25 });
byte[] bytes = packet.getBytes();

assertThat(bytes.length, is(1200));

assertThat(bytes[0], is((byte) 0xFF));
assertThat(bytes[1], is((byte) 0xFF));
assertThat(bytes[2], is((byte) 0xFF));
assertThat(bytes[3], is((byte) 0xFF));
assertThat(bytes[4], is((byte) 0x21));
assertThat(bytes[5], is((byte) 0x22));
assertThat(bytes[6], is((byte) 0x23));
assertThat(bytes[7], is((byte) 0x24));
assertThat(bytes[8], is((byte) 0x25));

byte[] paddingBytes = ArrayUtils.subarray(bytes, 9, 1200);
byte[] expectedPadding = new byte[1191];
Arrays.fill(expectedPadding, (byte) 0x0);
assertThat(paddingBytes, is(equalTo(expectedPadding)));
}
}

0 comments on commit e03cdf6

Please sign in to comment.