using System.Security.Cryptography; using System.Text; using MassTransit.Mediator; using Microsoft.Extensions.Logging; using NetCoreServer; namespace Server; public abstract class AuthSession : TcpSession { private readonly ILogger _logger; private readonly IMediator _mediator; private static readonly byte[] Key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7 } .Reverse().ToArray(); private static readonly byte[] IV = new byte[] { 0xfe, 220, 0xba, 0x98, 0x76, 0x54, 50, 0x10, 15, 30, 0x2d, 60, 0x4b, 90, 0x69, 120 }.Reverse().ToArray(); private readonly ICryptoTransform _encryptor; private readonly ICryptoTransform _decryptor; protected AuthSession(TcpServer server, ILogger logger, IMediator mediator) : base(server) { _logger = logger; _mediator = mediator; var aes = Aes.Create(); aes.Key = Key; aes.IV = IV; aes.Padding = PaddingMode.None; aes.Mode = CipherMode.ECB; _decryptor = aes.CreateDecryptor(aes.Key, aes.IV); _encryptor = aes.CreateEncryptor(aes.Key, aes.IV); } public override long Send(byte[] buffer) { byte[] encryptedBuffer; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, _encryptor, CryptoStreamMode.Write)) { cs.Write(buffer); cs.FlushFinalBlock(); encryptedBuffer = ms.ToArray(); } return base.Send(encryptedBuffer); } public override long Send(byte[] buffer, long offset, long size) { byte[] encryptedBuffer; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, _encryptor, CryptoStreamMode.Write)) { cs.Write(buffer, (int)offset, (int)size); cs.FlushFinalBlock(); encryptedBuffer = ms.ToArray(); } return base.Send(encryptedBuffer, 0, encryptedBuffer.Length); } public override long Send(ReadOnlySpan buffer) { Span encryptedBuffer; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, _encryptor, CryptoStreamMode.Write)) { cs.Write(buffer); cs.FlushFinalBlock(); encryptedBuffer = ms.ToArray(); } return base.Send(encryptedBuffer); } public override bool SendAsync(byte[] buffer) { byte[] encryptedBuffer; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, _encryptor, CryptoStreamMode.Write)) { cs.Write(buffer); cs.FlushFinalBlock(); encryptedBuffer = ms.ToArray(); } return base.SendAsync(encryptedBuffer); } public override bool SendAsync(byte[] buffer, long offset, long size) { byte[] encryptedBuffer; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, _encryptor, CryptoStreamMode.Write)) { cs.Write(buffer, (int)offset, (int)size); cs.FlushFinalBlock(); encryptedBuffer = ms.ToArray(); } return base.SendAsync(encryptedBuffer, 0, encryptedBuffer.Length); } public override bool SendAsync(ReadOnlySpan buffer) { Span encryptedBuffer; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, _encryptor, CryptoStreamMode.Write)) { cs.Write(buffer); cs.FlushFinalBlock(); encryptedBuffer = ms.ToArray(); } return base.SendAsync(encryptedBuffer); } public override long Receive(byte[] buffer) { Span decryptedBuffer; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, _decryptor, CryptoStreamMode.Write)) { cs.Write(buffer); cs.FlushFinalBlock(); decryptedBuffer = ms.ToArray(); } return base.Receive(decryptedBuffer.ToArray()); } public override long Receive(byte[] buffer, long offset, long size) { byte[] decryptedBuffer; using (var ms = new MemoryStream()) using (var cs = new CryptoStream(ms, _decryptor, CryptoStreamMode.Write)) { cs.Write(buffer, (int)offset, (int)size); cs.FlushFinalBlock(); decryptedBuffer = ms.ToArray(); } return base.Receive(decryptedBuffer, 0, decryptedBuffer.Length); } protected override void OnReceived(byte[] buffer, long offset, long size) { try { Console.WriteLine($"Length: {size} & offset: {offset}"); //Console.WriteLine(BitConverter.ToString(buffer.ToArray()).Replace("-", string.Empty)); Span decryptedBuffer = new byte[size]; // xor every value after the first 8 bytes // then apply AES decryption var dataBuffer = Decrypt(new ArraySegment(buffer, 8, (int)size - 8).ToArray()); /*using (var ms = new MemoryStream(dataBuffer)) using (var cs = new CryptoStream(ms, _decryptor, CryptoStreamMode.Read)) { cs.Read(decryptedBuffer); }*/ Console.WriteLine("Length " + BitConverter.ToUInt16(buffer, 0)); var opCode = BitConverter.ToUInt16(buffer.ToArray(), 2); Console.WriteLine("Packet Op Code: " + opCode); Console.WriteLine("Some Value: " + buffer[4]); /* * 20s = 5 * 15s = 4 * 10s = 3 * * client alive time * 5s => uptime */ var clientAliveTime = BitConverter.ToUInt16(buffer.ToArray(), 5); Console.WriteLine("Client Alive time: " + clientAliveTime); Console.WriteLine("Might be a flag:" + buffer[7]); Console.WriteLine("username: " + Encoding.ASCII.GetString(dataBuffer.ToArray(), 0, 20)); Console.WriteLine("password: " + Encoding.ASCII.GetString(dataBuffer.ToArray(), 20, 32)); Console.WriteLine("Full buffer: " + Encoding.ASCII.GetString(dataBuffer.ToArray())); RawPacket rawPacket = new RawPacket((OperationCode)opCode, dataBuffer, clientAliveTime, buffer[0], buffer[3], Id, this); Parallel.Invoke(() => _mediator.Send(rawPacket)); _logger.LogInformation("Connection from: {@RemoteEndpoint}", Socket.RemoteEndPoint?.ToString()); base.OnReceived(decryptedBuffer.ToArray(), offset, decryptedBuffer.Length); } catch (CryptographicException ex) { _logger.LogError("An error has occured while decrypting: {ErrorMessage}", ex.Message); _logger.LogError("Default buffer message: {Message}", Encoding.ASCII.GetString(buffer)); } } private byte[] Decrypt(byte[] buffer) { for (int i = 0; i < buffer.Length; ++i) { buffer[i] = (byte)(buffer[i] ^ i ^ (3 * (0xFE - i))); } return buffer; } }