void ShutdownClient(bool implantNotified = false) { status = (implantNotified) ? "closing (implant called close)" : "closing (SOCKS timeout)"; LastUpdateTime = DateTime.Now; //Set the reading flag to stop any further threads coming in _open = false; Interlocked.CompareExchange(ref CurrentlyReading, 1, 0); if (!ShutdownRecieved) { lock (_shutdownLocker) { if (!ShutdownRecieved) { ShutdownRecieved = true; if (null != _tc && _tc.Connected) { _tc.Close(); } if (!String.IsNullOrWhiteSpace(_targetId) && !implantNotified) { SocketComms.CloseTargetConnection(_targetId); } } } if (mapTargetIdToSocksInstance.ContainsKey(_targetId)) { mapTargetIdToSocksInstance.Remove(_targetId); } TimeoutEvent.Close(); } }
void CreateImplantSocksRequest() { ServerComms.LogMessage($"SOCKS Request to open {_targetHost}:{_targetPort}"); status = "opening"; LastUpdateTime = DateTime.Now; _targetId = SocketComms.CreateNewConnectionTarget(_targetHost, _targetPort); var thisptr = this; if (null == thisptr) { ServerComms.LogError("This pointer is NULL something wrong here"); } mapTargetIdToSocksInstance.TryAdd(_targetId, thisptr); }
void ShutdownClient(bool implantNotified = false) { status = (implantNotified) ? "closing (implant called close)" : "closing (SOCKS timeout)"; LastUpdateTime = DateTime.Now; _open = false; if (!ShutdownRecieved) { lock (_shutdownLocker) { if (!ShutdownRecieved) { ShutdownRecieved = true; if (null != _tc && _tc.Connected) { _tc.Close(); } if (!String.IsNullOrWhiteSpace(_targetId) && !implantNotified) { SocketComms.CloseTargetConnection(_targetId); } } } } if (mapTargetIdToSocksInstance.ContainsKey(_targetId)) { if (!mapTargetIdToSocksInstance.TryRemove(_targetId, out SocksProxy scks)) { ServerComms.LogError($"Couldn't mark {_targetId} as an invalid session"); } } if (null == TimeoutEvent) { TimeoutEvent.Close(); TimeoutEvent = null; } }
void ProxySocketReadCallback(IAsyncResult iar) { var asyncState = (AsyncBufferState)iar.AsyncState; try { var stream = asyncState.Stream; int bytesRead = stream.EndRead(iar); if (ShutdownRecieved || null == _tc) { return; } if (!_tc.Connected) { ShutdownClient(); try { if (_tc.Client != null) { ServerComms.LogError($"Connection to {_tc.Client.RemoteEndPoint.ToString()} closed"); } } catch (ObjectDisposedException) { ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} closed"); } return; } if (bytesRead > 0) { var payload = new List <byte>(); payload.AddRange(asyncState.Buffer.Take(bytesRead)); while (stream.CanRead && stream.DataAvailable) { if ((bytesRead = stream.Read(asyncState.Buffer, 0, HEADERLIMIT)) > 0) { payload.AddRange(asyncState.Buffer.Take(bytesRead)); } } SocketComms.SendDataToTarget(_targetId, payload); ServerComms.LogMessage($"Client sent data (size: {payload.Count}) {_targetId} writing to Implant"); _dataSent += payload.Count; } } catch (Exception ex) { try { if (_tc.Client != null) { ServerComms.LogError($"Connection to {_tc.Client.RemoteEndPoint.ToString()} has dropped cause {ex.Message}"); } } catch (ObjectDisposedException) { ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} has dropped cause {ex.Message}"); } ShutdownClient(); } finally { asyncState.RecvdData.Set(); } }
byte ProcessSocksHeaders(List <byte> buffer) { if (9 > buffer.Count || 256 < buffer.Count) { ServerComms.LogError($"Socks server: buffer size {buffer.Count} is not valid, must be between 9 & 256"); return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED); } byte version = buffer[0]; if (version == 0x4) { byte commandCode = buffer.Skip(1).Take(1).First(); BitConverter.ToUInt16(buffer.Skip(2).Take(2).ToArray(), 0); BitConverter.ToUInt16(buffer.Skip(2).Take(2).Reverse().ToArray(), 0); _targetPort = BitConverter.ToUInt16(buffer.Skip(2).Take(2).Reverse().ToArray(), 0); var dstIp = buffer.Skip(4).Take(4).ToArray(); var tailBuffer = buffer.Skip(8); var endUserIdx = tailBuffer.ToList().IndexOf(0x0) + 1; if (-1 == endUserIdx) { ServerComms.LogError($"User id is invalid rejecting connection request"); return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED); } var userId = UTF8Encoding.UTF8.GetString(tailBuffer.Take(endUserIdx).ToArray()); //Check if SOCKS 4a and domain name specified //If the domain name is to follow the IP will be in the format 0.0.0.x if (0 == dstIp[0] && 0 == dstIp[1] && 0 == dstIp[2] && 0 != dstIp[3]) { var endHostIdx = tailBuffer.Skip(endUserIdx).ToList().IndexOf(0x0); var arrayHost = tailBuffer.Skip(endUserIdx).Take(endHostIdx).ToArray(); if (arrayHost.Length == 0) { ServerComms.LogError($"Host name is empty rejecting connection request"); return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED); } var dnsHost = UTF8Encoding.UTF8.GetString(arrayHost); if (UriHostNameType.Unknown == Uri.CheckHostName(dnsHost)) { ServerComms.LogError($"Host name {dnsHost} is invalid rejecting connection request"); return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED); } _targetHost = dnsHost; } else { _targetHost = new IPAddress(BitConverter.ToUInt32(dstIp, 0)).ToString(); } ServerComms.LogMessage($"SOCKS Request to open {_targetHost}:{_targetPort}"); status = "opening"; LastUpdateTime = DateTime.Now; _targetId = SocketComms.CreateNewConnectionTarget(_targetHost, _targetPort); var thisptr = this; if (null == thisptr) { ServerComms.LogError("This pointer is NULL something wrong here"); } mapTargetIdToSocksInstance.Add(_targetId, thisptr); if (_waitOnConnect) { SocksTimeout.WaitOne(SOCKSCONNECTIONTOOPENTIMEOUT); if (!_open) { return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED); } } } else { return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED); } ServerComms.LogMessage($"Opened SOCKS port {_targetHost}:{_targetPort} targetid {_targetId}"); return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_GRANTED); }
void ProxySocketReadCallback(IAsyncResult iar) { var asyncState = (AsyncBufferState)iar.AsyncState; var stream = asyncState.Stream; int bytesRead = 0; if (ShutdownRecieved || null == _tc) { return; } if (!_tc.Connected) { ShutdownClient(); try { if (_tc.Client != null) { ServerComms.LogError($"Connection to {_tc.Client.RemoteEndPoint.ToString()} closed"); } } catch (ObjectDisposedException) { ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} closed"); } return; } try { bytesRead = stream.EndRead(iar); _dataSent += bytesRead; if (bytesRead > 0) { var payload = new List <byte>(); payload.AddRange(asyncState.Buffer.Take(bytesRead)); Array.Clear(asyncState.Buffer, 0, asyncState.Buffer.Length); while (stream.CanRead && stream.DataAvailable && (bytesRead = stream.Read(asyncState.Buffer, 0, HEADERLIMIT)) > 0) { payload.AddRange(asyncState.Buffer.Take(bytesRead)); Array.Clear(asyncState.Buffer, 0, asyncState.Buffer.Length); } //Not currently reading now so if anything comes in fair play Interlocked.Decrement(ref CurrentlyReading); ServerComms.LogMessage($"Client sent data (size: {payload.Count}) {_targetId} writing to Implant"); SocketComms.SendDataToTarget(_targetId, payload); StartCommsWithProxyAndImplant(asyncState.Stream); } else { //No bytes have been read from the connection //Try again and start the thread timeout cycle Interlocked.Decrement(ref CurrentlyReading); TimeoutEvent.WaitOne(timeout); StartCommsWithProxyAndImplant(asyncState.Stream); } } catch (Exception ex) { try { if (_tc.Client != null) { ServerComms.LogError($"Connection to {_tc.Client.RemoteEndPoint.ToString()} has dropped cause {ex.Message}"); } } catch (ObjectDisposedException) { ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} has dropped cause {ex.Message}"); } ShutdownClient(); } }