Any hint about where i should fix this class !
Code:
sealed class DownloadContext
{
Socket m_ClientSocket = null;
AsyncServer.E_ServerType m_HandlerType;
AsyncServer.delClientDisconnect m_delDisconnect;
object m_Lock = new object();
Socket m_ModuleSocket = null;
// New buffers
byte[] m_LocalBuffer = new byte[8192];
byte[] m_RemoteBuffer = new byte[8192];
Security m_LocalSecurity = new Security();
Security m_RemoteSecurity = new Security();
Thread m_TransferPoolThread = null;
ulong m_BytesRecvFromClient = 0;
DateTime m_StartTime = DateTime.Now;
// Module name
string module_name = "DOWNLOAD";
bool packet_handler = false;
// User information
string user_id="";
// Packet
int packetCount = 0;
Timer packet_timer = null;
int length = 0;
// User IP
string ip = string.Empty;
// Locker :D
public static object locker = new object();
#region COUNT_IP
// Count IP list
public static int ip_count(string ip)
{
lock (locker)
{
try
{
int count_ip = 0;
foreach (string ips in MainForm.Ip_List)
{
if (ips == ip)
{
count_ip++;
}
}
return count_ip + 1;
}
catch
{
return 0;
}
}
}
#endregion
public DownloadContext(Socket ClientSocket, AsyncServer.delClientDisconnect delDisconnect)
{
this.m_delDisconnect = delDisconnect;
this.m_ClientSocket = ClientSocket;
this.m_HandlerType = AsyncServer.E_ServerType.DownloadServer;
this.m_ModuleSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Register ip
this.ip = ((IPEndPoint)(m_ClientSocket.RemoteEndPoint)).Address.ToString();
// download count
MainForm.Download++;
// GLOBAL IP LIST
MainForm.Ip_List.Add(this.ip);
#region BAN LIST / BAN SYSTEM
if (MainForm.Ban_List.Contains(this.ip))
{
// Disconnect
this.DisconnectModuleSocket();
return;
}
#endregion
#region FLOOD_PROTECTION
if (MainForm.ENABLE_FLOOD_PROTECT)
{
if (ip_count(this.ip) > MainForm.FLOOD_LIMIT)
{
MainForm.SUSPECT++;
// IF BAN IP?
if (MainForm.FLOOD_ACTION == "BAN")
{
if (!MainForm.Ban_List.Contains(this.ip))
{
// Add ban
FirewallHandler.BlockIP(this.ip, "flood");
MainForm.Ban_List.Add(this.ip);
try
{
// File exist, write to it.
System.IO.StreamWriter file = new System.IO.StreamWriter("config/blacklist.txt", true);
if (this.ip.Length > 0)
{
file.WriteLine(this.ip + "\n");
}
file.Close();
// Ban log(For checking random bans)
System.IO.StreamWriter banlog = new System.IO.StreamWriter("logs/banlog.txt", true);
banlog.WriteLine("[" + DateTime.Now + "] {" + this.module_name + "} Banned {" + this.ip + "} Reason: {FLOOD ATTEMPT}\n");
banlog.Close();
}
catch { }
MainForm.WriteLine(2, "[" + this.module_name + "] IP:{" + this.ip + "} User:{" + this.user_id + "} Reason:{FLOODING} Bytes:{" + this.length + "} Packet_c{" + this.packetCount + "}");
}
}
// Disconnect
this.DisconnectModuleSocket();
return;
}
}
#endregion
try
{
this.m_ModuleSocket.Connect(new IPEndPoint(IPAddress.Parse(MainForm.PUBLIC_DOWNLOAD_IP), MainForm.PRI_DOWNLOAD_PORT));
this.m_LocalSecurity.GenerateSecurity(true, true, true);
this.DoRecvFromClient();
Send(false);
}
catch { }
#region PACKET_TIMER_START
if (this.packet_timer == null)
{
this.packet_timer = new Timer(new TimerCallback(this.resetPackets), null, 0, 500);
}
#endregion
// Mike pro :3
//this.sent_id = 0;
//this.sent_list = 0;
//this.patch_sent = 0;
}
double GetBytesPerSecondFromClient()
{
double res = 0.0;
TimeSpan diff = (DateTime.Now - m_StartTime);
if (m_BytesRecvFromClient > int.MaxValue)
m_BytesRecvFromClient = 0;
if (m_BytesRecvFromClient > 0)
{
try
{
unchecked
{
double div = diff.TotalSeconds;
if (diff.TotalSeconds < 1.0)
div = 1.0;
res = Math.Round((m_BytesRecvFromClient / div), 2);
}
}
catch
{
}
}
return res;
}
void DisconnectModuleSocket()
{
try
{
if (this.m_ModuleSocket != null)
{
// Download count
if (MainForm.Download > 0)
{
MainForm.Download--;
}
// GLOBAL IP LIST / FLOOD IP LIST
MainForm.Ip_List.Remove(this.ip);
if (this.packet_timer != null)
{
this.packet_timer.Dispose();
this.packet_timer = null;
}
// DISCONNECT
this.m_ModuleSocket.Close();
}
// NULL
this.m_ModuleSocket = null;
}
catch { }
}
void OnReceive_FromServer(IAsyncResult iar)
{
lock (m_Lock)
{
try
{
int nReceived = m_ModuleSocket.EndReceive(iar);
if (nReceived != 0)
{
this.m_RemoteSecurity.Recv(m_RemoteBuffer, 0, nReceived);
List<Packet> RemotePackets = m_RemoteSecurity.TransferIncoming();
if (RemotePackets != null)
{
foreach (Packet _pck in RemotePackets)
{
#region 0x5000_0x9000_HANDSHAKE
// Handshake
if (_pck.Opcode == 0x5000 || _pck.Opcode == 0x9000)
{
Send(true);
continue;
}
#endregion
#region 0xA100_DOWNLOAD
else if (_pck.Opcode == 0xa100 )
{
byte result = _pck.ReadUInt8();
if (result == 0x02)
{
byte ErrorCode = _pck.ReadUInt8();
if (ErrorCode == 0x02)
{
string ip = _pck.ReadAscii(); // ServerIP
ushort port = _pck.ReadUInt16(); // ServerPort
UInt32 version = _pck.ReadUInt32(); // Version
byte flag = _pck.ReadUInt8(); // Flag
Packet spoof = new Packet(0xA100, false, true);
spoof.WriteUInt8(result);
spoof.WriteUInt8(ErrorCode);
spoof.WriteAscii(MainForm.PROXY_IP); // Spoofing part
spoof.WriteUInt16(MainForm.PUBLIC_DOWNLOAD_PORT); // Spoofing part
spoof.WriteUInt32(version); // Version
spoof.WriteUInt8(flag);
while (flag == 0x01)
{
UInt32 FileID = _pck.ReadUInt32();
string FileName = _pck.ReadAscii();
string FilePath = _pck.ReadAscii();
UInt32 FileLen = _pck.ReadUInt32();
byte unk = _pck.ReadUInt8(); // Packed, no idea.
flag = _pck.ReadUInt8();
spoof.WriteUInt32(FileID);
spoof.WriteAscii(FileName);
spoof.WriteAscii(FilePath);
spoof.WriteUInt32(FileLen);
spoof.WriteUInt8(unk);
spoof.WriteUInt8(flag);
}
m_LocalSecurity.Send(spoof);
Send(false);
continue;
}
}
}
#endregion
}
}
}
else
{
try
{
// Abort connection
this.DisconnectModuleSocket();
this.m_TransferPoolThread.Abort();
}
catch { }
this.m_delDisconnect.Invoke(ref m_ClientSocket, m_HandlerType);
return;
}
DoRecvFromServer();
}
catch (Exception)
{
try
{
// Abort connection
this.DisconnectModuleSocket();
this.m_TransferPoolThread.Abort();
}
catch { }
this.m_delDisconnect.Invoke(ref m_ClientSocket, m_HandlerType);
return;
}
}
}
public void Send(bool ToHost)
{
lock (m_Lock)
foreach (var p in (ToHost ? m_RemoteSecurity : m_LocalSecurity).TransferOutgoing())
{
Socket ss = (ToHost ? m_ModuleSocket : m_ClientSocket);
ss.Send(p.Key.Buffer);
if (ToHost)
{
try
{
m_BytesRecvFromClient += (ulong)p.Key.Size;
double nBps = GetBytesPerSecondFromClient();
if (nBps > MainForm.GATEWAY_BYTES_PER_SECOND)
{
MainForm.SUSPECT++;
MainForm.Ban_List.Add(this.ip);
FirewallHandler.BlockIP(this.ip, "nBps count");
MainForm.WriteLine(2, "[" + this.module_name + "] IP:{" + this.ip + "} User:{" + this.user_id + "} has ban. Reason: Flood");
try
{
// Abort connection
this.DisconnectModuleSocket();
this.m_TransferPoolThread.Abort();
}
catch { }
this.m_delDisconnect.Invoke(ref m_ClientSocket, m_HandlerType);
return;
}
}
catch
{
try
{
// Abort connection
this.DisconnectModuleSocket();
this.m_TransferPoolThread.Abort();
}
catch { }
this.m_delDisconnect.Invoke(ref m_ClientSocket, m_HandlerType);
return;
}
}
}
}
void resetPackets(object e)
{
try
{
if (this.packetCount > MainForm.GATEWAY_PACKET_PER_SECOND)
{
MainForm.SUSPECT++;
if (MainForm.PACKET_ACTION == "BAN")
{
if (!MainForm.Ban_List.Contains(this.ip))
{
// Add ban
MainForm.Ban_List.Add(this.ip);
MainForm.WriteLine(2, "[" + this.module_name + "] IP:{" + this.ip + "} was kicked for exceeding packet limit/second");
FirewallHandler.BlockIP(this.ip, "exploit");
try
{
// File exist, write to it.
System.IO.StreamWriter file = new System.IO.StreamWriter("config/blacklist.txt", true);
if (this.ip.Length > 0)
{
file.WriteLine(this.ip + "\n");
}
file.Close();
// Ban log(For checking random bans)
System.IO.StreamWriter banlog = new System.IO.StreamWriter("logs/banlog.txt", true);
banlog.WriteLine("[" + DateTime.Now + "] {" + this.module_name + "} Banned {" + this.ip + "} Reason: {HIGH PPS}\n");
banlog.Close();
}
catch { }
}
}
this.DisconnectModuleSocket();
return;
}
}
catch { }
this.packetCount = 0;
}
void OnReceive_FromClient(IAsyncResult iar)
{
lock (m_Lock)
{
try
{
int nReceived = m_ClientSocket.EndReceive(iar);
if (nReceived != 0)
{
m_LocalSecurity.Recv(m_LocalBuffer, 0, nReceived);
List<Packet> ReceivedPackets = m_LocalSecurity.TransferIncoming();
if (ReceivedPackets != null)
{
foreach (Packet _pck in ReceivedPackets)
{
//MainForm.WriteConsole(2, $"Agent: Client send opcode({ _pck.Opcode:X4})");
this.length = _pck.GetBytes().Length;
// Packet count
this.packetCount++;
this.packet_handler = true;
#region NEW_EXPLOIT_FIX
if (MainForm.Server_Opcodes_Gateway.Contains(_pck.Opcode))
{
Send(false);
continue;
}
#endregion
#region 0x5000_0x9000_IGNORE_HANDSHAKE
// Ignore handshake
if (_pck.Opcode == 0x5000 || _pck.Opcode == 0x9000)
{
this.packet_handler = false;
Send(false);
continue;
}
#endregion
#region 0x2001_CLIENT_FLOOD_PROTECTION
else if (_pck.Opcode == 0x2001)
{
this.packet_handler = false;
// Recieve
this.DoRecvFromServer();
// K-guard
if (this.length != 12)
{
MainForm.SUSPECT++;
MainForm.WriteLine(2, $"ExClient({this.ip}:{this.user_id}) tried to exploit 0x2001");
this.DisconnectModuleSocket();
return;
}
Send(false);
continue;
}
#endregion
#region OPCODE_HANDLER
if (this.packet_handler)
{
#region OPCODE HANDLER
if (MainForm.Bad_Opcodes.ContainsKey(_pck.Opcode))
{
MainForm.SUSPECT++;
if (MainForm.EXPLOIT_ACTION == "BAN")
{
if (!MainForm.Ban_List.Contains(this.ip))
{
MainForm.Ban_List.Add(this.ip);
try
{
// File exist, write to it.
System.IO.StreamWriter file = new System.IO.StreamWriter("config/blacklist.txt", true);
if (this.ip.Length > 0)
{
file.WriteLine(this.ip + "\n");
}
file.Close();
// Ban log(For checking random bans)
System.IO.StreamWriter banlog = new System.IO.StreamWriter("logs/banlog.txt", true);
banlog.WriteLine("[" + DateTime.Now + "] {" + this.module_name + "} Banned {" + this.ip + "} Reason: {EXPLOITING}\n");
banlog.Close();
}
catch { }
MainForm.WriteLine(2, "[" + this.module_name + "] IP:{" + this.ip + "} User:{" + this.user_id + "} Opcode:{0x" + _pck.Opcode.ToString("X") + "} has ban. Reason: {Exploit}");
}
}
this.DisconnectModuleSocket();
return;
}
#endregion
}
#endregion
// Send packets
m_RemoteSecurity.Send(_pck);
Send(true);
}
}
}
else
{
try
{
// Abort connection
this.DisconnectModuleSocket();
this.m_TransferPoolThread.Abort();
}
catch { }
this.m_delDisconnect.Invoke(ref m_ClientSocket, m_HandlerType);
return;
}
this.DoRecvFromClient();
}
catch
{
try
{
// Abort connection
this.DisconnectModuleSocket();
this.m_TransferPoolThread.Abort();
}
catch { }
this.m_delDisconnect.Invoke(ref m_ClientSocket, m_HandlerType);
return;
}
}
}
void DoRecvFromServer()
{
try
{
this.m_ModuleSocket.BeginReceive(m_RemoteBuffer, 0, m_RemoteBuffer.Length,
SocketFlags.None,
new AsyncCallback(OnReceive_FromServer), null);
}
catch
{
try
{
// Abort connection
this.DisconnectModuleSocket();
this.m_TransferPoolThread.Abort();
}
catch { }
this.m_delDisconnect.Invoke(ref m_ClientSocket, m_HandlerType);
return;
}
}
void DoRecvFromClient()
{
try
{
this.m_ClientSocket.BeginReceive(m_LocalBuffer, 0, m_LocalBuffer.Length,
SocketFlags.None,
new AsyncCallback(OnReceive_FromClient), null);
}
catch
{
try
{
// Abort connection
this.DisconnectModuleSocket();
this.m_TransferPoolThread.Abort();
}
catch { }
this.m_delDisconnect.Invoke(ref m_ClientSocket, m_HandlerType);
return;
}
}
}
}






