fix(Core): prevent movement exploit (#2410)

This commit is contained in:
Stefano Borzì
2019-11-15 10:03:57 +01:00
committed by Francesco Borzì
parent 685538b01b
commit ab637800e7
6 changed files with 1334 additions and 1340 deletions

View File

@@ -661,7 +661,7 @@ bool LinkExtractor::IsValidMessage()
break; break;
char commandChar; char commandChar;
_iss >> commandChar; _iss.get(commandChar);
// | in normal messages is escaped by || // | in normal messages is escaped by ||
if (commandChar != PIPE_CHAR) if (commandChar != PIPE_CHAR)

View File

@@ -303,7 +303,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
Unit* mover = _player->m_mover; Unit* mover = _player->m_mover;
ASSERT(mover != NULL); // there must always be a mover ASSERT(mover != nullptr); // there must always be a mover
Player* plrMover = mover->ToPlayer(); Player* plrMover = mover->ToPlayer();
@@ -319,10 +319,16 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
recvData.readPackGUID(guid); recvData.readPackGUID(guid);
// prevent tampered movement data
if (!guid || guid != mover->GetGUID()) {
recvData.rfinish(); // prevent warnings spam
return;
}
// pussywizard: typical check for incomming movement packets // pussywizard: typical check for incomming movement packets
if (!mover || !mover->IsInWorld() || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID()) if (!mover || !(mover->IsInWorld()) || mover->IsDuringRemoveFromWorld() || !(mover->movespline->Finalized()))
{ {
recvData.rfinish(); recvData.rfinish(); // prevent warnings spam
return; return;
} }
@@ -330,8 +336,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
movementInfo.guid = guid; movementInfo.guid = guid;
ReadMovementInfo(recvData, &movementInfo); ReadMovementInfo(recvData, &movementInfo);
if (!movementInfo.pos.IsPositionValid()) if (!movementInfo.pos.IsPositionValid()) {
{
recvData.rfinish(); // prevent warnings spam recvData.rfinish(); // prevent warnings spam
return; return;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1361,7 +1361,6 @@ struct OpcodeHandler
SessionStatus status; SessionStatus status;
PacketProcessing packetProcessing; PacketProcessing packetProcessing;
void (WorldSession::*handler)(WorldPacket& recvPacket); void (WorldSession::*handler)(WorldPacket& recvPacket);
bool isGrouppedMovementOpcode; // pussywizard
}; };
extern OpcodeHandler opcodeTable[NUM_MSG_TYPES]; extern OpcodeHandler opcodeTable[NUM_MSG_TYPES];

View File

@@ -301,28 +301,18 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
} }
else else
{ {
if (opHandle.isGrouppedMovementOpcode) if (movementPacket)
{ {
if (movementPacket) HandleMovementOpcodes(*movementPacket);
delete movementPacket; delete movementPacket;
movementPacket = new WorldPacket(packet->GetOpcode(), 0); movementPacket = NULL;
movementPacket->append(*((ByteBuffer*)packet)); }
} sScriptMgr->OnPacketReceive(this, *packet);
else
{
if (movementPacket)
{
HandleMovementOpcodes(*movementPacket);
delete movementPacket;
movementPacket = NULL;
}
sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA #ifdef ELUNA
if (!sEluna->OnPacketReceive(this, *packet)) if (!sEluna->OnPacketReceive(this, *packet))
break; break;
#endif #endif
(this->*opHandle.handler)(*packet); (this->*opHandle.handler)(*packet);
}
} }
break; break;
case STATUS_TRANSFER: case STATUS_TRANSFER:
@@ -358,7 +348,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break; break;
} }
} }
catch(ByteBufferException &) catch(ByteBufferException const&)
{ {
sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
if (sLog->IsOutDebug()) if (sLog->IsOutDebug())

View File

@@ -711,7 +711,7 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
} }
} }
} }
catch (ByteBufferException &) catch (ByteBufferException const&)
{ {
sLog->outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.", opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1); sLog->outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.", opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1);
if (sLog->IsOutDebug()) if (sLog->IsOutDebug())