Urban Terror Forums: DRDoS - Urban Terror Forums

Jump to content

 Login | Register 
Advertisement
  • (27 Pages)
  • +
  • 1
  • 2
  • 3
  • 4
  • Last »
  • You cannot start a new topic
  • This topic is locked

DRDoS Rate Topic: ***** 1 Votes

Server used as reflector fro DRDoS

#11 User is offline   Rambetter Icon

  •   community dev   
  • Account: rambetter
  • Joined: 28-February 10
  • Posts: 1,140

Posted 09 December 2011 - 10:46 PM

Hi guys, thanks for bringing this exploit to my attention.

In fact I saw the possibility for this exploit last year when I was working with the network code. So it finally got abused, eh?

I will create a patch for this in the next 48 hours.

My proposed fix is twofold.

A. First, limit the number of getstatus/getinfo packet responses to a given IP address to a very low number over the course of 5 seconds or so.

B. Second, as a "catch all", limit the total number of getstatus/getinfo responses to a moderate number over the course of 5 seconds.

Let's take two attack scenarios.

First scenario, an attacker is trying to flood a particular server somewhere. The attacker sends getstatus packets with the source IP being that of the server he wants to attack. Because of fix A, he'll only be able to get a small number of UDP packets sent to that IP address via our game server. What's better is that a legitimate client who requests getstatus will be able to make a successful request, because the duplicate phony requests that the attacker is sending all have the same source IP, and only a few of those are counted towards the total number of responses sent (fix B).

Second scenario, an attacker just wants to flood the game server network. He just wants the game server to send lots of data for no reason. The attacker uses a different random source IP address in every getstatus request. Because of fix B, we'll limit the number of traffic sent. Unfortunately a legitimate client who sincerely requests a getstatus will likely be denied a response. There is no way around this.

This post has been edited by Rambetter: 09 December 2011 - 10:51 PM


#12 User is offline   Rambetter Icon

  •   community dev   
  • Account: rambetter
  • Joined: 28-February 10
  • Posts: 1,140

Posted 09 December 2011 - 10:57 PM

One more thing. You can find out about the getinfo/getstatus packets in the server console. Type "developer 1" in the console to enable the messages, then "developer 0" to disable the messages. You'll get output like this:

SV packet 91.121.24.62 : getstatus
SV packet 96.242.151.107 : getinfo
SV packet 96.242.151.107 : getstatus
SV packet 91.121.30.80 : getstatus
SV packet 77.176.217.21 : getstatus
SV packet 201.90.132.250 : getinfo

#13 User is offline   Rambetter Icon

  •   community dev   
  • Account: rambetter
  • Joined: 28-February 10
  • Posts: 1,140

Posted 09 December 2011 - 11:02 PM

Lol, you have got to be kidding me. I just found out that one of my servers is getting bombarded too. And it's a pretty empty server too.

SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus
SV packet 217.116.255.38 : getstatus

I'm getting hundreds per second. Lol!

OK, maybe I'll have a patch sooner than 48 hours. :-)

#14 User is offline   beautifulNihilist Icon

  •   verified user   

Posted 10 December 2011 - 12:40 AM

It is SO nice to have you back.

#15 User is offline   ipwnn00bs Icon

  • Account: ipwnn00bs
  • Joined: 06-June 10
  • Posts: 23

Posted 10 December 2011 - 04:01 AM

View PostRambetter, on 09 December 2011 - 10:46 PM, said:

First scenario, an attacker is trying to flood a particular server somewhere. The attacker sends getstatus packets with the source IP being that of the server he wants to attack. Because of fix A, he'll only be able to get a small number of UDP packets sent to that IP address via our game server. What's better is that a legitimate client who requests getstatus will be able to make a successful request, because the duplicate phony requests that the attacker is sending all have the same source IP, and only a few of those are counted towards the total number of responses sent (fix B).


Yep, I think this solution is the best, limit the request per host and not only globally, but I was unable to code that in little time.

View PostRambetter, on 09 December 2011 - 10:46 PM, said:

Second scenario, an attacker just wants to flood the game server network. He just wants the game server to send lots of data for no reason. The attacker uses a different random source IP address in every getstatus request. Because of fix B, we'll limit the number of traffic sent. Unfortunately a legitimate client who sincerely requests a getstatus will likely be denied a response. There is no way around this.


After applying my solution, I was still able to get the server info without problems during the attacks, despite the apparently global limit that I've imposed.



