Merge pull request #270 from diamante0018/sec-fix-net

[Security] Refactor patch (fix mistake?)
This commit is contained in:
Edo 2022-05-11 18:33:53 +01:00 committed by GitHub
commit a4db4f5ed3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 12 deletions

View File

@ -356,17 +356,11 @@ namespace Components
}
}
void Network::NET_DeferPacketToClientStub(Game::netadr_t* from, Game::msg_t* msg)
{
if (msg->cursize > 0 && msg->cursize <= 1404)
Game::NET_DeferPacketToClient(from, msg);
}
void Network::SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg)
{
if (client->reliableAcknowledge < 0)
{
Logger::Print("Negative reliableAcknowledge from %s - cl->reliableSequence is %i, reliableAcknowledge is %i\n",
Logger::Print(Game::conChannel_t::CON_CHANNEL_NETWORK, "Negative reliableAcknowledge from %s - cl->reliableSequence is %i, reliableAcknowledge is %i\n",
client->name, client->reliableSequence, client->reliableAcknowledge);
client->reliableAcknowledge = client->reliableSequence;
Network::SendCommand(Game::NS_SERVER, client->netchan.remoteAddress, "error", "EXE_LOSTRELIABLECOMMANDS");
@ -412,9 +406,6 @@ namespace Components
// Install packet deploy hook
Utils::Hook::RedirectJump(0x5AA713, Network::DeployPacketStub);
// Fix packets causing buffer overflow
Utils::Hook(0x6267E3, Network::NET_DeferPacketToClientStub, HOOK_CALL).install()->quick();
// Fix server freezer exploit
Utils::Hook(0x626996, Network::SV_ExecuteClientMessageStub, HOOK_CALL).install()->quick();

View File

@ -87,7 +87,6 @@ namespace Components
static void NetworkStartStub();
static void PacketErrorCheck();
static void NET_DeferPacketToClientStub(Game::netadr_t* from, Game::msg_t* msg);
static void SV_ExecuteClientMessageStub(Game::client_t* client, Game::msg_t* msg);
};

View File

@ -84,6 +84,25 @@ namespace Components
Game::G_LogPrintf("%s", fmt);
}
void Security::NET_DeferPacketToClientStub(Game::netadr_t* net_from, Game::msg_t* net_message)
{
assert(net_from != nullptr);
assert(net_message != nullptr);
if (static_cast<std::size_t>(net_message->cursize) >= sizeof(Game::DeferredMsg::data))
{
return;
}
auto* msg = &Game::deferredQueue->msgs[Game::deferredQueue->send % std::extent_v<decltype(Game::DeferredQueue::msgs)>];
std::memcpy(msg->data, net_message->data, net_message->cursize);
msg->datalen = net_message->cursize;
msg->addr = *net_from;
InterlockedIncrement(&Game::deferredQueue->send);
}
Security::Security()
{
// Exploit fixes
@ -108,5 +127,8 @@ namespace Components
// Patch unsecure call to G_LogPrint inside GScr_LogPrint
// This function is unsafe because IW devs forgot to G_LogPrintf("%s", fmt)
Utils::Hook(0x5F70B5, G_LogPrintfStub, HOOK_CALL).install()->quick();
// Fix packets causing buffer overflow
Utils::Hook(0x6267E3, NET_DeferPacketToClientStub, HOOK_CALL).install()->quick();
}
}

View File

@ -20,5 +20,7 @@ namespace Components
static int G_GetClientScore();
static void G_LogPrintfStub(const char* fmt);
static void NET_DeferPacketToClientStub(Game::netadr_t* net_from, Game::msg_t* net_message);
};
}

View File

@ -562,6 +562,8 @@ namespace Game
int* window_center_x = reinterpret_cast<int*>(0x649D638);
int* window_center_y = reinterpret_cast<int*>(0x649D630);
DeferredQueue* deferredQueue = reinterpret_cast<DeferredQueue*>(0x1CC2CE8);
int* g_waitingForKey = reinterpret_cast<int*>(0x63A50FC);
void Sys_LockRead(FastCriticalSection* critSect)

View File

@ -1166,6 +1166,8 @@ namespace Game
extern int* window_center_x;
extern int* window_center_y;
extern DeferredQueue* deferredQueue;
extern int* g_waitingForKey;
void Sys_LockRead(FastCriticalSection* critSect);

View File

@ -5365,12 +5365,13 @@ namespace Game
struct netadr_t
{
netadrtype_t type;
//char ip[4];
netIP_t ip;
unsigned __int16 port;
char ipx[10];
};
static_assert(sizeof(netadr_t) == 20);
struct netProfileInfo_t
{
char __pad0[0x5E0];
@ -7561,6 +7562,24 @@ namespace Game
static_assert(sizeof(WinMouseVars_t) == 0x10);
struct DeferredMsg
{
netadr_t addr;
unsigned char data[1400];
int datalen;
};
static_assert(sizeof(DeferredMsg) == 0x590);
struct DeferredQueue
{
DeferredMsg msgs[16];
volatile long get;
volatile long send;
};
static_assert(sizeof(DeferredQueue) == 0x5908);
#pragma endregion
#ifndef IDA