Solved

HIdden telnet session

Posted on 2003-12-03
20
2,782 Views
Last Modified: 2012-06-27
Does anyone know of a way to create a telnet session and pass commands to it the scenes. Basically I want my application to login to a telnet server, login and then execute a few simple commands without the user knowing whats going on. Does anybody know how to do this.
0
Comment
Question by:andyk1
  • 9
  • 6
  • 2
  • +2
20 Comments
 
LVL 22

Expert Comment

by:_TAD_
ID: 9869703


Here is something I've used for ping....  telnet can be done the same way

            private void DOSCommand()
            {            
                  Process myDosCmd = null;
                  ProcessStartInfo qOptions = new ProcessStartInfo("cmd.exe", @"/C ping pc-02-49");
                  qOptions.WindowStyle = ProcessWindowStyle.Hidden;
                  qOptions.RedirectStandardOutput = true;  // set to "true" to enable logging
                  qOptions.UseShellExecute = false;  // set to true to make silent/background
                  
                  myDosCmd = Process.Start(qOptions);
                  myDosCmd.WaitForExit();
                  
                  //Logging commands, cannot be used in "silent" mode
                  string dosOut = myDosCmd.StandardOutput.ReadToEnd();
                  Console.Write(dosOut);
            }
0
 
LVL 22

Expert Comment

by:_TAD_
ID: 9869738

using System.Diagnostics




This will create a telnet session on my computer

               ProcessStartInfo qOptions = new ProcessStartInfo("cmd.exe", @"/C telnet pc-02-49");
0
 

Author Comment

by:andyk1
ID: 9870655
I have got that far, from a previous post from yourself. however,how I do keep this connection and then login, and enter commands.
0
 
LVL 22

Expert Comment

by:_TAD_
ID: 9870783


When starting a process it only allows for 1 command and its arguments.  Therefore if you want to use multiple commands you need to create a batch process in order to run a series of commands.


