Since there were some attacks going on last night on several servers abusing uninitialized CUser objects in CDPSrvr, I tried coming up with a fix for it. I just got it working when making my client spam the abused function every 100ms on login. Since it affects multiple servers, I want to share it. No guarantee this is a fix for it, but it worked for me. If you have suggestions about it or concerns, please post here or pm me.
IMPORTANT UPDATE:
This fix will NOT fully fix the attacks that were going on previously. This fix will only filter messages from invalid players sending packets.
The actual fix has been developed with a lot of outside help and in a group of 10 people.
The group in total has decided to not disclose any details as we invested a lot of time into it and simply don't want to share it with everyone out there.
Sharing a fix will also mean making servers that are not present on epvp vulnerable to the attack. We don't want that to happen.
The invalid user filter will stay on here, but nothing else will be disclosed.
Previous Updates:
User.h
below
add
below
add
User.cpp
add
in
add at the top of the function
In
replace
with
in
at the top of the function, add
DPDatabaseClient.cpp
In OnJoin replace
with
DPSrvr.cpp
In UserMessageHandler after GETTYPE( ar ) add
in OnAddUser
after
add
Consider removing the Errors since multiple logins may work server lag with too many calls. It's mostly for debugging purposes.
After adding that the error triggered twice when logging in local server. As said above, if you have concerns or suggestions on how to improve that code, post here or pm me.
Quick demonstration of the fix:
Contributions and suggestions made by:
Vladi#5038
Dylan#8888
kotori#0001
IMPORTANT UPDATE:
This fix will NOT fully fix the attacks that were going on previously. This fix will only filter messages from invalid players sending packets.
The actual fix has been developed with a lot of outside help and in a group of 10 people.
The group in total has decided to not disclose any details as we invested a lot of time into it and simply don't want to share it with everyone out there.
Sharing a fix will also mean making servers that are not present on epvp vulnerable to the attack. We don't want that to happen.
The invalid user filter will stay on here, but nothing else will be disclosed.
Previous Updates:
User.h
below
Code:
map<DWORD, CUser*> m_users;
Code:
map<DWORD, CUser*> m_invalid_users;
Code:
CUser* GetUser(DPID dpidCache, DPID dpidUser);
Code:
CUser* GetInvalidUser(DPID dpidUser);
add
Code:
CUser* CUserMng::GetInvalidUser(DPID dpidUser)
{
auto it = m_invalid_users.find(dpidUser);
if (it != m_invalid_users.end())
return it->second;
else
return nullptr;
}
in
Code:
CUserMng::AddPlayer
Code:
m_users.insert({ pUser->m_dwSerial, pUser });
m_invalid_users.erase(pUser->m_dwSerial);
Code:
CUserMng::AddUser
Code:
m_users.insert(std::make_pair(dpidUser, pUser));
Code:
m_invalid_users.insert({dpidUser, pUser});
Code:
CUserMng::RemoveUser
Code:
auto findInvalid = m_invalid_users.find(dwSerial);
if (findInvalid != m_invalid_users.end())
{
m_invalid_users.erase(findInvalid);
return;
}
In OnJoin replace
Code:
CUser* pUser = g_UserMng.GetUser( dpidCache, dpidUser );
Code:
CUser* pUser = g_UserMng.GetInvalidUser( dpidUser );
In UserMessageHandler after GETTYPE( ar ) add
Code:
CUser* pUser = g_UserMng.GetInvalidUser(*(UNALIGNED LPDPID)lpMsg);
if (pUser)
{
Error("Received Packet from Invalid user");
return;
}
after
Code:
if( nSlot >= 3 ) return;
Code:
CUser* pInvalidUser = g_UserMng.GetInvalidUser(dpidUser);
if (pInvalidUser)
{
Error("Invalid Connection Attempt UserID [%u]", idPlayer);
return;
}
After adding that the error triggered twice when logging in local server. As said above, if you have concerns or suggestions on how to improve that code, post here or pm me.
Quick demonstration of the fix:
|
|
Contributions and suggestions made by:
Vladi#5038
Dylan#8888
kotori#0001