View PostRambetter, on 09 December 2011 - 10:57 PM, said:

One more thing. You can find out about the getinfo/getstatus packets in the server console. Type "developer 1" in the console to enable the messages, then "developer 0" to disable the messages.


Thanks, I didn't knew about this


View PostRambetter, on 09 December 2011 - 11:02 PM, said:

Lol, you have got to be kidding me. I just found out that one of my servers is getting bombarded too. And it's a pretty empty server too.
I'm getting hundreds per second. Lol!


Yes, I think everybody is getting flooded, they are just taking the master list or something. Even the Quake 3 servers probably are being used.

This post has been edited by ipwnn00bs: 10 December 2011 - 04:01 AM


bullet_loaderAdvertisement

#16 User is offline   apath0 Icon

  • Account: apath0
  • Joined: 06-December 11
  • Posts: 7

Posted 10 December 2011 - 11:41 AM

Thanks a lot for taking a look into this, ramb!

I am running the tempoary fix provided by ipwnn00bs (thx!) for the last days and this really helps at least in bringing the traffic down. i am on the other hand experiencing the problem, that while being bombarded with requests my server wont show up in any serverbrowser (ingame + urtsb), at least not on every query. I also am facing problems with my b3-configuration (countryfilter announces every user every round, xlrstats aren't logged correctly anymore, ...). I am not really sure about this, but this could also be connected to using ioquake3-UrT-server-4.1 now, instead of ioUrT-server-4.1 before.
Could anyone please tell me about the differences between those two versions? I noticed the newer extrapatches are just there for ioquake3... so is this the version the one being actively maintained at the moment? The opening post in rambs thread points to ioUrT-server-4.1. Got me a little confused there ;)

Anyways, thanks to all of you

apath0

#17 User is offline   Nitro Icon

  •   former FS member   
  • Account: nitro
  • Main tag: |PWNY|
  • Country:
  • Joined: 15-March 10
  • Posts: 1,130

Posted 10 December 2011 - 12:20 PM

View PostRambetter, on 09 December 2011 - 10:46 PM, said:

Hi guys, thanks for bringing this exploit to my attention.

In fact I saw the possibility for this exploit last year when I was working with the network code. So it finally got abused, eh?

I will create a patch for this in the next 48 hours.

My proposed fix is twofold.

A. First, limit the number of getstatus/getinfo packet responses to a given IP address to a very low number over the course of 5 seconds or so.

B. Second, as a "catch all", limit the total number of getstatus/getinfo responses to a moderate number over the course of 5 seconds.

Let's take two attack scenarios.

First scenario, an attacker is trying to flood a particular server somewhere. The attacker sends getstatus packets with the source IP being that of the server he wants to attack. Because of fix A, he'll only be able to get a small number of UDP packets sent to that IP address via our game server. What's better is that a legitimate client who requests getstatus will be able to make a successful request, because the duplicate phony requests that the attacker is sending all have the same source IP, and only a few of those are counted towards the total number of responses sent (fix B).

Second scenario, an attacker just wants to flood the game server network. He just wants the game server to send lots of data for no reason. The attacker uses a different random source IP address in every getstatus request. Because of fix B, we'll limit the number of traffic sent. Unfortunately a legitimate client who sincerely requests a getstatus will likely be denied a response. There is no way around this.


Hi Ram! I am so glad you still monitor these forums! I have been currently using iptables to prevent this:

Quote

iptables -A INPUT -p udp -m udp --dport 27000:29000 -m state --state NEW -m recent --update --seconds 30 --hitcount 10 --name DEFAULT --rsource -j DROP
iptables -A INPUT -p udp -m udp --dport 27000:29000 -m state --state NEW -m recent --set --name DEFAULT --rsource


Please can you make a cvar or list variable so that we can provide a whitelist of ip's or ignore local ip's that way server bots dont get interupted, for example B3 sends getstatus quite a lot to keeps teams balanced, my server has the bot locally so it uses a local IP, however some services provide remote B3 support and they do this via FTPtail of the log file.

thanks again.

P.S. if your ever hanging out in mumble or TS can you pm and let me know where!

P.P.S please make a patch for both ioUrT and ioQ3 repo's PRETTY PLEASE :D you know some of us still use your ioUrT :(

This post has been edited by nitro: 10 December 2011 - 03:11 PM