The good news is that you can create a batch process on the fly, and then kill it when you are done:


            private void DOSCommand()
            {      
                  StreamWriter sw = new StreamWriter(@"C:\test.bat");
                  sw.WriteLine(@"ping pc-02-49");
                  sw.WriteLine(@"dir C:\");
                  sw.Flush();
                  sw.Close();

                  Process myDosCmd = null;
                  ProcessStartInfo qOptions = new ProcessStartInfo("cmd.exe", @"/C C:\test.bat");
                  qOptions.WindowStyle = ProcessWindowStyle.Hidden;
                  qOptions.RedirectStandardOutput = true;  // set to "true" to enable logging
                  qOptions.UseShellExecute = false;  // set to true to make silent/background
                  
                  myDosCmd = Process.Start(qOptions);
                  myDosCmd.WaitForExit();
                  
                  //Logging commands, cannot be used in "silent" mode
                  string dosOut = myDosCmd.StandardOutput.ReadToEnd();
                  Console.Write(dosOut);

                  File.Delete(@"C:\test.bat");
            }



Notice that I added 6 new lines of code.  The first 5 lines, plus the last line.

My process object still only executes a single command "cmd.exe" and it's command line arguments "/c Prog.bat"

Only this time, the arguments point to a small dos program.


I hope this helps.
0
 

Author Comment

by:andyk1
ID: 9870880
That was a great idea. Although do you know how to write a batch cript that will connect to a telnet session

I tried
@echo off
telnet 127.0.0.1
echo administrator
echo mypassword

Any idea?
0
 
LVL 22

Expert Comment

by:_TAD_
ID: 9871024


Actually I have only used telnet once in my life... so Iam not very familiar with it.

However, the "echo" command I believe only displays the parameter to the screen.  I'm not entirely sure that it actually executes that command (although it should).


I've looked through a few websites trying to find batch programs that run telnet from within them and I haven't found anything usefull yet...


I'll keep looking, and I'll let you know.
0
 

Author Comment

by:andyk1
ID: 9871059
Thanks, I am looking myself. I was trying to find if I could send parameters using .Net with any Process members but had no luck either.
0
 

Author Comment

by:andyk1
ID: 9871593
I have a telnet server running on my machine. I have looked at various other methods and have tried this.

string dosOut;
Process myDosCmd = null;
ProcessStartInfo qOptions = new ProcessStartInfo("telnet.exe");
qOptions.RedirectStandardOutput = true;
qOptions.RedirectStandardInput = true;
qOptions.UseShellExecute = false;  
qOptions.WindowStyle = ProcessWindowStyle.Hidden;
myDosCmd = Process.Start(qOptions);                  
StreamWriter sw2;
StreamReader sr;            
sr = myDosCmd.StandardOutput;
sw2 = myDosCmd.StandardInput;
sw2.AutoFlush = true;
sw2.WriteLine("open 127.0.0.1");                  
sw2.WriteLine("administrator");
sw2.WriteLine("password");
//sw2.WriteLine("dir");
dosOut = sr.ReadToEnd();
myDosCmd.WaitForExit();
myDosCmd=null;

I don;t know where I am going wrong.
0
 
LVL 22

Expert Comment

by:_TAD_
ID: 9875578


Got it!!


(well... sorta)

Just copy and paste this function as is and you will get a telnet session started, and attempt to log in.  Since I don't have a pop3 mail account here it wil fail, but at least you can see everything gets typed in to the proper place.

by the way... the carriage return "\n"  MUST be in its own separate line... I don't know why, but it doesn't work otherwise.


            private void DOSCommand()
            {      
                  Process myDosCmd = null;
                  ProcessStartInfo qOptions = new ProcessStartInfo("cmd.exe", @"/C telnet mail.plus.net 110");
                  qOptions.WindowStyle = ProcessWindowStyle.Hidden;
                  qOptions.RedirectStandardOutput = false;  // set to "true" to enable logging
                  
                  qOptions.UseShellExecute = false;  // set to true to make silent/background
                  
                  myDosCmd = Process.Start(qOptions);
                  
                  if(myDosCmd.Responding)
                  {
                        SendKeys.SendWait("user tad");
                        SendKeys.SendWait("\n");
                        SendKeys.SendWait("pass tad");
                        SendKeys.SendWait("\n");
                        SendKeys.SendWait("quit");
                        SendKeys.SendWait("\n");
                  }
                  
                  myDosCmd.WaitForExit();
            }
0
 

Author Comment

by:andyk1
ID: 9876644
Ok that works, sort off.

Process myDosCmd = null;
ProcessStartInfo qOptions = new ProcessStartInfo("cmd.exe", @"/C telnet 127.0.0.1");
qOptions.WindowStyle = ProcessWindowStyle.Hidden;
qOptions.RedirectStandardOutput = false;  // set to "true" to enable logging
           
qOptions.UseShellExecute = false;  // set to true to make silent/background
               
myDosCmd = Process.Start(qOptions);
               
if(myDosCmd.Responding)
{
     SendKeys.SendWait("administrator");
     SendKeys.SendWait("{ENTER}");
     SendKeys.SendWait("password");
     SendKeys.SendWait("{ENTER}");
     SendKeys.SendWait("dir");
     SendKeys.SendWait("{ENTER}");
}
myDosCmd.WaitForExit();

This will create  a telnet session but if I try to RedirectStandardInput or Ouptut I get an exception saying that the process  has exited. in the above code, it logs on to the telnet session, which is great but doesn't pass in the "dir" command. The code I was trying earlier with :
sw2.WriteLine("password"); etc.
seems to be the way to do it. Another post used this code in VB.Net to log into an FTP server.

0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 22

Expert Comment

by:_TAD_
ID: 9876786


Normally I would agree... write a stream out to the process is the way to go.

However.... telnet seems to create its own process to run in (or something...??)

When I replace the Telnet commands with ftp, everything works perfectly (using the streamWriter method).

The problem really is with telnet, or rather... lack of understanding of telnet.

:-(

I'll keep working on it.




0
 

Author Comment

by:andyk1
ID: 9878117
CHeers, it is wrecking my head. Have been at it non-stop now for too long.
0
 
LVL 6

Expert Comment

by:martinv
ID: 9900351
What about using one of .NET telnet libaries?

C# TELNET Client
http://www.csharphelp.com/archives/archive239.html

Telnet Scripting in C#
http://www.c-sharpcorner.com/Code/2003/Jan/TelnetScripting.asp
0
 

Author Comment

by:andyk1
ID: 9907260
tried the telnet scripting but no luck
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 9947989
Trying to control some other telnet program is always going to be a pain.
I think you should bite the bullet here and do the socket programming.
You just need to make a connection to port 23 on the remote server and then write to and read from the socket.
0
 
LVL 15

Accepted Solution

by:
SRigney earned 125 total points
ID: 9952629
ozymandias it's not as easy as just opening a socket and talking to port 23.  Telnet expects a bunch of additional comminication characters embeded in the transmission.

I tried both of the same chunks of code previously.  Neither of them worked for me.

The following link is a link to Telnet specs.  Numer 854 through 861 specifically refer to telnet as do several others
http://www.armware.dk/RFC/rfc/index801.html#854

Here is the class that I wrote.  It does not handle everything yet, but it worked for what I needed.  There are still issues with this.  And I don't deserve all of the credit.  I stole what someone else had written, but I can't find the original to give partial credit where it is due.

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;


namespace TestTelnet
{
      public class Telnet
      {
            Char IAC                        = Convert.ToChar(255);
            Char DO                              = Convert.ToChar(253);
            Char DONT                        = Convert.ToChar(254);
            Char WILL                        = Convert.ToChar(251);
            Char WONT                        = Convert.ToChar(252);
            Char SB                              = Convert.ToChar(250);
            Char SE                              = Convert.ToChar(240);
            const      Char IS                  = '0';
            const      Char SEND            = '1';
            const      Char INFO            = '2';
            const      Char VAR            = '0';
            const      Char VALUE            = '1';
            const      Char ESC            = '2';
            const      Char USERVAR      = '3';

            private ArrayList mListOptions = new ArrayList();
            private IPEndPoint iep ;
            private string m_address ;
            private Socket m_comm ;
            Byte[] m_ReceiveBuffer = new Byte[32767];
            private string m_ReceivedHist;
            private string m_ReceivedLast;
            private string Resp;

            public Telnet()
            {
            }

            public string Address
            {
                  get{ return m_address; }
                  set{ m_address = value; }
            }

            string m_ReceivedCurrent;
            public string ReceivedCurrent
            {
                  get{ return m_ReceivedCurrent; }
            }

            public string ReceivedHist
            {
                  get{ return m_ReceivedHist; }
            }

            public string ReceivedLast
            {
                  get{ return m_ReceivedLast; }
            }

            public void Connect()
            {
                  int port = 23;

                  IPHostEntry IPHost = Dns.Resolve(m_address);
                  string []aliases = IPHost.Aliases;
                  IPAddress[] addr = IPHost.AddressList;

                  // TODO: handle m_comm already being connected.
                  try
                  {
                        // Create New Socket
                        m_comm = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        // Create New EndPoint
                        iep      = new IPEndPoint(addr[0],port);

                        // Begin Asyncronous Connection
                        m_comm.Connect(iep);
                        ReceiveData();
                        System.Threading.Thread.Sleep(500);
                        ReceiveData();
                        System.Threading.Thread.Sleep(500);
                        ReceiveData();
                        System.Threading.Thread.Sleep(500);
                        ReceiveData();
                        System.Threading.Thread.Sleep(500);
                  }
                  catch( Exception e )
                  {
                        throw(new Exception("Error Connecting to host", e));
                  }
            }
////////////////
            public void ReceiveData()
            {
                  // Get The data , if any
                  int BytesReceived = m_comm.Available;
                  if( BytesReceived > 0 )
                  {
                        m_ReceiveBuffer = new Byte[32767];
                        BytesReceived = m_comm.Receive(m_ReceiveBuffer);
                        string Recieved = Encoding.ASCII.GetString( m_ReceiveBuffer, 0, BytesReceived );
                        string Line = "";
                        for( int i=0; i < BytesReceived; i++ )
                        {
                              char ch = Convert.ToChar(m_ReceiveBuffer[i]);
                              switch( ch )
                              {
                                    case '\r':
                                          Line += Convert.ToString("\r\n");
                                          break;
                                    case '\n':
                                          break;
                                    case '\b':
                                          Line = Line.Remove(Line.Length-1 ,1);
                                          break;
                                    default:
                                          Line += Convert.ToString(ch);
                                          break;
                              }
                        }
                        try
                        {
                              int strLinelen = Line.Length ;
                              if ( strLinelen == 0 )
                              {
                                    Line = Convert.ToString("\r\n");
                              }

                              Byte[] ToProcess = new Byte[strLinelen];
                              for ( int i=0; i <  strLinelen ; i++)
                                    ToProcess[i] = Convert.ToByte(Line[i]);
                              // Process the incoming data
                              m_ReceivedLast = ProcessOptions(ToProcess, Line);
                              m_ReceivedHist += m_ReceivedLast;
                              m_ReceivedCurrent += m_ReceivedLast;
                              // SCR comented out. 11/17/2003
                              // string TotalScreen = m_ReceivedHist + m_ReceivedLast;
                              // m_ReceivedHist =  TotalScreen;
                        
                              // Respond to any incoming m_commands
                              RespondToOptions();
                        }
                        catch( Exception e )
                        {
                              Console.WriteLine(e.Message);
                        }
                  }
            }
      
            private string ProcessOptions(byte[] LineToProcess, string Temp)
            {
                  string DISPLAYTEXT = "";
                  string Option = "";
                  bool ScanDone = false;
                  int ndx = 0;
                  int ldx      = 0;
                  char ch;
                  try
                  {
                        while( ScanDone != true )
                        {
                              ndx = Temp.IndexOf(Convert.ToString(IAC));
                              if( ndx > Temp.Length )
                                    // Set the offset to the maxlength, in case
                                    // a value greater than the length is returned.
                                    ndx = Temp.Length;

                              if(ndx != -1)
                              {
                                    // if IAC is in the temp string
                                    // Get everything left of IAC
                                    DISPLAYTEXT += Temp.Substring(0, ndx);

                                    // Get the character after the IAC
                                    ch = Temp[ndx + 1];
                                    if ( ch == DO || ch == DONT || ch == WILL || ch == WONT )
                                    {
                                          // if the next character is DO, DONT, WILL or WONT
                                          // Option = the next 3 characters
                                          Option = Temp.Substring(ndx, 3);  
                                          // DISPLAYTEXT = everything up to IAC
                                          DISPLAYTEXT += Temp.Substring(0,ndx);
                                          // Add the 3 character Option to the List of Options.
                                          mListOptions.Add(Option);
                                          // Remove those 3 characters from the Temp string
                                          Temp = Temp.Substring(ndx + 3);
                                    }
                                    else if( ch == IAC )
                                    {
                                          // IAC followed by IAC
                                          // DISPLAYTEXT = everything up to IAC
                                          DISPLAYTEXT = Temp.Substring(0, ndx);
                                          // Temp = everything after the first IAC
                                          Temp = Temp.Substring(ndx + 1);
                                    }
                                    else if( ch == SB )
                                    {
                                          // IAC followed by SB
                                          // DISPLAYTEXT = everything up to IAC
                                          DISPLAYTEXT= Temp.Substring(0, ndx);
                                          // SB will always be accompanied with an SE
                                          // find the SE
                                          ldx = Temp.IndexOf(Convert.ToString(SE));
                                          // Set Option to everything between IAC and SE
                                          Option = Temp.Substring(ndx, ldx);
                                          // Add the option to the list of options
                                          mListOptions.Add(Option);
                                          // Remove the Option from the Temp string.
                                          Temp = Temp.Substring(ldx + 1);
                                    }
                              }
                              else
                              {
                                    // No more IAC's just display text, done processing m_commands.
                                    if ( Temp.IndexOf(Convert.ToString(Convert.ToChar(0))) >=0 )
                                          DISPLAYTEXT += Temp.Substring(0, Temp.IndexOf(Convert.ToString(Convert.ToChar(0))));
                                    else
                                          DISPLAYTEXT += Temp;

                                    ScanDone = true;
                              }
                        }
                  }
                  catch(Exception e)
                  {
                        Console.WriteLine(e.Message);
                  }
                  return DISPLAYTEXT;
            }
      
            public void SendData(string messageText)
            {
                  try
                  {
                        // Reset the buffer, for the most recent command.
                        m_ReceivedCurrent = String.Empty;
                        
                        // See if there is anything to receive first.
                        ReceiveData();

                        // Send the Message
                        Byte[] sendMessage = new Byte[messageText.Length];
                        for( int i=0; i < messageText.Length; i++ )
                        {
                              sendMessage[i] = Convert.ToByte(messageText[i]);
                        }

                        m_comm.Send(sendMessage, 0, sendMessage.Length, SocketFlags.None);
                        System.Threading.Thread.Sleep(500);
                  }
                  catch(Exception e)
                  {
                        Console.WriteLine("Send To Telnet Error: " + e.Message);
                  }

                  ReceiveData();
            }

            private void ReSendData(string messageText)
            {
                  try
                  {
                        // See if there is anything to receive first.
                        ReceiveData();

                        // Send the Message
                        Byte[] sendMessage = new Byte[messageText.Length];
                        for( int i=0; i < messageText.Length; i++ )
                        {
                              sendMessage[i] = Convert.ToByte(messageText[i]);
                        }

                        m_comm.Send(sendMessage, 0, sendMessage.Length, SocketFlags.None);
                        System.Threading.Thread.Sleep(500);
                  }
                  catch(Exception e)
                  {
                        Console.WriteLine("Send To Telnet Error: " + e.Message);
                  }
            }

            void RespondToOptions()
            {
                  try
                  {
                        string Option;
                        for( int i=0; i < mListOptions.Count; i++ )
                        {
                              Option = (string)mListOptions[i];
                              ArrangeReply(Option);
                        }
                        ReSendData(Resp);
                        Resp ="";
                        mListOptions.Clear();
                  }
                  catch(Exception e)
                  {
                        Console.WriteLine("Error in Respond to options: " + e.Message);
                        Console.WriteLine("ERROR IN RESPOND OPTIONS");
                  }
            }

            void ArrangeReply(string strOption)
            {
                  try
                  {
                        char Verb;
                        char Option;
                        char Modifier;
                        bool Defined = false;

                        if(strOption.Length  < 3)
                              // An option should be at least 3 long,
                              // if it is not then ignore it.
                              return;

                        // Set the Verb to the second character.
                        Verb = strOption[1];
                        // Set the option to the 3rd character.
                        Option = strOption[2];

                        if ( Option == 1 || Option == 3 )
                        {
                              //      case 1:      // Echo
                              //      case 3: // Suppress Go-Ahead
                              Defined = true;
                        }

                        Resp += IAC;
                        if ( Defined )
                        {
                              if ( Verb == DO )
                                    Resp += WILL.ToString() + Option.ToString();

                              if ( Verb == DONT )
                                    Resp += WONT.ToString() + Option.ToString();

                              if ( Verb == WILL )
                                    Resp += DO.ToString() + Option.ToString();

                              if ( Verb == WONT )
                                    Resp += DONT.ToString() + Option.ToString();

                              if (( Verb == SB ))
                              {
                                    Modifier = strOption[3];
                                    if( Modifier == SEND )
                                          Resp += SB.ToString() + Option.ToString() + IS.ToString() + IAC.ToString() + SE.ToString();
                              }
                        }
                        else
                        {
                              if ( Verb == DO )
                                    Resp += WONT.ToString() + Option.ToString();

                              if ( Verb == DONT )
                                    Resp += WONT.ToString() + Option.ToString();

                              if ( Verb == WILL )
                                    Resp += DONT.ToString() + Option.ToString();

                              if ( Verb == WONT )
                                    Resp += DONT.ToString() + Option.ToString();
                        }

                  }
                  catch(Exception e )
                  {
                        Console.WriteLine(e.Message);
                  }

            }
            /////////////////////////////////////////
      }
}



That was the Telnet class.
To use it is fairly simple

conn.Address = "host";
conn.Connect();
richTextBox1.Text = conn.ReceivedCurrent;
conn.SendData("username\r\n");
richTextBox1.Text += conn.ReceivedCurrent;
conn.SendData("password\r\n");
richTextBox1.Text += conn.ReceivedCurrent;
conn.SendData("l -la\r\n");
richTextBox1.Text += conn.ReceivedCurrent;
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 9952768
You are right, sorry.
My previous comment was a bit flippant, as I do know how complex telnet is.

My point was, that if you can find and adapt a class like the one above, it will probably be easier in the long run than trying to proxy through a closed app.

Good luck with that.
Cheers.
0
 

Author Comment

by:andyk1
ID: 9953856
That code works great, thanks a lot for that. Any idea, how to format  the received data from a DIR command, it contains unwanted bytes. Thanks again. I have been stuck on that for a long time know.
0
 
LVL 15

Expert Comment

by:SRigney
ID: 9956282
Each line in the returned string is in a specific format.  You can loop through the lines and reformat them to however you want using substring to get the pieces that you want.
0
 

Author Comment

by:andyk1
ID: 9959956
Thanks for that. I am going to look into reformatting the output from. Thanks Again
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Introduction                                                 Was the var keyword really only brought out to shorten your syntax? Or have the VB language guys got their way in C#? What type of variable is it? All will be revealed.   Also called…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now