__VERSION__ = '0.1' __AUTHOR__ = 'Galkan' __DATE__ = '16.07.2014' try: import os import re import sys import shlex import signal import paramiko import argparse import tempfile import datetime import subprocess from lib.threadpool import ThreadPool from lib.iprange import IpRange except ImportError,e: import sys sys.stdout.write("%s\n" %e) sys.exit(1) class AddressAction(argparse.Action): def __call__(self, parser, args, values, option = None): if args.brute == "sshkey": if args.key_file is None: print >> sys.stderr, """usage: Usage: use --help for futher information\nlevye.py: error: argument -k/--key: expected one argument """ sys.exit(1) elif args.username is None: print >> sys.stderr, """usage: Usage: use --help for futher information\nlevye.py: error: argument -u/--user: expected one argument """ sys.exit(1) elif args.brute == "openvpn": if args.config is None: print >> sys.stderr, """usage: Usage: use --help for futher information\nlevye.py: error: argument -m/--config: expected one argument """ sys.exit(1) elif args.passwd is None: print >> sys.stderr, """usage: Usage: use --help for futher information\nlevye.py: error: argument -c/--passwd: expected one argument """ sys.exit(1) elif args.username is None: print >> sys.stderr, """usage: Usage: use --help for futher information\nlevye.py: error: argument -u/--user: expected one argument """ sys.exit(1) elif (args.brute == "rdp" or args.brute == "vnckey") and args.passwd is None: if args.passwd is None: print >> sys.stderr, """usage: Usage: use --help for futher information\nlevye.py: error: argument -c/--passwd: expected one argument """ sys.exit(1) class Main: def __init__(self): self.services = {"sshkey":self.sshkey,"rdp":self.rdp, "openvpn":self.openvpn, "vnckey":self.vnckey} self.levye_readme = "https://github.com/galkan/levye/blob/master/README.md" self.openvpn_path = "/usr/sbin/openvpn" self.vpn_failure = re.compile("SIGTERM\[soft,auth-failure\] received, process exiting") self.vpn_success = re.compile("Initialization Sequence Completed") self.vpn_remote_regex = re.compile("^\s+remote\s[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\s[0-9]{1,3}") self.vpn_warning = "Warning !!! Both \"remote\" options were used at the same time. But command line \"remote\" options will be used !!!" self.xfreerdp_path = "/usr/bin/xfreerdp" self.rdp_success = "Authentication only, exit status 0" self.rdp_display_error = "Please check that the \$DISPLAY environment variable is properly set." self.vncviewer_path = "/usr/bin/vncviewer" self.vnc_success = "Authentication successful" description = "Levye is a brute force tool which is support sshkey, vnckey, rdp, openvpn." usage = "Usage: use --help for futher information" parser = argparse.ArgumentParser(description = description, usage = usage) parser.add_argument('-b', '--brute', dest = 'brute', help = 'Brute Force Type', choices = self.services.keys(), required = True) parser.add_argument('-s', '--server', dest = 'server', action = 'store', help = 'Server/Server File', required = True) parser.add_argument('-u', '--user', dest = 'username', action = 'store', help = 'Username/Username File') parser.add_argument('-n', '--number', dest = 'thread', action = 'store', help = 'Thread Number', default = 5, type = int) parser.add_argument('-l', '--log', dest = 'log_file', action = 'store', help = 'Log File', metavar = 'FILE', default = "levye.log") parser.add_argument('-o', '--output', dest = 'output', action = 'store', help = 'Output File', metavar = 'FILE', default = "levye.out") parser.add_argument('-c', '--passwd', dest = 'passwd', action = 'store', help = 'Password/Password File', metavar = 'FILE') parser.add_argument('-t', '--timeout', dest = 'timeout', action = 'store', help = 'Timeout Value', default = 2, type = int) parser.add_argument('-p', '--port', dest = 'port', action = 'store', help = 'Service Port Number', type = int) parser.add_argument('-k', '--key', dest = 'key_file', action = 'store', help = 'Key File') parser.add_argument('-m', '--config', dest = 'config', action = 'store', help = 'Configuration File') parser.add_argument('options', nargs='*', action = AddressAction) try: self.args = parser.parse_args() except Exception, err: print >> sys.stderr, err sys.exit(1) for levye_file in self.args.log_file, self.args.output: if not os.path.exists(levye_file): open(levye_file, 'w').close() self.ip_list = [] try: iprange = IpRange() for ip in iprange.iprange(self.args.server): self.ip_list.append(ip) except: print >> sys.stderr, "Please use IP/CIDR notation. <192.168.37.37/32, 192.168.1.0/24>" sys.exit(1) now = datetime.datetime.now() start_time = "START TIME: " + now.strftime("%Y-%m-%d %H:%M:%S") + "\n" print start_time[:-1] self.fd_log_file = open(self.args.log_file, "a") self.fd_output_file = open(self.args.output, "a") self.fd_log_file.write(start_time) def vnclogin(self, ip, port, passwd_file): vnc_cmd = "%s -passwd %s %s:%s"% (self.vncviewer_path, passwd_file, ip, port) proc = subprocess.Popen(shlex.split(vnc_cmd), shell=False, stdout = subprocess.PIPE, stderr = subprocess.PIPE) brute = "LOG: VNC: " + ip + ":" + str(port) + ":" + passwd_file + "\n" self.fd_log_file.write(brute) for line in iter(proc.stderr.readline, ''): if re.search(self.vnc_success, line): now = datetime.datetime.now() os.kill(proc.pid, signal.SIGQUIT) result = "SUCCESS," + now.strftime("%Y-%m-%d %H:%M:%S") + "," + "VNC," + ip + "," + str(port) + "," + passwd_file + "\n" print result[:-1] self.fd_output_file.write(result) break def vnckey(self, *options): port = 5900 if not os.path.exists(self.vncviewer_path): print >> sys.stderr, "vncviewer: %s path doesn't exists on the system !!!"% (self.vncviewer_path) sys.exit(1) if self.args.port is not None: port = self.args.port if not os.path.isfile(self.args.passwd): print >> sys.stderr, "Password must be file !!!" sys.exit(1) try: pool = ThreadPool(int(self.args.thread)) except Exception, err: print >> sys.stderr, err sys.exit(1) for ip in self.ip_list: pool.add_task(self.vnclogin, ip, port, self.args.passwd) pool.wait_completion() def rdplogin(self, ip, user, password, port): rdp_cmd = "%s /sec:nla /p:%s /u:%s /port:%s /v:%s +auth-only /cert-ignore"% (self.xfreerdp_path, password, user, port, ip) proc = subprocess.Popen(shlex.split(rdp_cmd), shell=False, stdout = subprocess.PIPE, stderr = subprocess.PIPE) brute = "LOG: RDP: " + ip + ":" + user + ":" + password + ":" + str(port) + "\n" self.fd_log_file.write(brute) for line in iter(proc.stderr.readline, ''): if re.search(self.rdp_success, line): now = datetime.datetime.now() result = "SUCCESS," + now.strftime("%Y-%m-%d %H:%M:%S") + "," + "RDP," + ip + "," + user + "," + password + "," + str(port) + "\n" print result[:-1] self.fd_output_file.write(result) break elif re.search(self.rdp_display_error, line): print >> sys.stderr, "Please check \$DISPLAY is properly set. See readme %s"% self.levye_readme break def rdp(self): port = 3389 if not os.path.exists(self.xfreerdp_path): print >> sys.stderr, "xfreerdp: %s path doesn't exists on the system !!!"% (self.xfreerdp_path) sys.exit(1) if self.args.port is not None: port = self.args.port try: pool = ThreadPool(int(self.args.thread)) except Exception, err: print >> sys.stderr, err sys.exit(1) for ip in self.ip_list: if os.path.isfile(self.args.username): for user in open(self.args.username, "r").read().splitlines(): if os.path.isfile(self.args.passwd): for password in open(self.args.passwd, "r").read().splitlines(): pool.add_task(self.rdplogin, ip, user, password, port) else: pool.add_task(self.rdplogin, ip, user, self.args.passwd, port) else: if os.path.isfile(self.args.passwd): for password in open(self.args.passwd, "r").read().splitlines(): pool.add_task(self.rdplogin, ip, self.args.username, password, port) else: pool.add_task(self.rdplogin, ip, self.args.username, self.args.passwd, port) pool.wait_completion() def openvpnlogin(self, host, username, password, brute_file, port): brute_file_name = brute_file.name brute_file.seek(0) openvpn_cmd = "%s --config %s --auth-user-pass %s --remote %s %s"% (self.openvpn_path, self.args.config, brute_file_name, host, port) proc = subprocess.Popen(shlex.split(openvpn_cmd), shell=False, stdout = subprocess.PIPE, stderr = subprocess.PIPE) brute = "LOG: OPENVPN: " + host + ":" + username + ":" + password + ":" + brute_file_name + "\n" self.fd_log_file.write(brute) for line in iter(proc.stdout.readline, ''): if re.search(self.vpn_success, line): now = datetime.datetime.now() result = "SUCCESS," + now.strftime("%Y-%m-%d %H:%M:%S") + "," + "OPENVPN," + host + "," + username + "," + password + "\n" print result[:-1] self.fd_output_file.write(result) os.kill(proc.pid, signal.SIGQUIT) brute_file.close() def openvpn(self): port = 443 if not os.path.exists(self.openvpn_path): print >> sys.stderr, "openvpn: %s path doesn't exists on the system !!!"% (self.openvpn_path) sys.exit(1) if self.args.port is not None: port = self.args.port try: pool = ThreadPool(int(self.args.thread)) except Exception, err: print >> sys.stderr, err sys.exit(1) for config_line in open(self.args.config, "r"): if re.search(self.vpn_remote_regex, config_line): print self.vpn_warning sys.exit(1) for ip in self.ip_list: if os.path.isfile(self.args.username): for user in open(self.args.username, "r").read().splitlines(): if os.path.isfile(self.args.passwd): for password in open(self.args.passwd, "r").read().splitlines(): brute_file = tempfile.NamedTemporaryFile(mode='w+t') brute_file.write(user + "\n") brute_file.write(password + "\n") pool.add_task(self.openvpnlogin, ip, user, password, brute_file, port) else: brute_file = tempfile.NamedTemporaryFile(mode='w+t') brute_file.write(user + "\n") brute_file.write(self.args.passwd + "\n") pool.add_task(self.openvpnlogin, ip, user, self.args.passwd, brute_file, port) else: if os.path.isfile(self.args.passwd): for password in open(self.args.passwd, "r").read().splitlines(): brute_file = tempfile.NamedTemporaryFile(mode='w+t') brute_file.write(self.args.username + "\n") brute_file.write(password + "\n") pool.add_task(self.openvpnlogin, ip, self.args.username, password, brute_file, port) else: brute_file = tempfile.NamedTemporaryFile(mode='w+t') brute_file.write(self.args.username + "\n") brute_file.write(self.args.passwd + "\n") pool.add_task(self.openvpnlogin, ip, self.args.username, self.args.passwd, brute_file, port) pool.wait_completion() def sshlogin(self,ip,port,user,keyfile,timeout): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) brute = "LOG: SSH: " + ip + ":" + str(port) + ":" + user + ":" + keyfile + ":" + str(timeout) + "\n" self.fd_log_file.write(brute) try: ssh.connect(ip, port, username=user, password=None, pkey=None, key_filename=keyfile, timeout=timeout, allow_agent=False, look_for_keys=False) now = datetime.datetime.now() result = "SUCCESS," + now.strftime("%Y-%m-%d %H:%M:%S") + "," + "SSH," + ip + "," + str(port) + "," + user + "," + keyfile + "\n" print result[:-1] self.fd_output_file.write(result) except Exception ,err: pass def sshkey(self): port = 22 if self.args.port is not None: port = self.args.port try: pool = ThreadPool(self.args.thread) except Exception, err: print >> sys.stderr, err sys.exit(1) for ip in self.ip_list: if os.path.isfile(self.args.username): for user in open(self.args.username, "r").read().splitlines(): if os.path.isdir(self.args.key_file): for dirname, dirnames, filenames in os.walk(self.args.key_file): for keyfile in filenames: keyfile_path = self.args.key_file + "/" + keyfile pool.add_task(self.sshlogin, ip, port, user, keyfile_path, self.args.timeout) else: pool.add_task(self.sshlogin, ip, port, user, self.args.key_file, self.args.timeout) else: if os.path.isdir(self.args.key_file): for dirname, dirnames, filenames in os.walk(self.args.key_file): for keyfile in filenames: keyfile_path = self.args.key_file + "/" + keyfile pool.add_task(self.sshlogin, ip, port, self.args.username, keyfile_path, self.args.timeout) else: pool.add_task(self.sshlogin, ip, port, self.args.username, self.args.key_file, self.args.timeout) pool.wait_completion() def run(self, brute_type): signal.signal(signal.SIGINT, self.signal_handler) if not brute_type in self.services.keys(): print >> sys.stderr, "%s is not valid service. Please select %s "% (brute_type,self.services.keys()) sys.exit(1) else: self.services[brute_type]() now = datetime.datetime.now() stop_time = "STOP TIME: " + now.strftime("%Y-%m-%d %H:%M:%S") + "\n" print stop_time[:-1] self.fd_log_file.write(stop_time) self.fd_output_file.close() self.fd_log_file.close() def signal_handler(self, signal, frame): print('Bye ...') sys.exit(37)