Skip to content
Browse files

fixed serverside exploid to fill the server. network protocol changed!

  • Loading branch information...
1 parent 4feff0e commit f1fca9b3ac4234a8da57ac478f90c5594f78d076 BotoX committed Jan 8, 2012
Showing with 134 additions and 30 deletions.
  1. +13 −0 src/engine/shared/network.h
  2. +79 −27 src/engine/shared/network_conn.cpp
  3. +42 −3 src/engine/shared/network_server.cpp
View
13 src/engine/shared/network.h
@@ -52,6 +52,7 @@ enum
NET_MAX_CONSOLE_CLIENTS = 4,
NET_MAX_SEQUENCE = 1<<10,
NET_SEQUENCE_MASK = NET_MAX_SEQUENCE-1,
+ NET_TOKENSEED_LENGTH = 8,
NET_CONNSTATE_OFFLINE=0,
NET_CONNSTATE_CONNECT=1,
@@ -169,6 +170,9 @@ class CNetConnection
void Resend();
public:
+ const char *m_CurTokenSeed;
+ const char *m_PrevTokenSeed;
+
void Init(NETSOCKET Socket);
int Connect(NETADDR *pAddr);
void Disconnect(const char *pReason);
@@ -183,6 +187,7 @@ class CNetConnection
void SignalResend();
int State() const { return m_State; }
NETADDR PeerAddress() const { return m_PeerAddr; }
+ void GenerateConnectToken(char *pToken, const char *Seed);
void ResetErrorString() { m_ErrorString[0] = 0; }
const char *ErrorString() const { return m_ErrorString; }
@@ -257,6 +262,8 @@ class CNetServer
{
public:
CNetConnection m_Connection;
+ // needed to call registerfuncs for new clients <- TODO: Fix this
+ bool m_Online;
};
struct CBan
@@ -279,6 +286,11 @@ class CNetServer
int m_MaxClients;
int m_MaxClientsPerIP;
+ // seeds for the connecttoken (new seed is generated every 10 seconds and is valid for 20 seconds)
+ char m_CurTokenSeed[NET_TOKENSEED_LENGTH];
+ char m_PrevTokenSeed[NET_TOKENSEED_LENGTH];
+ int64 m_LastTokenSeedGenerated;
+
CBan *m_aBans[256];
CBan m_BanPool[NET_SERVER_MAXBANS];
CBan *m_BanPool_FirstFree;
@@ -306,6 +318,7 @@ class CNetServer
//
int Drop(int ClientID, const char *pReason);
+ int Add(int ClientID);
// banning
int BanAdd(NETADDR Addr, int Seconds, const char *pReason);
View
106 src/engine/shared/network_conn.cpp
@@ -236,43 +236,80 @@ int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr)
}
else
{
- if(State() == NET_CONNSTATE_OFFLINE)
+ // If the connection isn't online always accept new connections
+ if(CtrlMsg == NET_CTRLMSG_CONNECT)
{
- if(CtrlMsg == NET_CTRLMSG_CONNECT)
- {
- // send response and init connection
- Reset();
- m_State = NET_CONNSTATE_PENDING;
- m_PeerAddr = *pAddr;
- m_LastSendTime = Now;
- m_LastRecvTime = Now;
- m_LastUpdateTime = Now;
- SendControl(NET_CTRLMSG_CONNECTACCEPT, 0, 0);
- if(g_Config.m_Debug)
- dbg_msg("connection", "got connection, sending connect+accept");
- }
+ // send response and init connection
+ Reset();
+ m_State = NET_CONNSTATE_PENDING;
+ m_PeerAddr = *pAddr;
+ m_LastSendTime = Now;
+ m_LastRecvTime = Now;
+ m_LastUpdateTime = Now;
+ char ConnectToken[2];
+ GenerateConnectToken(ConnectToken, m_CurTokenSeed);
+ SendControl(NET_CTRLMSG_CONNECTACCEPT, ConnectToken, 1);
+ if(g_Config.m_Debug)
+ dbg_msg("connection", "got connection, sending connect+accept");
}
- else if(State() == NET_CONNSTATE_CONNECT)
+ if(State() == NET_CONNSTATE_CONNECT)
{
if(CtrlMsg == NET_CTRLMSG_CONNECTACCEPT)
{
- // send accept and go online
- m_LastRecvTime = Now;
- SendControl(NET_CTRLMSG_ACCEPT, 0, 0);
- m_State = NET_CONNSTATE_ONLINE;
- if(g_Config.m_Debug)
- dbg_msg("connection", "got connect+accept, sending accept. connection online");
+ if(pPacket->m_DataSize > 1)
+ {
+ // send accept with token and go online in hope it gets accepted :o
+ m_LastRecvTime = Now;
+ char aBuf[2] = {(char)pPacket->m_aChunkData[1], 0};
+ m_State = NET_CONNSTATE_ONLINE;
+ SendControl(NET_CTRLMSG_ACCEPT, aBuf, 1);
+ if(g_Config.m_Debug)
+ dbg_msg("connection", "got connect+accept with token, sending accept with token.");
+ }
+ else
+ {
+ // send accept and go online
+ m_LastRecvTime = Now;
+ m_State = NET_CONNSTATE_ONLINE;
+ SendControl(NET_CTRLMSG_ACCEPT, 0, 0);
+ if(g_Config.m_Debug)
+ dbg_msg("connection", "got connect+accept, sending accept. connection online");
+ }
}
}
else if(State() == NET_CONNSTATE_PENDING)
{
if(CtrlMsg == NET_CTRLMSG_ACCEPT)
{
- // connection made
- m_LastRecvTime = Now;
- m_State = NET_CONNSTATE_ONLINE;
- if(g_Config.m_Debug)
- dbg_msg("connection", "got accept. connection online");
+ // update the peer address in case somebody is flooding the server with connect packets
+ m_PeerAddr = *pAddr;
+ if(pPacket->m_DataSize > 1)
+ {
+ char aBuf[2];
+ GenerateConnectToken(aBuf, m_CurTokenSeed);
+ if(aBuf[0] == (char)pPacket->m_aChunkData[1])
+ {
+ // connection made
+ m_LastRecvTime = Now;
+ m_State = NET_CONNSTATE_ONLINE;
+ if(g_Config.m_Debug)
+ dbg_msg("connection", "got accept. connection online");
+ }
+ else
+ {
+ // connecttoken wrong, drop the client
+ m_LastRecvTime = Now;
+ m_State = NET_CONNSTATE_ERROR;
+ SetError("Connection refused. Reason: Wrong connecttoken");
+ }
+ }
+ else
+ {
+ // no connecttoken received, drop the client
+ m_LastRecvTime = Now;
+ m_State = NET_CONNSTATE_ERROR;
+ SetError("Connection refused. Reason: No connecttoken, maybe you'r connecting with a old client");
+ }
}
}
}
@@ -287,6 +324,17 @@ int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr)
return 1;
}
+void CNetConnection::GenerateConnectToken(char *pToken, const char *Seed)
+{
+ NETADDR Tmp = m_PeerAddr;
+ char aBuf[NETADDR_MAXSTRSIZE+NET_TOKENSEED_LENGTH];
+ net_addr_str(&Tmp, aBuf, sizeof(aBuf));
+ str_append(aBuf, Seed, sizeof(aBuf));
+ char Hash = str_quickhash(aBuf);
+ pToken[0] = (char)Hash;
+ pToken[1] = '\0';
+}
+
int CNetConnection::Update()
{
int64 Now = time_get();
@@ -343,7 +391,11 @@ int CNetConnection::Update()
else if(State() == NET_CONNSTATE_PENDING)
{
if(time_get()-m_LastSendTime > time_freq()/2) // send a new connect/accept every 500ms
- SendControl(NET_CTRLMSG_CONNECTACCEPT, 0, 0);
+ {
+ char ConnectToken[2];
+ GenerateConnectToken(ConnectToken, m_CurTokenSeed);
+ SendControl(NET_CTRLMSG_CONNECTACCEPT, ConnectToken, 1);
+ }
}
return 0;
View
45 src/engine/shared/network_server.cpp
@@ -1,5 +1,6 @@
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
+#include <stdlib.h> // rand()
#include <base/system.h>
#include "network.h"
@@ -46,7 +47,12 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int
m_MaxClientsPerIP = MaxClientsPerIP;
for(int i = 0; i < NET_MAX_CLIENTS; i++)
+ {
m_aSlots[i].m_Connection.Init(m_Socket);
+ // setup pointers to tokenseeds
+ m_aSlots[i].m_Connection.m_CurTokenSeed = m_CurTokenSeed;
+ m_aSlots[i].m_Connection.m_PrevTokenSeed = m_PrevTokenSeed;
+ }
BanRemoveAll();
@@ -81,6 +87,17 @@ int CNetServer::Drop(int ClientID, const char *pReason)
m_pfnDelClient(ClientID, pReason, m_UserPtr);
m_aSlots[ClientID].m_Connection.Disconnect(pReason);
+ m_aSlots[ClientID].m_Online = false;
+
+ return 0;
+}
+
+int CNetServer::Add(int ClientID)
+{
+ if(m_pfnNewClient)
+ m_pfnNewClient(ClientID, m_UserPtr);
+
+ m_aSlots[ClientID].m_Online = true;
return 0;
}
@@ -260,11 +277,23 @@ int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char *pReason)
int CNetServer::Update()
{
int Now = time_timestamp();
+ if(m_LastTokenSeedGenerated+time_freq()*10 < time_get())
+ {
+ // generate new tokenseed and save the old one for slow clients
+ str_copy(m_PrevTokenSeed, m_CurTokenSeed, NET_TOKENSEED_LENGTH);
+ for(int i = 0; i < NET_TOKENSEED_LENGTH; i++)
+ m_CurTokenSeed[i] = 'A'+rand()%('z'-'A');
+ m_CurTokenSeed[NET_TOKENSEED_LENGTH-1] = '\0';
+ m_LastTokenSeedGenerated = time_get();
+ }
+
for(int i = 0; i < MaxClients(); i++)
{
m_aSlots[i].m_Connection.Update();
if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ERROR)
Drop(i, m_aSlots[i].m_Connection.ErrorString());
+ else if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ONLINE && !m_aSlots[i].m_Online)
+ Add(i);
}
// remove expired bans
@@ -390,12 +419,10 @@ int CNetServer::Recv(CNetChunk *pChunk)
for(int i = 0; i < MaxClients(); i++)
{
- if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_OFFLINE)
+ if(m_aSlots[i].m_Connection.State() != NET_CONNSTATE_ONLINE)
{
Found = 1;
m_aSlots[i].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr);
- if(m_pfnNewClient)
- m_pfnNewClient(i, m_UserPtr);
break;
}
}
@@ -407,6 +434,18 @@ int CNetServer::Recv(CNetChunk *pChunk)
}
}
}
+ else if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL && m_RecvUnpacker.m_Data.m_aChunkData[0] == NET_CTRLMSG_ACCEPT)
+ {
+ // accept packet, find a pending connection
+ for(int i = 0; i < MaxClients(); i++)
+ {
+ if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_PENDING)
+ {
+ m_aSlots[i].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr);
+ break;
+ }
+ }
+ }
else
{
// normal packet, find matching slot

0 comments on commit f1fca9b

Please sign in to comment.
Something went wrong with that request. Please try again.