private void LoadCommandsButton_click(object sender, EventArgs e) { // populate the CmdQueueListView with executors of the selected techniques var checkedTechniques = TechniqueListView.CheckedItems; CmdQueueListView.BeginUpdate(); CmdQueueListView.Clear(); CmdQueueListView.Columns.Add("Technique"); CmdQueueListView.Columns.Add("Command"); CmdQueueListView.View = View.Details; foreach (ListViewItem item in checkedTechniques) { string technique = item.SubItems[0].Text.ToString(); // e.g. "T1017" var thisAtomic = atomicRT.GetAtomicByTechnique(technique); List <string> executors = atomicRT.BuildWindowsExecutors(thisAtomic); // assembles the commands foreach (string executor in executors) { // add each command to the listview CmdQueueListView.Items.Add(new ListViewItem(new[] { technique, executor }) { Checked = true }); } } CmdQueueListView.Columns[0].Width = -2; CmdQueueListView.Columns[1].Width = -2; CmdQueueListView.EndUpdate(); ExecuteButton.Enabled = KillButton.Enabled; }
/// <summary> /// Begins the process of executing the commands that are "checked" in CmdQueueListView. <para/> /// Commands are sent to the remote computer via the PAExecService instance, and displayed in real time. /// </summary> private async void StartCmdQueue() { // because this is an asynchronous method, all access to the GUI thread (and its controls) must be through invokes. int numUnchecked = (int)CmdQueueListView.Invoke(new Func <int>(() => CmdQueueListView.Items.Count - CmdQueueListView.CheckedItems.Count)); while (shouldSendCommands && CmdQueueListView.Items.Count > numUnchecked) { // is the item at top (index 0) of the queue checked? bool isChecked = (bool)CmdQueueListView.Invoke(new Func <bool>(() => CmdQueueListView.Items[0].Checked)); if (isChecked) { CheckIfConsoleAllowsInput: string cmdText = (string)CmdOutput.Invoke(new Func <string>(() => CmdOutput.Text)); string endOfConsoleText = cmdText.Substring(cmdText.Length - Math.Min(10, cmdText.Length)); if (!endOfConsoleText.Contains('>')) { if (!shouldSendCommands) { break; } // stop endless loops if console dies await Task.Delay(1000); goto CheckIfConsoleAllowsInput; // check again after waiting } // send next command to the paexecService, remove from queue, then start over string nextCmd = (string)CmdQueueListView.Invoke(new Func <string>(() => CmdQueueListView.Items[0].SubItems[1].Text.ToString())); paexecService.WriteToClient(nextCmd.TrimEnd()); CmdQueueListView.Invoke(new Action(() => CmdQueueListView.Items.RemoveAt(0))); await Task.Delay(500); await Task.Run(() => StartCmdQueue()); } else { // if the command isn't checked, then move it to bottom of command queue CmdQueueListView.Invoke(new Action(() => CmdQueueListView.Items.Add((ListViewItem)CmdQueueListView.Items[0].Clone()))); CmdQueueListView.Invoke(new Action(() => CmdQueueListView.Items.RemoveAt(0))); } } shouldSendCommands = false; StopExecutingButton.Invoke(new Action(() => StopExecutingButton.Enabled = false)); }