Beispiel #1
0
    def __init__(self, project_name=None):
        self.show_banner()
        self.logger = Logger(level='DEBUG', module=self.__module__)

        if project_name is not None:
            BphSession.project_name = project_name
        else:
            raise BphSessionNameException('Session Name was not provided')

        try:
            sample_abs_path = sys.argv[1]
        except IndexError:
            self.logger.log('Starting session without setting up a sample file...')
        else:
            self.tmp_sample_abs_path = sample_abs_path
            self.logger.log('Setting sample: {}'.format(self.tmp_sample_abs_path))
            BphSession.sample_md5 = LabFile.md5hash(self.tmp_sample_abs_path)
            
        # Session files, folders and identifiers here.
        self.project_folder = os.path.join(BPH_USER_DATA, BphSession.project_name)
        self.session_log_file = os.path.join(self.project_folder, 'session.log')
        self.launcher_folder = os.path.join(self.project_folder, 'launcher')
        
        self.project_folder_check()
        
        if BphSession.sample_md5 == '':
            self.sid_folder = os.path.join(BPH_USER_DATA, BphSession.project_name, '', BphSession.sid)
        else:
            self.sid_folder = os.path.join(BPH_USER_DATA, BphSession.project_name, BphSession.sample_md5, BphSession.sid)
            
        BphSession.sample_folder = os.path.join(BPH_USER_DATA, BphSession.project_name, BphSession.sample_md5)
        
        BphSession.sid_folder = self.sid_folder

        # Create session directory if doesn't exist.
        Directory(self.sid_folder).check_and_create()
class BphDirectory(BphFileSystem):
    def __init__(self, directory):
        self.directory = directory
        self.logger = Logger(level='INFO', module=self.__module__)

    def check_and_create(self):
        self.logger.log(f"Verifying directory existence: {self.directory}",
                        level='DEBUG')
        try:
            if os.path.isdir(self.directory):
                self.logger.log(f"Directory ({self.directory}) exists.",
                                level='DEBUG')

            else:
                self.logger.log(f"Creating directory: {self.directory}",
                                level='DEBUG')
                os.makedirs(self.directory, 0o777, exist_ok=True)

        except OSError:
            raise
Beispiel #3
0
 def __init__(self):
     self.logger = Logger(level='INFO', module=self.__module__)
     client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     self.client_socket = client_socket
     self.vm_data = None
     self.connection_status = False
Beispiel #4
0
class BphVmControl(BphVm):
    def __init__(self):
        self.logger = Logger(level='INFO', module=self.__module__)
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.client_socket = client_socket
        self.vm_data = None
        self.connection_status = False

    def __client_connector(self):
        try:
            self.client_socket.connect(
                (BPH_VIRTUALBOX_SERVER_IP, BPH_VIRTUALBOX_SERVER_PORT))
        except socket.error:
            self.logger.log(
                "Can't connect to VM manager. Attempting in 5 seconds")
            time.sleep(5)
            self.__client_connector()

        else:
            self.logger.log('Connected...!')
            self.connection_status = True

    def send_data(self):
        if self.connection_status:

            if self.vm_data is not None:

                self.logger.log('Sending: {}'.format(self.vm_data))
                self.client_socket.send(bytes(self.vm_data, 'ascii'))

                while True:
                    self.logger.log('Awaiting response from Agent...')
                    time.sleep(3)
                    data = self.client_socket.recv(128)

                    if b"OK" in data:
                        self.logger.log('Data received from Agent => OK')
                        self.logger.log(data, level='DEBUG')
                        break

    def __update_cmd(self, action):
        self.logger.log('Updating cmd action to: {}'.format(action),
                        level='DEBUG')

        self._vm_data['action'] = action
        self.vm_data = "|".join([
            self._vm_data['action'], self._vm_data['vm_id'],
            self._vm_data['snapshot_id'], self._vm_data['network_id']
        ])

        self.logger.log('New VM Data: {}'.format(self.vm_data))

    def set_vm(self, exec_type, network_id=None):
        _exec_type = "".join(exec_type.split('_'))
        self.logger.log(f'[{exec_type}] VM Analysis was selected')

        data = {}

        for vm_data in BphVm.vm_config.VIRTUALMACHINES:
            if _exec_type in vm_data:
                if exec_type not in BphVm.vm_config.VIRTUALMACHINES[vm_data]:
                    _vm_data = BphVm.vm_config.VIRTUALMACHINES[vm_data]

                    if "machineid" in vm_data:
                        vm_id = _vm_data
                        self.logger.log(f"VmId: {vm_id}", level='INFO')
                        data['vm_id'] = vm_id

                    if "snapshotid" in vm_data:
                        snapshot_id = _vm_data
                        self.logger.log(f"SnapshotId: {snapshot_id}",
                                        level='INFO')
                        data['snapshot_id'] = snapshot_id

                    if "networkconnection" in vm_data:
                        net_id = _vm_data
                        self.logger.log(f"NetworkConnectionId: {net_id}",
                                        level='INFO')

                        if network_id is not None:
                            data['network_id'] = str(network_id)
                        else:
                            data['network_id'] = net_id

        self._vm_data = data
        self.logger.log('VM Data: {}'.format(self._vm_data))
        self.__client_connector()

    def start(self):
        self.logger.log('Starting VM')
        self.__update_cmd('start')
        self.send_data()

        if self.connection_status:
            self.logger.log('VM Started OK.')
            time.sleep(5)

    def stop(self):
        self.logger.log('Stopping VM')
        self.__update_cmd('stop')
        self.send_data()

        if not self.connection_status:
            self.logger.log('VM Shutdown OK')
            time.sleep(2)