Corsair 230T Orange | Intel 6600K @ 4.8GHz | 16GB DDR4 2133MHz | 512GB Samsung 950pro NVMe SSD | 8GB AMD Radeon RX-480

#18 User is offline   WizardOfGore Icon

  •   clan leader   
  • Account: wizardofgore
  • Country:
  • Joined: 23-December 10
  • Posts: 3

Posted 10 December 2011 - 01:50 PM

Heya there!

Since my servers are becoming increasingly unplayable during these attacks, I took the liberty of writing my own patch to bridge the time until Rambetter codes something proper. It supersedes the patch created by ipwnn00bs and defies all attack scenarios proposed so far.

I host several servers on a single dedicated box, which led to outging traffic peaks of 10MB/s and above during attacks - with the patch applied the outgoing traffic is less than the incoming traffc generated by the attackers queries.

While it lacks fancy features like whitelisting and adjustment via cvars yet, it does its job. The limit on getstatus and getinfo imposed by this patch is quite generous, so it should not affect B3 or other server management tools (it will ignore both getstatus and getinfo packets coming from a single IP address in excess of 5 in the past 2 seconds, with a maximum of 32 simultaneous queries from different IPs).

You can get the patch here.
Edit: Archive now contains .patch files for both ioUrT and ioquake3 (based on Rambetters)


Code snipped from sv_main with the patch applied (ioUrT):
/*
================
SVC_Status

Responds with all the info that qplug or qspy can see about the server
and all connected players.  Used for getting detailed information after
the simple info query.
================
*/
/* Added per ip timeout! Rough fix */

typedef struct cl_ip_tout
{
	uint8_t count;
	uint32_t time;
	uint32_t ip;

} cl_ip_tout;

cl_ip_tout *cit_array = 0;
uint8_t     cit_count = 0;

void SVC_Status( netadr_t from ) {
	char	player[1024];
	char	status[MAX_MSGLEN];
	int		i;
	client_t	*cl;
	playerState_t	*ps;
	int		statusLength;
	int		playerLength;
	char	infostring[MAX_INFO_STRING];

	// ignore if we are in single player
	if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER ) {
		return;
	}

	uint32_t from_ip_as_int = *((uint32_t*)from.ip);
	cl_ip_tout *match = NULL;

	// check for timed out clients.
	// also check if the ip is already known (multiple queries or DRDOS)
	for (i=0; i < cit_count; i++)
	{
		if (cit_array[i].time < svs.time) // timeout?
		{
			cit_array[i].ip = 0; // -> drop
		}
		else if (cit_array[i].ip == from_ip_as_int) // match found.
		{
			match = &cit_array[i];
			break;
		}
	}

	if (cit_count >= 32) // Prevent mass flooding. Max allowed packets: 32*5 per 2 seconds.
		return;

	// is the last entry of our array empty? If yes, drop.
	if (cit_count > 0 && cit_array[cit_count-1].ip == 0) // resize our array.
	{
		cit_count--;
		cit_array = realloc(cit_array, cit_count*sizeof(cl_ip_tout));
	}

	if (match != NULL) // now that we've found our match.
	{
		match->count++;
		if (match->count > 5)
		{
			return; // ignore spammers!
		}
	}
	else  // new client
	{
		for (i=0; i < cit_count; i++) // check for empty array slots
		{
			if (cit_array[i].ip == 0) // empty slot found.
			{
				match = &cit_array[i];
				break;
			}
		}

		if (match == NULL) // array full -> resizing array.
		{
			cit_count++;
			cit_array = realloc(cit_array, cit_count*sizeof(cl_ip_tout));
			match = &cit_array[cit_count-1];
		}

		match->count = 1; // set data.
		match->ip    = from_ip_as_int;
		match->time  = svs.time + 2000;
	}

	strcpy( infostring, Cvar_InfoString( CVAR_SERVERINFO ) );

	// echo back the parameter to status. so master servers can use it as a challenge
	// to prevent timed spoofed reply packets that add ghost servers
	Info_SetValueForKey( infostring, "challenge", Cmd_Argv(1) );

	status[0] = 0;
	statusLength = 0;

	for (i=0 ; i < sv_maxclients->integer ; i++) {
		cl = &svs.clients[i];
		if ( cl->state >= CS_CONNECTED ) {
			ps = SV_GameClientNum( i );
			Com_sprintf (player, sizeof(player), "%i %i \"%s\"\n", 
				ps->persistant[PERS_SCORE], cl->ping, cl->name);
			playerLength = strlen(player);
			if (statusLength + playerLength >= sizeof(status) ) {
				break;		// can't hold any more
			}
			strcpy (status + statusLength, player);
			statusLength += playerLength;
		}
	}

	NET_OutOfBandPrint( NS_SERVER, from, "statusResponse\n%s\n%s", infostring, status );
}

