I am using Python telnetlib for taking the "running config" output from router.How to store the "show running-config" output in a variable.And print the variable.My requirement is the each and every output will display in the console when executing each and every line of the code.Is there any option to aviod these print statements.
import telnetlib
#import getpass
ipaddr = "10.1.1.1"
passwd = "abcd123"
tn = telnetlib.Telnet(ipaddr)
if Password:
try:
print (tn.write (password + "\n"))
print(tn.read_until("Router>"))
print(tn.write("enable\n"))
print(tn.read_until("Password:"))
print(tn.write(passwd + "\n"))
print(tn.read_until("Router#"))
print(tn.write("show clock\n"))
print(tn.read_until("#"))
print(tn.write("show running-config\n"))
print(tn.write("\040\n"))
print(tn.write("\040\n"))
print(tn.write("\040\n"))
print(tn.read_until("#"))
print(tn.write("logout\n"))
print(tn.read_until(">"))
print tn.close
If I understand you correctly you wish to print out to your local console the output of each command which you run on the remote console. I am not sure why it needs to be synchronous except you say that is a requirement. You might want to make sure you understand the requirements. In any case, since your requirement is that the output be printed, you don't need to print your input...
I highly recommend storing the output into a variable even if you need to print it immediately simply because I see no benefit of retrieving the data unless you are going to act on the data and if you merely print the data you cannot act on it. Store it in a variable and then it can be printed as well as acted upon. I doubt the human eye would be able to tell the difference in storing it and then writing it all at once rather than piecemeal.
Your try block, as written, will never happen because you have to read from the telnet session first before you can evaluate if 'Password:' is on the remote console.
Some further suggestions:
First, write terminal length 0, that will avoid having to handle paused output.
Second, since I am lazy, any variables I know I am only using to pass to the remote unit I save with a newline character.
Third, always give it a timeout or else it runs the risk of waiting forever for a match that might never come.
Fourth, have a look at Telnet.expect(list, [timeout]). I find it far more useful than a simple read_until; it allows you to look for multiple responses and act on each of them accordingly. It is quite useful for handling errors. It returns a three item tuple that represents the index of the matched item (-1 if no match) as well as the matched text (or everything in the buffer if no match).
Fifth, write a decorator for your telnet session to log in. You know it will be used at least once every time you interact with a remote unit, and more if you are loading new firmware. Develop a library of functions that you can reuse rather than writing it out each time. Lazy is good.
import telnetlib
import sys
ipaddr = "10.1.1.1"
passwd = "abcd123"
def login(tn):
global passwd
passwd=passwd+'\n'
def error_check(tmp):
if tmp[0]==-1:
print "Unexpected response"
print "tmp[2]
sys.exit()
tmp=tn.expect(["Password:",], 5)
error_check(tmp)
tn.write(passwd)
tmp=expect([">",],5)
error_check(tmp)
tn.write('en\n')
tmp=expect(["Password", "#'],5)
error_check(tmp)
if tmp(0)==0: #if someone left enable unlocked, don't send a password
tn.write(passwd)
tmp=expect(["#',],5)
error_check(tmp)
tn = telnetlib.Telnet(ipaddr)
login(tn)
tn.write('terminal length 0')
tmp=expect(["#',],5)
tn.write('sho clock')
now=tn.expect(["#",], 5)
print now
tn.write('sho run')
print run
cfg=tn.expect(["#",], 5)
tn.write("logout\n"))
bye=tn.expect([">",], 5)
print bye
tn.close()
Related
I have a c exectuable that I want to exploit.
The output of that file looks like this:
$ ./vuln_nostack
Enter some text:
enteringTEXT
You entered: enteringTEXT
You enter some text, and the program spits it back.
I want to run this prorgam (and later exploit it) with python and pwntools.
So far, the functioning part of my pwntools program looks like this:
from concurrent.futures import process
from sys import stdout
from pwn import *
import time
pty = process.PTY
p = process("./vuln_nostack", stdin=pty, stdout=pty)
ss = p.recv()
p.clean()
asstring = ss.decode("utf-8")
print(asstring)
This works fine, it gets the first line and then prints it.
What I want to do now is to send a message to the program and then get the final line.
I have tried something along these lines:
p.send(b"dong")
p.clean()
print(p.recv())
I'm not sure whether or not the send actually ever sends anything, but as soon as I add the recv function, the prorgam just hangs and never finishes.
My guess is that the input to the executable is never given properly, and therefore it's still just waiting.
How do I actually get a message delivered to the exectuable so that it can move on and srever me the last line?
You can also use p.sendline():
p.sendline("payload")
This automatically adds a breakline after your bytes.
Moreover, to know whether your exploit is sending/receiving messages to/from the program, you can use debug context by adding this assignment:
context.log_level = 'debug'
The answer was a lot more simple than formerly presumed.
I just needed a breakline in the send:
p.send("payload \n")
I am using a python library I wrote to interact with a custom USB device. The library needs to send and receive data. I also need to interactively call methods. At the moment I utilize two shells, one receiving only and the other sending only. The latter is in the (i)python REPL. It works but it is clumsy, so I want to consolidate the two things in a single shell, which will have the advantage to have access to data structures from both sides in one context. That works fine. The problem is in the UI.
In fact, the receiving part needs to asynchronously print some information. So I wrote something like the following:
#!/usr/bin/python
import threading
import time
import blessings
TOTAL=5
def print_time( thread_id, delay):
count = 0
t=blessings.Terminal()
while count < TOTAL:
time.sleep(delay)
count += 1
stuff = "Thread " + str(thread_id) + " " + str(time.ctime(time.time())) + " -- " + str(TOTAL - count) + " to go"
with t.location(t.width - len(stuff) - 1, thread_id):
print (stuff, end=None )
print("", end="") # just return the cursor
try:
t1 = threading.Thread( target = print_time, args = (1, 2, ) )
t1.start()
print ("Thread started")
except:
print ("Error: unable to start thread")
That is my __init__.py file for the module. It somewhat works, but it has two problems:
While the thread is running, you cannot exit the REPL neither with CTRL-D nor with sys.exit() (that is the reason I am using TOTAL=5 above, so your life is easier if you try this code). This is a problem since my actual thread needs to be an infinite loop. I guess one solution could be to exit via a custom call which will cause a break into that infinite loop, but is there anything better?
The cursor does not return correctly to its earlier position
if I remove the end="" in the line with the comment # just return the cursor, it sort of works, but obviously print an unwanted newline in the place the cursor was (which messes us other input and/or output which might be happening there, in addition to add that unwanted newline)
if I leave the end="" it does not return the cursor, not even if I add something to print, e.g. print(".", end="") -- the dots . are printed at the right place, but the blinking cursor and the input is printed at the top
I know these are two unrelated problem and I could have asked two separate questions, but I need an answer to both, or otherwise it's a moot point. Or alternatively, I am open to other solutions. I thought of a separate GTK window, and that might work, but it's a subpar solution, since I really would like this to work in CLI only (to keep it possible in a ssh-without-X-tunneling setup).
Using blessed instead of blessing does not have the problem with the cursor not returning to the previous position, even without anything outside of the with context.
Making the thread a daemon solves the other problem.
I'm currently working on a project where I need to send data via Serial persistently but need to occasionally change that data based in new inputs. My issue is that my current loop only functions exactly when a new input is offered by raw_input(). Nothing runs again until another raw_input() is received.
My current (very slimmed down) loop looks like this:
while True:
foo = raw_input()
print(foo)
I would like for the latest values to be printed (or passed to another function) constantly regardless of how often changes occur.
Any help is appreciated.
The select (or in Python 3.4+, selectors) module can allow you to solve this without threading, while still performing periodic updates.
Basically, you just write the normal loop but use select to determine if new input is available, and if so, grab it:
import select
while True:
# Polls for availability of data on stdin without blocking
if select.select((sys.stdin,), (), (), 0)[0]:
foo = raw_input()
print(foo)
As written, this would print far more than you probably want; you could either time.sleep after each print, or change the timeout argument to select.select to something other than 0; if you make it 1 for instance, then you'll update immediately when new data is available, otherwise, you'll wait a second before giving up and printing the old data again.
How will you type in your data at the same time while data is being printed?
However, you can use multithreading if you make sure your source of data doesn't interfere with your output of data.
import thread
def give_output():
while True:
pass # output stuff here
def get_input():
while True:
pass # get input here
thread.start_new_thread(give_output, ())
thread.start_new_thread(get_input, ())
Your source of data could be another program. You could connect them using a file or a socket.
I write some codes to get the input from keyboard and also check something is alive or not:
import sys
from select import select
timeout = 10
while is_alive(): # is_alive is a method to check some stuffs, might take 5 secs
rlist, _, _ = select([sys.stdin], [], [], timeout)
if rlist:
s = sys.stdin.readline()
print repr(s)
handle(s) # handle is a method to handle and react according to input s
I found that when the keyboard input ends outside of the waiting in select() (usually it ends during the 5 secs of is_alive()), the if rlist: will get false.
I can understand why but I don't know how to solve it.
And there is still another question related to the situation mentioned above, sometimes readline() will return the last line of my input when some inputs are located across different select() waiting.
That means, if I enter 'abc\n' and unfortunately the '\n' located outside of wating in select() (that means, when I press Enter, the program are executing other parts, such as is_alive()), and then if I enter 'def\n' and this time the Enter pressed successfully located within select(), I'll see the s from readline() becomes 'def\n' and the first line is disappeared.
Is there any good solution to solve two issues above? I'm using FreeBSD 9.0.
As your code in is_alive() calls ssh, this will eat up the stdin.
Try starting ssh with the -n option or with a re-directed stdin.
The latter would work with
sp = subprocess.Popen(..., stdin=subprocess.PIPE)
sp.stdin.close()
I am using the Python module telnetlib to create a telnet session (with a chess server), and I'm having an issue I really can't wrap my brain around. The following code works perfectly:
>>> f = login("my_server") #code for login(host) below.
>>> f.read_very_eager()
This spits out everything the server usually prints upon login. However, when I put it inside a function and then call it thus:
>>> def foo():
... f = login("my_server")
... return f.read_very_eager()
...
>>> foo()
I get nothing (the empty string). I can check that the login is performed properly, but for some reason I can't see the text. So where does it get swallowed?
Many thanks.
For completeness, here is login(host):
def login(host, handle="guest", password=""):
try:
f = telnetlib.Telnet(host) #connect to host
except:
raise Error("Could not connect to host")
f.read_until("login: ")
try:
f.write(handle + "\n\r")
except:
raise Error("Could not write username to host")
if handle == "guest":
f.read_until(":\n\r")
else:
f.read_until("password: ")
try:
f.write(password + "\n\r")
except:
raise Error("Could not write password to host")
return f
The reason why this works when you try it out manually but not when in a function is because when you try it out manually, the server has enough time to react upon the login and send data back. When it's all in one function, you send the password to the server and never wait long enough for the server to reply.
If you prefer a (probably more correct) technical answer:
In file telnetlib.py (c:\python26\Lib\telnetlib.py on my Windows computer), function read_very_eager(self) calls self.sock_avail() Now, function sock_avail(self) does the following:
def sock_avail(self):
"""Test whether data is available on the socket."""
return select.select([self], [], [], 0) == ([self], [], [])
What this does is really simple: if there is -anything- to read from our socket (the server has answered), it'll return True, otherwise it'll return False.
So, what read_very_eager(self) does is: check if there is anything available to read. If there is, then read from the socket, otherwise just return an empty string.
If you look at the code of read_some(self) you'll see that it doesn't check if there is any data available to read. It'll try reading till there is something available, which means that if the server takes for instance 100ms before answering you, it'll wait 100ms before returning the answer.
I'm having the same trouble as you, unfortunately the combination of select.select, which I have in a while loop until I am able to read, and then calling read_some() does not work for me, still only reading 1% of the actual output. If I put a time.sleep(10) on before I read and do a read_very_eager() it seems to work...this is a very crude way of doing things but it does work..I wish there was a better answer and I wish I had more reputation points so I could respond to user387821 and see if he has any additional tips.