Beispiel #5
0
 def __init__(self):
     self.logger = Logger(level='INFO', module=self.__module__)
     self.thread_flag = False
     self._scan_bph_tmp_file(clean=True)
Beispiel #6
0
class BphTemplateServer(BphToolTemplateExecutor):

    BphToolTemplateExecutor.server_status = False
    BphToolTemplateExecutor.template_delivered = False

    def __init__(self):
        self.logger = Logger(level='INFO', module=self.__module__)
        self.thread_flag = False
        self._scan_bph_tmp_file(clean=True)

    def start(self):

        self.logger.log('Initializing BLACKPHENIX C&C Template Server...')

        try:
            serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        except socket.error as e:
            self.logger.log('Initialization Socket Error: {e}'.format(e.errno),
                            level='DEBUG')
        else:

            self._socket_handle = serversocket
            self.logger.log('Socket Ready')
            self._socket_handle.bind(
                (BPH_TEMPLATE_SERVER_IP, BPH_TEMPLATE_SERVER_PORT))
            self.logger.log('Starting server listener..')
            self._socket_handle.listen(0)
            self.logger.log('Accepting new connections now....')

            self.thread = threading.Thread(target=self.accept_connections,
                                           daemon=True)
            self.thread.start()

    def __cleanup(self, template_file):
        if os.path.isfile(template_file):
            self.logger.log('Removing template file: {}'.format(template_file),
                            level='DEBUG')
            try:
                os.remove(template_file)
            except OSError:
                self.logger.log(
                    'Error while deleting the file: {}'.format(template_file),
                    level='DEBUG')
            else:
                self.logger.log('File deleted: {}'.format(template_file),
                                level='DEBUG')

    def accept_connections(self):
        while True:

            try:
                # Accepting connections from Agent
                clientsocket, addr = self._socket_handle.accept()

                if clientsocket:
                    BphToolTemplateExecutor.server_status = True

                    self.logger.log(f"Agent connected: {addr}")

                    # Continuous scan for temporary template files
                    while True:
                        self.logger.log('Agent Loop...', level='DEBUG')
                        time.sleep(1)

                        template_file = self._scan_bph_tmp_file()
                        self.logger.log(
                            'Template File: {}'.format(template_file),
                            level='DEBUG')

                        if template_file is not None:
                            if os.path.isfile(template_file):
                                self.logger.log(
                                    'Template: {}'.format(template_file),
                                    level='DEBUG')

                                self.send_template(template_file, clientsocket)
                                template_file = None

            except (BrokenPipeError):
                self.logger.log('Agent down? Running server once again...')
                BphToolTemplateExecutor.server_status = False
                self.accept_connections()

    def send_template(self, template_file, clientsocket):
        self.logger.log('Delivering Template', level='DEBUG')
        BphToolTemplateExecutor.template_delivered = False

        # If temp template is found, send it to agent
        if os.path.isfile(
                template_file) and os.path.getsize(template_file) != 0:
            self.logger.log('Sending template...')

            self.logger.log(template_file, level='DEBUG')

            # Temp file is a Boxed & Pickled data
            tmp_file = open(template_file, 'rb')
            dat = tmp_file.read()

            clientsocket.send(dat)
            tmp_file.close()

            self.logger.log('Waiting response from client...')
            if clientsocket.recv(128) == b"ok":
                self.logger.log('Template was delivered correctly')
                self.__cleanup(template_file)
                BphToolTemplateExecutor.template_delivered = True

            else:
                self.logger.log('Template was not delivered correctly.')
                time.sleep(5)

    def stop(self):
        self.logger.log('Stopping Template server...')
        self._socket_handle.close()

    def restart(self):
        self.logger.log('Restarting Template Server')
        self.stop()
        self.start()
 def __init__(self, directory):
     self.directory = directory
     self.logger = Logger(level='INFO', module=self.__module__)
Beispiel #8
0
class BphSession:
 
    # Class variables are being used when a template is generated
    project_name = ""
    sample_md5 = ""  
    sid = ""
    sid_folder = ""      
    sample_folder = ""
    launcher_abs_path = ""
    
    def __init__(self, project_name=None):
        self.show_banner()
        self.logger = Logger(level='DEBUG', module=self.__module__)

        if project_name is not None:
            BphSession.project_name = project_name
        else:
            raise BphSessionNameException('Session Name was not provided')

        try:
            sample_abs_path = sys.argv[1]
        except IndexError:
            self.logger.log('Starting session without setting up a sample file...')
        else:
            self.tmp_sample_abs_path = sample_abs_path
            self.logger.log('Setting sample: {}'.format(self.tmp_sample_abs_path))
            BphSession.sample_md5 = LabFile.md5hash(self.tmp_sample_abs_path)
            
        # Session files, folders and identifiers here.
        self.project_folder = os.path.join(BPH_USER_DATA, BphSession.project_name)
        self.session_log_file = os.path.join(self.project_folder, 'session.log')
        self.launcher_folder = os.path.join(self.project_folder, 'launcher')
        
        self.project_folder_check()
        
        if BphSession.sample_md5 == '':
            self.sid_folder = os.path.join(BPH_USER_DATA, BphSession.project_name, '', BphSession.sid)
        else:
            self.sid_folder = os.path.join(BPH_USER_DATA, BphSession.project_name, BphSession.sample_md5, BphSession.sid)
            
        BphSession.sample_folder = os.path.join(BPH_USER_DATA, BphSession.project_name, BphSession.sample_md5)
        
        BphSession.sid_folder = self.sid_folder

        # Create session directory if doesn't exist.
        Directory(self.sid_folder).check_and_create()
        
        #self.collect_session_files()
            
    def show_banner(self):
        logo = r"""
            ____  __    ___   ________ __ ____  __  _________   _______  __
           / __ )/ /   /   | / ____/ //_// __ \/ / / / ____/ | / /  _/ |/ /
          / __  / /   / /| |/ /   / ,<  / /_/ / /_/ / __/ /  |/ // / |   / 
         / /_/ / /___/ ___ / /___/ /| |/ ____/ __  / /___/ /|  // / /   |  
        /_____/_____/_/  |_\____/_/ |_/_/   /_/ /_/_____/_/ |_/___//_/|_|
                                                             -=[v.1.0.0]=-
                                                              
                    MALWARE ANALYSIS + AUTOMATION FRAMEWORK
                   
                Developed by Chris Navarrete @ FortiGuard Labs
              
                       Copyright (c) 2019 Fortinet, Inc.
                       
                     Contact: [email protected]               
        """  
        print(colored(logo, 'green', attrs=['bold']))
            
    def project_folder_check(self):
        if os.path.isdir(self.project_folder):
            self.logger.log('Project folder already exists', level='DEBUG')
            
            if os.path.isfile(self.session_log_file):
                self.logger.log('Session log already exists', level='DEBUG')
                
                self.session_log(action='read')
                    
        else:
            self.logger.log('Generating sid...', level='DEBUG')
            BphSession.sid = self.generate_session_id()                  
        
        self.logger.log('Session ID: {}'.format(self.sid))
    
    @staticmethod       
    def get_session_id():
        return BphSession.sid
    
    def generate_session_id(self):
        return str(uuid.uuid4())        
    
    def session_log(self, action=None):
        
        if action == 'write':
            try:
                self.logger.log('Writing Session file...', level='DEBUG')
                log_file = open(self.session_log_file, 'w+')
                log_file.write(self.sid)
            except IOError:
                self.logger.log('Error when writing session log file', level='DEBUG')
            else:
                if os.path.isfile(self.session_log_file):
                    self.logger.log('Saved SessionID: {}'.format(self.sid), level='DEBUG')
                    self.logger.log(self.session_log_file, level='DEBUG')
            
        elif action == 'read':
            try:
                log_file = open(self.session_log_file, 'r')
                BphSession.sid = log_file.readline()
                log_file.close()
            except IOError:
                self.logger.log('Error when reading the log file.', level='DEBUG')
            else:
                self.logger.log('Stored SessionID: {}'.format(self.sid), level='DEBUG')
    
 
    def set_launcher(self, move_sample=True):
        try:
            if not os.path.isdir(self.launcher_folder):
                os.mkdir(self.launcher_folder)                
                
            sample_file_set = os.path.join(self.launcher_folder, os.path.split(self.tmp_sample_abs_path)[1])
    
            if not os.path.isfile(sample_file_set):
                if move_sample:
                    self.logger.log('MOVING SAMPLE', level='INFO')
                    shutil.move(self.tmp_sample_abs_path, self.launcher_folder)
                else:
                    self.logger.log('COPYING SAMPLE', level='INFO')
                    shutil.copy(self.tmp_sample_abs_path, self.launcher_folder)                
            
        except shutil.Error as e:
            self.logger.log('Error when copying the sample file: {}'.format(e), level='DEBUG')
            raise
        else:
            
            BphSession.launcher_abs_path = os.path.join(self.launcher_folder, os.path.basename(sample_file_set))
 
    def start(self):     
        self.logger.log('Starting session: {}'.format(self.project_name)) 
        if os.path.isdir(self.project_folder):
            self.logger.log('Session folder OK', level='DEBUG')
                        
            if os.path.isfile(self.session_log_file):
                self.logger.log('Session Log file OK', level='DEBUG')
                
                # Checking if file is empty
                with open(self.session_log_file, 'r') as lf:
                    if len(lf.readline()) == 0:
                        self.session_log(action='write')                
                    else:
                        self.session_log(action='read')
            else:
                self.logger.log('No session folder. Creating one...', level='DEBUG')
                self.session_log(action='write')
       
                
    def stop(self):
        self.logger.log('Stopping session: {}'.format(self.session_log_file))
        os.remove(self.session_log_file)
        
        
    def collect_session_files(self, tool_name=None):
        session_files = []
        for root, dirs, files in os.walk(self.sid_folder):
            if len(dirs) == 0 and len(files) != 0:
                for file in files:
                    file_abs_path = os.path.join(root, file)
                    
                    if tool_name is not None:
                        if tool_name in file:
                            print('Filtered: {}'.format(file_abs_path))
                            
                            if file not in session_files:
                                session_files.append(file_abs_path)
                    else:
                        print('Unfiltered: {}'.format(file_abs_path))

                        if file_abs_path not in session_files:
                            session_files.append(file_abs_path)
                            
        return session_files