/*
================
SVC_Info

Responds with a short info message that should be enough to determine
if a user is interested in a server to do a full status
================
*/
void SVC_Info( netadr_t from ) {
	int		i, count;
	char	*gamedir;
	char	infostring[MAX_INFO_STRING];

	// ignore if we are in single player
	if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
		return;
	}

        uint32_t from_ip_as_int = *((uint32_t*)from.ip);
        cl_ip_tout *match = NULL;

        // check for timed out clients.
        // also check if the ip is already known (multiple queries or DRDOS)
        for (i=0; i < cit_count; i++)
        {
                if (cit_array[i].time < svs.time) // timeout?
                {
                        cit_array[i].ip = 0; // -> drop.
                }
                else if (cit_array[i].ip == from_ip_as_int) // match found.
                {
                        match = &cit_array[i];
                        break;
                }
        }

        if (cit_count >= 32) // Prevent mass flooding. Max allowed packets: 32*5 per 2 seconds.
                return;

        // is the last entry of our array empty? If yes, drop.
        if (cit_count > 0 && cit_array[cit_count-1].ip == 0) // resize our array.
        {
                cit_count--;
                cit_array = realloc(cit_array, cit_count*sizeof(cl_ip_tout));
        }

        if (match != NULL) // now that we've found our match.
        {
                match->count++;
                if (match->count > 5)
                {
                        return; // ignore spammers!
                }
        }
        else  // new client
        {
                for (i=0; i < cit_count; i++) // check for empty array slots
                {
                        if (cit_array[i].ip == 0) // empty slot found.
                        {
                                match = &cit_array[i];
                                break;
                        }
                }

                if (match == NULL) // array full -> resizing array.
                {
                        cit_count++;
                        cit_array = realloc(cit_array, cit_count*sizeof(cl_ip_tout));
                        match = &cit_array[cit_count-1];
                }

                match->count = 1; // set data.
                match->ip    = from_ip_as_int;
                match->time  = svs.time + 2000;
        }


And, before i forget it: Yay! first post after months of membership.



Wizard.

This post has been edited by WizardOfGore: 10 December 2011 - 02:27 PM


#19 User is offline   Nitro Icon

  •   former FS member   
  • Account: nitro
  • Main tag: |PWNY|
  • Country:
  • Joined: 15-March 10
  • Posts: 1,130

Posted 10 December 2011 - 04:01 PM

willthese patches being created be enough to prevent unpatched servers from accidentally send the return data to patched servers or will all servers require this patch in order to prevent the attack from spoofing the source ip as a patched servers ip
Corsair 230T Orange | Intel 6600K @ 4.8GHz | 16GB DDR4 2133MHz | 512GB Samsung 950pro NVMe SSD | 8GB AMD Radeon RX-480

#20 User is offline   farflame Icon

  • Account: farflame
  • Joined: 06-December 11
  • Posts: 7

Posted 10 December 2011 - 04:10 PM

View Postipwnn00bs, on 09 December 2011 - 08:20 PM, said:

Have you read my post farflame?


Yes, thanks a lot :)

Thanks also to all of you that are trying to solve this problem :)

Quote

If you get something with iptables let me know, despite isn't the best solution for all, because some people uses Windows, or uses a machine without root privileges.


I'm trying to figure out something to limit them via iptables. Of course I know that this will help only linux users that have full acces to their server :(
Seems that nitro in previous post did it using recent module.

Thanks Rambetter for helping us in solving this problem.
Will wait for your patch :)

The attacker are moving from more crowded server lists (COD4 2) to smaller lists but they still create a lot of problems :(

Thanks again.

This post has been edited by farflame: 10 December 2011 - 04:36 PM


  • (27 Pages)
  • +
  • 1
  • 2
  • 3
  • 4
  • Last »
  • You cannot start a new topic
  • This topic is locked

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users

Advertisement


Copyright © 1999-2019 Frozensand Games Limited  |  All rights reserved  |  Urban Terror™ and FrozenSand™ are trademarks of Frozensand Games Limited

Frozensand Games is a Limited company registered in England and Wales. Company Reg No: 10343942