Hi guys.  I'm becoming quite familiar with ioquake3 server code, in
particular the connect procedure defined in code/server/sv_client.c.  I'm
modifying SV_GetChallenge() and SV_DirectConnect() quite extensively,
because I am implementing a central player database and auth server for all
of my Urban Terror servers (see http://daffy.nerius.com/urtserver/ and
http://daffy.nerius.com/bansystem/).  My playerdb works a bit like the
classic Q3 auth server (defined at the bottom of SV_GetChallenge()), but not
exactly.  The rest of this email is just regarding plain vanilla ioquake3,
however.

After reading the code in SV_GetChallenge(), I began to think about expoit
possibilities.  I'm looking at ioquake3 1.36 and the current version in SVN.

OK, so my main question is, without diving too deeply into the low-level NET
code, as follows.  Does every getchallenge UDP packet coming from a client
translate one-to-one to a call to SV_GetChallenge()?

I am asking this question because of the following possible scenario.

Let's say that a devious client decides to flood the ioquake3 server with
getchallenge packets.  However, this client is really devious; he or she
decides to choose a source port at random for every packet that gets sent.
The server is absolutely bombarded with getchallenge packets; they are sent
to the server as quickly as possible.

OK, so two really bad things will happen, from what I see in the source
code, when SV_GetChallenge() is called at a very fast rate with a different
source address each time (different because of changing port number).
First, all of the server challenges (there are only 1024) will be cycled
through very quickly.  Within milliseconds.  They will all be set to have an
address being equal to the attacker's IP address.  They will be exhausted
because each getchallenge packet has a random source port.

Two consequences of this.  First, let's say that a high pinger (ping 200) is
connecting to the server.  it takes him or her 200 milliseconds between when
the server sends the challenge response to when the client's connect packet
is received.  In 200 milliseconds, all of the challenges are cycled through
due to the attacker.  So the high pinger will never be able to connect
because a matching challenge will never be found.

Another big consequence of this attack.  For each getchallenge packet
received, if this isn't STANDALONE and if com_standalone is set to 0 (like
in default vanilla Q3A), a packet will be sent to the Q3 auth server for
every one of these attacking getchallenge packets.  If we multiply this by
the number of servers out there and assume that each one could be attacked
simultaneously, then that would imply that the auth server would be
absolutely flooded with auth packets.

I have addressed a lot of issues in my custom code that implements my custom
playerdb and auth system.  However, one issue remains - the possiblity of of
this getchallenge attack with the varying source ports.  That would cause
unpleasant things to happen in my system, too.

Is there some kind of throttle in getchallenge packets that does not allow
more than a certain rate of these packets from one particular IP address?
Would that be an elegant way to address this problem?

Thanks, Rambetter
_______________________________________________
ioquake3 mailing list
ioquake3@lists.ioquake.org
http://lists.ioquake.org/listinfo.cgi/ioquake3-ioquake.org
By sending this message I agree to love ioquake3 and libsdl.

Reply via email to