Skip to content

Instantly share code, notes, and snippets.

@droberson
Created April 7, 2020 02:46
Show Gist options
  • Save droberson/399bf5a612db258575ed15669c9d67a8 to your computer and use it in GitHub Desktop.
Save droberson/399bf5a612db258575ed15669c9d67a8 to your computer and use it in GitHub Desktop.
Some wack garbage to grab lots of SSH banners
#!/usr/bin/env python3
import os
import sys
import time
import fcntl
import errno
import socket
from threading import Thread
from queue import Queue
Q = Queue()
def valid_ipv4_address(ip_address):
""" valid_ipv4_address() - Validate an IPv4 address.
Args:
ip_address (str) - IP address to verify.
Returns:
True if ip_address is a valid IPv4 address.
False if ip_address is not a valid IPv4 address.
"""
try:
socket.inet_aton(ip_address)
except socket.error:
return False
return True
def log(host, port, message):
with open("ssh-logfile-%s" % sys.argv[1], "a") as logfile:
logfile.write("%d %s %s %s\n" %
(time.time(), host, port, message))
def grab_ssh_banner(host, port, timeout=5):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
fcntl.fcntl(sock, fcntl.F_SETFL, os.O_NONBLOCK)
try:
sock.connect((host, port))
except Exception as exc:
#print(" [-] %d %s:%s %s" % (time.time(), host, port, exc))
#log(host, port, False, exc)
return False
try:
sock.send(b"SSH-2.0-sshsurveyor\r\n")
except ConnectionResetError as exc:
#log(host, port, False, exc)
return False
received = 0
banner = []
while True:
try:
msg = sock.recv(4096)
received += len(msg)
except socket.error as e:
err = e.args[0]
if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
continue
else:
#print(" [-] %d %s:%s %s" % (time.time(), host, port, e))
#log(host, port, False, e)
sock.close()
break
except socket.timeout:
#print(" [-] %d %s:%s timed out" % (time.time(), host, port))
#log(host, port, False, "timed out")
sock.close()
return False
if msg != b'' or received > 8192:
banner += [msg]
else:
break
banner = b"".join(banner)
#print(" [+] %d %s:%s %s" % (time.time(), host, port, banner))
sock.close()
log(host, port, banner)
return True
def thread_scan(thread_id, queue):
while True:
host, port = queue.get()
#print(" [*] Scanning %s:%s on thread %d" % (host, str(port), thread_id))
grab_ssh_banner(host, port, timeout=5)
queue.task_done()
def process_ip_list(ip_list, port=0):
for ip in ip_list:
if valid_ipv4_address(ip):
Q.put((ip, port))
else:
print("[-] invalid ip: %s" % ip)
print("[+] Scanning %s - %s (%d/%d %d%%) -- Elapsed: %s" %
(ip_list[0], ip_list[-1],
progress, ip_count, progress / ip_count * 100,
display_time(round(time.time() - start_time))))
for thread in range(32):
worker = Thread(target=thread_scan, args=(thread, Q))
worker.setDaemon(True)
worker.start()
Q.join()
def linecount(filename):
with open(filename, "r") as file:
for i, _ in enumerate(file):
pass
return i + 1
intervals = (
("weeks", 604800), # 60 * 60 * 24 * 7
("days", 86400), # 60 * 60 * 24
("hours", 3600), # 60 * 60
("minutes", 60),
("seconds", 1)
)
def display_time(seconds, granularity=2):
result = []
if seconds == 0:
return "0 seconds"
for name, count in intervals:
value = seconds // count
if value:
seconds -= value * count
if value == 1:
name = name.rstrip("s")
result.append("{} {}".format(value, name))
return ", ". join(result[:granularity])
print("[+] Scanning ips in %s" % sys.argv[1])
ip_count = linecount(sys.argv[1])
progress = 0
start_time = time.time()
with open(sys.argv[1], "r") as fp:
count = 0
cset = []
for line in fp:
count += 1
cset += [line.rstrip()]
if count % 1000 == 0:
progress += len(cset)
process_ip_list(cset, port=22)
cset = []
progress += len(cset)
if len(cset) > 0:
process_ip_list(cset, 22)
print("[+] Finished. Elapsed: %s" % display_time(time.time() - start_time))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment