Potential exploit in AbstractClassRep::create.
by Stefan Lundmark · in Torque Game Engine · 11/03/2006 (2:03 pm) · 3 replies
There is a potential DOS exploit in AbstractClass::create () which triggers if an invalid or out of range classId is specified.
[BACKGROUND.]
Torque keeps a list of networkable classes and maintains class id's for each of these classes. When a NetEvent is triggered, this class bit is sent to the other side so that it can create an instance of the NetEvent class. Both sides need to have the same list or the bits won't represent the same classes on both machines.
So when the connection handshake is initialized, the list is CRC'd and compared on both sides. If they differ, the connection is dropped. All fine so far!
[WHAT?]
But what if the sender (as in a hacked client or if someone is intercepting packets) passes the CRC check and then proceeds to send an invalid out of range class Id bit? Actually, the receiver (ie. server) will crash.
[SOLUTION.]
Put these two checks at the start of:
AbstractClass::create ( const U32 groupId, const U32 typeId, const U32 in_classId )
Inside:
console/consoleObject.cpp.
What the above code does is disconnecting the client if it passes an invalid classId.
[BACKGROUND.]
Torque keeps a list of networkable classes and maintains class id's for each of these classes. When a NetEvent is triggered, this class bit is sent to the other side so that it can create an instance of the NetEvent class. Both sides need to have the same list or the bits won't represent the same classes on both machines.
So when the connection handshake is initialized, the list is CRC'd and compared on both sides. If they differ, the connection is dropped. All fine so far!
[WHAT?]
But what if the sender (as in a hacked client or if someone is intercepting packets) passes the CRC check and then proceeds to send an invalid out of range class Id bit? Actually, the receiver (ie. server) will crash.
[SOLUTION.]
Put these two checks at the start of:
AbstractClass::create ( const U32 groupId, const U32 typeId, const U32 in_classId )
Inside:
console/consoleObject.cpp.
// Is the specified ID bit out of range?
if ( in_classId >= NetClassCount[groupId][typeId] )
{
// Trigger an invalid packet error.
Con::printf ( "AbstractClassRep::create() - Class id out of range." );
return NULL;
}
// No? So is there a class with the requested ID type?
if ( classTable[groupId][typeId][in_classId] == NULL )
{
// Trigger an invalid packet error.
Con::printf ( "AbstractClassRep::create() - No class with requested ID type." );
return NULL;
}What the above code does is disconnecting the client if it passes an invalid classId.
About the author
Torque Owner Stefan Lundmark