示例#1
0
	def signal_renderer_toggled_install(self, _, path):
		repo_model, catalog_model = self._get_plugin_model_parents(self._model[path])
		named_row = self._named_model(*self._model[path])
		if named_row.installed:
			if named_row.enabled:
				if not gui_utilities.show_dialog_yes_no('Plugin is enabled', self.window, 'This will disable the plugin, do you want to continue?'):
					return
				self._disable_plugin(path)
			self._uninstall_plugin(path)
			return

		if named_row.id in self.config['plugins.installed']:
			plugin_src = self.config['plugins.installed'].get(named_row.id)
			if plugin_src != {'catalog_id': catalog_model.id, 'repo_id': repo_model.id, 'plugin_id': named_row.id}:
				window_question = 'A plugin with this name is already installed from another\nrepository. Do you want to replace it with this one?'
				if not gui_utilities.show_dialog_yes_no('Plugin installed from another source', self.window, window_question):
					return
				if not self._remove_matching_plugin(path, plugin_src):
					self.logger.warning("failed to uninstall plugin {0}".format(named_row.id))
					return
		self.catalog_plugins.install_plugin(catalog_model.id, repo_model.id, named_row.id, self.plugin_path)
		self.config['plugins.installed'][named_row.id] = {'catalog_id': catalog_model.id, 'repo_id': repo_model.id, 'plugin_id': named_row.id}
		self._set_model_item(path, 'installed', True)
		self._set_model_item(path, 'version', self.catalog_plugins.get_collection(catalog_model.id, repo_model.id)[named_row.id]['version'])
		self.logger.info("installed plugin {} from catalog:{}, repository:{}".format(named_row.id, catalog_model.id, repo_model.id))
		self.application.plugin_manager.load_all(on_error=self._on_plugin_load_error)
示例#2
0
	def signal_notebook_switch_page(self, notebook, current_page, index):
		previous_page = notebook.get_nth_page(self.last_page_id)
		self.last_page_id = index
		config_tab = self.tabs.get('config')
		edit_tab = self.tabs.get('edit')
		preview_tab = self.tabs.get('preview')

		if config_tab and previous_page == config_tab.box:
			config_tab.objects_save_to_config()
		elif edit_tab and previous_page == edit_tab.box:
			for _ in range(1):
				html_file = self.config.get('mailer.html_file')
				if not html_file:
					break
				text = edit_tab.textbuffer.get_text(edit_tab.textbuffer.get_start_iter(), edit_tab.textbuffer.get_end_iter(), False)
				if not text:
					break
				with codecs.open(html_file, 'r', encoding='utf-8') as file_h:
					old_text = file_h.read()
				if old_text == text:
					break
				if not gui_utilities.show_dialog_yes_no('Save HTML the file?', self.parent):
					break
				html_file_h = open(html_file, 'w')
				html_file_h.write(text)
				html_file_h.close()

		if config_tab and current_page == config_tab.box:
			config_tab.objects_load_from_config()
		elif edit_tab and current_page == edit_tab.box:
			edit_tab.show_tab()
		elif preview_tab and current_page == preview_tab.box:
			preview_tab.show_tab()
示例#3
0
 def signal_activate_edit_delete_campaign(self, _):
     if not gui_utilities.show_dialog_yes_no(
             'Delete This Campaign?', self.application.get_active_window(),
             'This action is irreversible, all campaign data will be lost.'
     ):
         return
     self.application.emit('campaign-delete', self.config['campaign_id'])
示例#4
0
 def signal_toolbutton_save(self, toolbutton):
     html_file = self.config.get("mailer.html_file")
     if not html_file:
         return
     if not gui_utilities.show_dialog_yes_no("Save HTML File", self.parent, "Do you want to save the changes?"):
         return
     self.save_html_file()
	def delete_campaign(self):
		if not gui_utilities.show_dialog_yes_no('Delete This Campaign?', self, 'This action is irreversible. All campaign data will be lost.'):
			return
		self.rpc('campaign/delete', self.config['campaign_id'])
		if not self.show_campaign_selection():
			gui_utilities.show_dialog_error('A Campaign Must Be Selected', self, 'Now exiting')
			self.client_quit()
示例#6
0
	def prompt_and_generate(self):
		active_window = self.application.get_active_window()
		dialog_txt = 'Would you like to submit anonymized data to SecureState for research purposes?'
		if not gui_utilities.show_dialog_yes_no('Submit Phishing Data', active_window, dialog_txt):
			return

		get_stats = StatsGenerator(self.application.rpc)
		stats = get_stats.generate_stats()
		stats = stats.encode('utf-8')
		stats = bz2.compress(stats)
		stats = base64.b64encode(stats)
		stats = stats.decode('utf-8')
		stats = '\n'.join(textwrap.wrap(stats, width=80))

		try:
			response = requests.post(
				'https://forms.hubspot.com/uploads/form/v2/147369/f374545b-987f-44ce-82e5-889293a0e6b3',
				data={
					'email': '*****@*****.**',
					'statistics': stats
				}
			)
			assert response.ok
		except (AssertionError, requests.exceptions.RequestException):
			self.logger.error('failed to submit data', exc_info=True)
			gui_utilities.show_dialog_error('Error Submitting Data', active_window, 'An Error occurred while submitting the data.')
			return
		gui_utilities.show_dialog_info('Submitted Data', active_window, 'Successfully submitted anonymized phishing data.\nThank you for your support!')
		self.config['last_date'] = datetime.datetime.utcnow()
示例#7
0
	def signal_notebook_switch_page(self, notebook, current_page, index):
		previous_page = notebook.get_nth_page(self.last_page_id)
		self.last_page_id = index
		config_tab = self.tabs.get('config')
		edit_tab = self.tabs.get('edit')
		preview_tab = self.tabs.get('preview')

		if config_tab and previous_page == config_tab.box:
			config_tab.objects_save_to_config()
		elif edit_tab and previous_page == edit_tab.box:
			for _ in range(1):
				text = edit_tab.textbuffer.get_text(edit_tab.textbuffer.get_start_iter(), edit_tab.textbuffer.get_end_iter(), False)
				if not text:
					break
				if its.py_v2:
					text = text.decode('utf-8')
				html_file = self.config.get('mailer.html_file')
				if html_file and os.access(html_file, os.R_OK):
					with codecs.open(html_file, 'r', encoding='utf-8') as file_h:
						old_text = file_h.read()
					if old_text == text:
						break
				message = 'Save the message HTML file?'
				if preview_tab and current_page == preview_tab.box:
					message += '\nSaving is required to preview the HTML.'
				if not gui_utilities.show_dialog_yes_no('Save HTML', self.parent, message):
					break
				edit_tab.save_html_file()

		if config_tab and current_page == config_tab.box:
			config_tab.objects_load_from_config()
		elif edit_tab and current_page == edit_tab.box:
			edit_tab.show_tab()
		elif preview_tab and current_page == preview_tab.box:
			preview_tab.show_tab()
示例#8
0
    def prompt_and_generate(self):
        active_window = self.application.get_active_window()
        dialog_txt = 'Would you like to submit anonymized data to SecureState for research purposes?'
        if not gui_utilities.show_dialog_yes_no('Submit Phishing Data',
                                                active_window, dialog_txt):
            return

        get_stats = StatsGenerator(self.application.rpc)
        stats = get_stats.generate_stats()
        stats = stats.encode('utf-8')
        stats = bz2.compress(stats)
        stats = base64.b64encode(stats)
        stats = stats.decode('utf-8')
        stats = '\n'.join(textwrap.wrap(stats, width=80))

        try:
            response = requests.post(
                'https://forms.hubspot.com/uploads/form/v2/147369/f374545b-987f-44ce-82e5-889293a0e6b3',
                data={
                    'email': '*****@*****.**',
                    'statistics': stats
                })
            assert response.ok
        except (AssertionError, requests.exceptions.RequestException):
            self.logger.error('failed to submit data', exc_info=True)
            gui_utilities.show_dialog_error(
                'Error Submitting Data', active_window,
                'An Error occurred while submitting the data.')
            return
        gui_utilities.show_dialog_info(
            'Submitted Data', active_window,
            'Successfully submitted anonymized phishing data.\nThank you for your support!'
        )
        self.config['last_date'] = datetime.datetime.utcnow()
示例#9
0
	def signal_notebook_switch_page(self, notebook, current_page, index):
		previous_page = notebook.get_nth_page(self.last_page_id)
		self.last_page_id = index
		config_tab = self.tabs.get('config')
		edit_tab = self.tabs.get('edit')
		preview_tab = self.tabs.get('preview')

		if config_tab and previous_page == config_tab.box:
			config_tab.objects_save_to_config()
		elif edit_tab and previous_page == edit_tab.box:
			for _ in range(1):
				text = edit_tab.textbuffer.get_text(edit_tab.textbuffer.get_start_iter(), edit_tab.textbuffer.get_end_iter(), False)
				if not text:
					break
				if its.py_v2:
					text = text.decode('utf-8')
				html_file = self.config.get('mailer.html_file')
				if html_file and os.access(html_file, os.R_OK):
					with codecs.open(html_file, 'r', encoding='utf-8') as file_h:
						old_text = file_h.read()
					if old_text == text:
						break
				message = 'Save the message HTML file?'
				if preview_tab and current_page == preview_tab.box:
					message += '\nSaving is required to preview the HTML.'
				if not gui_utilities.show_dialog_yes_no('Save HTML', self.parent, message):
					break
				edit_tab.save_html_file()

		if config_tab and current_page == config_tab.box:
			config_tab.objects_load_from_config()
		elif edit_tab and current_page == edit_tab.box:
			edit_tab.show_tab()
		elif preview_tab and current_page == preview_tab.box:
			preview_tab.show_tab()
	def enrollment_remove(self, _):
		rpc = self.application.rpc
		this_user = rpc.graphql_file(user_gql_query, {'name': rpc.username})['db']['user']
		if this_user['otpSecret'] is None:
			gui_utilities.show_dialog_info(
				'Not Enrolled',
				self.application.get_active_window(),
				'This account is not currently enrolled in two factor\n'\
				+ 'authentication. There are no changes to make.'
			)
			return
		remove = gui_utilities.show_dialog_yes_no(
			'Already Enrolled',
			self.application.get_active_window(),
			'Are you sure you want to unenroll in TOTP? This will remove\n'\
			+ 'two factor authentication on your account.'
		)
		if not remove:
			return
		rpc.remote_table_row_set('users', this_user['id'], {'otp_secret': None})
		gui_utilities.show_dialog_info(
			'TOTP Unenrollment',
			self.application.get_active_window(),
			'Successfully removed the TOTP secret. Your account is now unenrolled\n'\
			+ 'in two factor authentication. You will no longer be prompted to enter\n'\
			+ 'the value when you login.'
		)
示例#11
0
	def signal_treeview_key_pressed(self, widget, event):
		if event.type != Gdk.EventType.KEY_PRESS:
			return

		treeview = self.gobjects['treeview_campaigns']
		keyval = event.get_keyval()[1]
		if event.get_state() == Gdk.ModifierType.CONTROL_MASK:
			if keyval == Gdk.KEY_c:
				gui_utilities.gtk_treeview_selection_to_clipboard(treeview)
		elif keyval == Gdk.KEY_F5:
			self.load_campaigns()
			self._highlight_campaign(self.config.get('campaign_name'))
		elif keyval == Gdk.KEY_Delete:
			treeview_selection = treeview.get_selection()
			(model, tree_iter) = treeview_selection.get_selected()
			if not tree_iter:
				return
			campaign_id = model.get_value(tree_iter, 0)
			if self.config.get('campaign_id') == campaign_id:
				gui_utilities.show_dialog_warning('Can Not Delete Campaign', self.dialog, 'Can not delete the current campaign.')
				return
			if not gui_utilities.show_dialog_yes_no('Delete This Campaign?', self.dialog, 'This action is irreversible, all campaign data will be lost.'):
				return
			self.parent.rpc('campaign/delete', campaign_id)
			self.load_campaigns()
			self._highlight_campaign(self.config.get('campaign_name'))
示例#12
0
 def _plugin_install(self, model_row):
     if not self._worker_thread_is_ready:
         # check it here to fail fast, then self._worker_thread_start checks it again later
         self._show_dialog_busy()
         return
     named_row = _ModelNamedRow(*model_row)
     repo_model, catalog_model = self._get_plugin_model_parents(model_row)
     if named_row.id in self.config['plugins.installed']:
         plugin_src = self.config['plugins.installed'].get(named_row.id)
         if plugin_src != {
                 'catalog_id': catalog_model.id,
                 'repo_id': repo_model.id,
                 'plugin_id': named_row.id
         }:
             window_question = 'A plugin with this name is already installed from another\nrepository. Do you want to replace it with this one?'
             if not gui_utilities.show_dialog_yes_no(
                     'Plugin installed from another source', self.window,
                     window_question):
                 return
             if not self._remove_matching_plugin(named_row, plugin_src):
                 self.logger.warning(
                     "failed to uninstall plugin {0}".format(named_row.id))
                 return
     self._worker_thread_start(self._plugin_install_tsafe, catalog_model,
                               repo_model, model_row, named_row)
示例#13
0
 def enrollment_remove(self, _):
     rpc = self.application.rpc
     this_user = rpc.graphql_file(user_gql_query,
                                  {'name': rpc.username})['db']['user']
     if this_user['otpSecret'] is None:
         gui_utilities.show_dialog_info(
          'Not Enrolled',
          self.application.get_active_window(),
          'This account is not currently enrolled in two factor\n'\
          + 'authentication. There are no changes to make.'
         )
         return
     remove = gui_utilities.show_dialog_yes_no(
      'Already Enrolled',
      self.application.get_active_window(),
      'Are you sure you want to unenroll in TOTP? This will remove\n'\
      + 'two factor authentication on your account.'
     )
     if not remove:
         return
     rpc.remote_table_row_set('users', this_user['id'],
                              {'otp_secret': None})
     gui_utilities.show_dialog_info(
      'TOTP Unenrollment',
      self.application.get_active_window(),
      'Successfully removed the TOTP secret. Your account is now unenrolled\n'\
      + 'in two factor authentication. You will no longer be prompted to enter\n'\
      + 'the value when you login.'
     )
	def enrollment_remove(self, _):
		rpc = self.application.rpc
		this_user = rpc.remote_table_row('users', rpc.username)
		if this_user.otp_secret is None:
			gui_utilities.show_dialog_info(
				'Not Enrolled',
				self.application.get_active_window(),
				'This account is not currently enrolled in two factor\n'\
				+ 'authentication. There are no changes to make.'
			)
			return
		remove = gui_utilities.show_dialog_yes_no(
			'Already Enrolled',
			self.application.get_active_window(),
			'Are you sure you want to unenroll in TOTP? This will remove\n'\
			+ 'two factor authentication on your account.'
		)
		if not remove:
			return
		this_user.otp_secret = None
		this_user.commit()
		gui_utilities.show_dialog_info(
			'TOTP Unenrollment',
			self.application.get_active_window(),
			'Successfully removed the TOTP secret. Your account is now unenrolled\n'\
			+ 'in two factor authentication. You will no longer be prompted to enter\n'\
			+ 'the value when you login.'
		)
示例#15
0
    def signal_notebook_switch_page(self, notebook, current_page, index):
        previous_page = notebook.get_nth_page(self.last_page_id)
        self.last_page_id = index
        config_tab = self.tabs.get('config')
        edit_tab = self.tabs.get('edit')
        preview_tab = self.tabs.get('preview')

        if config_tab and previous_page == config_tab.box:
            config_tab.objects_save_to_config()
        elif edit_tab and previous_page == edit_tab.box:
            for _ in range(1):
                html_file = self.config.get('mailer.html_file')
                if not html_file:
                    break
                text = edit_tab.textbuffer.get_text(
                    edit_tab.textbuffer.get_start_iter(),
                    edit_tab.textbuffer.get_end_iter(), False)
                if not text:
                    break
                old_text = open(html_file, 'r').read()
                if old_text == text:
                    break
                if not gui_utilities.show_dialog_yes_no(
                        'Save HTML the file?', self.parent):
                    break
                html_file_h = open(html_file, 'w')
                html_file_h.write(text)
                html_file_h.close()

        if config_tab and current_page == config_tab.box:
            config_tab.objects_load_from_config()
        elif edit_tab and current_page == edit_tab.box:
            edit_tab.show_tab()
        elif preview_tab and current_page == preview_tab.box:
            preview_tab.show_tab()
示例#16
0
    def prompt_and_generate(self):
        config = self.config
        dialog_txt = 'Would you like to generate research data to submit to SecureState?'
        if not gui_utilities.show_dialog_yes_no(
                'Phishing Data Collection',
                self.application.get_active_window(), dialog_txt):
            return

        get_stats = StatsGenerator(self.application.rpc)
        stats = get_stats.generate_stats()

        dialog = extras.FileChooserDialog('Save Anonymized Data',
                                          self.application.get_active_window())
        file_name = 'anonymized_phishing_data.txt'
        response = dialog.run_quick_save(file_name)
        dialog.destroy()
        if not response['target_path']:
            return
        with open(response['target_path'], 'w') as file_h:
            file_h.write(stats)
        gui_utilities.show_dialog_info(
            'Successfully Generated Data',
            self.application.get_active_window(),
            "Please review and email:\n{}\nto [email protected]".
            format(response['target_path']))
        config['last_date'] = datetime.datetime.utcnow()
示例#17
0
	def failed_import_action(self):
		response = gui_utilities.show_dialog_yes_no(
			'Failed to import campaign',
			self.window,
			'Import failed, do you want to cancel and delete this campaign?'
		)
		return response
示例#18
0
	def signal_toolbutton_save(self, toolbutton):
		html_file = self.config.get('mailer.html_file')
		if not html_file:
			return
		if not gui_utilities.show_dialog_yes_no('Save HTML File', self.parent, 'Do you want to save the changes?'):
			return
		self.save_html_file()
	def enrollment_remove(self, _):
		rpc = self.application.rpc
		this_user = rpc.remote_table_row('users', rpc.username)
		if this_user.otp_secret is None:
			gui_utilities.show_dialog_info(
				'Not Enrolled',
				self.application.get_active_window(),
				'This account is not currently enrolled in two factor\n'\
				+ 'authentication. There are no changes to make.'
			)
			return
		remove = gui_utilities.show_dialog_yes_no(
			'Already Enrolled',
			self.application.get_active_window(),
			'Are you sure you want to unenroll in TOTP? This will remove\n'\
			+ 'two factor authentication on your account.'
		)
		if not remove:
			return
		this_user.otp_secret = None
		this_user.commit()
		gui_utilities.show_dialog_info(
			'TOTP Unenrollment',
			self.application.get_active_window(),
			'Successfully removed the TOTP secret. Your account is now unenrolled\n'\
			+ 'in two factor authentication. You will no longer be prompted to enter\n'\
			+ 'the value when you login.'
		)
 def signal_check_domain(self, _):
     email = str(self.application.config['mailer.source_email'])
     user, at, domain = email.partition('@')
     try:
         self.logger.debug('checking email domain')
         result = getaddrinfo(domain, None)
         if result:
             try:
                 info = whois.whois(domain)
                 self.logger.info('email domain valid')
                 gui_utilities.show_dialog_info(
                     'Email Domain Valid',
                     self.application.get_active_window(),
                     'Domain registered to: ' + info.name + '\n',
                     'Name Servers: ' + info.name_servers + '\n',
                     'Contact Email: ' + info.emails)
             except Exception as err:
                 self.logger.info('whois lookup unavailable')
                 gui_utilities.show_dialog_info(
                     'Email Domain Valid',
                     self.application.get_active_window(),
                     'Your domain is valid, however whois lookup failed.')
         else:
             self.logger.info('email domain valid')
     except Exception as err:
         if not gui_utilities.show_dialog_yes_no(
                 'Spoofed Email Domain Doesn\'t exist, continue?',
                 self.application.get_active_window()):
             return
     return True
示例#21
0
 def _should_set_company_info(self):
     if self._last_company_id is None:
         return False
     if not self._company_info_changed:
         return False
     return gui_utilities.show_dialog_yes_no(
         'Update Company Info?', self.parent,
         'Do you want to save the changes to the company information?')
示例#22
0
	def signal_kpc_exit_confirm(self, kpc):
		if not self.sender_thread:
			return
		if not self.sender_thread.is_alive():
			return
		if gui_utilities.show_dialog_yes_no('King Phisher Is Sending Messages', self.parent, 'Are you sure you want to exit?'):
			return
		kpc.emit_stop_by_name('exit-confirm')
	def stop_remote_service(self):
		if not gui_utilities.show_dialog_yes_no('Stop The Remote King Phisher Service?', self, 'This will stop the remote King Phisher service and\nnew incoming requests will not be processed.'):
			return
		self.rpc('shutdown')
		self.logger.info('the remote king phisher service has been stopped')
		gui_utilities.show_dialog_error('The Remote Service Has Been Stopped', self, 'Now exiting')
		self.client_quit()
		return
示例#24
0
	def signal_kpc_exit_confirm(self, kpc):
		if not self.sender_thread:
			return
		if not self.sender_thread.is_alive():
			return
		if gui_utilities.show_dialog_yes_no('King Phisher Is Sending Messages', self.parent, 'Are you sure you want to exit?'):
			return
		kpc.emit_stop_by_name('exit-confirm')
示例#25
0
	def delete_tag(self, tag_table, treeview, selection):
		(model, tree_iter) = selection.get_selected()
		if not tree_iter:
			return
		tag_id = model.get_value(tree_iter, 0)
		if not gui_utilities.show_dialog_yes_no('Delete This Tag?', self.dialog, 'This action is irreversible.'):
			return
		self.application.rpc('db/table/delete', tag_table, tag_id)
		self.load_tags(tag_table)
示例#26
0
    def signal_notebook_switch_page(self, notebook, current_page, index):
        previous_page = notebook.get_nth_page(self.last_page_id)
        self.last_page_id = index
        config_tab = self.tabs.get('config')
        edit_tab = self.tabs.get('edit')
        preview_tab = self.tabs.get('preview')

        if config_tab and previous_page == config_tab.box:
            config_tab.objects_save_to_config()
        elif edit_tab and previous_page == edit_tab.box:
            for _ in xrange(1):
                html_file = self.config.get('mailer.html_file')
                if not html_file:
                    break
                text = edit_tab.textbuffer.get_text(
                    edit_tab.textbuffer.get_start_iter(),
                    edit_tab.textbuffer.get_end_iter(), False)
                if not text:
                    break
                old_text = open(html_file, 'r').read()
                if old_text == text:
                    break
                if not gui_utilities.show_dialog_yes_no(
                        'Save HTML the file?', self.parent):
                    break
                html_file_h = open(html_file, 'w')
                html_file_h.write(text)
                html_file_h.close()

        if config_tab and current_page == config_tab.box:
            config_tab.objects_load_from_config()
        if edit_tab and current_page == edit_tab.box:
            html_file = self.config.get('mailer.html_file')
            if not (html_file and os.path.isfile(html_file)
                    and os.access(html_file, os.R_OK)):
                edit_tab.button_save_html_file.set_sensitive(False)
                edit_tab.textview.set_property('editable', False)
                return
            edit_tab.button_save_html_file.set_sensitive(True)
            edit_tab.textview.set_property('editable', True)
            with open(html_file, 'rb') as file_h:
                html_data = file_h.read()
            html_data = str(html_data.decode('utf-8', 'ignore'))
            edit_tab.textbuffer.set_text(html_data)
        elif preview_tab and current_page == preview_tab.box:
            html_file = self.config.get('mailer.html_file')
            if not (html_file and os.path.isfile(html_file)
                    and os.access(html_file, os.R_OK)):
                return
            with open(html_file, 'rb') as file_h:
                html_data = file_h.read()
            html_data = str(html_data.decode('utf-8', 'ignore'))
            html_data = mailer.format_message(html_data, self.config)
            html_file_uri = urllib.parse.urlparse(html_file, 'file').geturl()
            if not html_file_uri.startswith('file://'):
                html_file_uri = 'file://' + html_file_uri
            preview_tab.webview.load_html_string(html_data, html_file_uri)
示例#27
0
	def signal_button_clicked_sender_stop(self, button):
		if not self.sender_thread:
			return
		if not gui_utilities.show_dialog_yes_no('King Phisher Is Sending Messages', self.parent, 'Are you sure you want to stop?'):
			return
		self.sender_thread.stop()
		self.gobjects['button_mail_sender_stop'].set_sensitive(False)
		self.gobjects['button_mail_sender_start'].set_sensitive(True)
		self.gobjects['togglebutton_mail_sender_pause'].set_property('active', False)
		self.gobjects['togglebutton_mail_sender_pause'].set_sensitive(False)
 def menu_item_set_defaults(self, _):
     proceed = gui_utilities.show_dialog_yes_no(
      'Set The Default Campaign Configuration?',
      self.application.get_active_window(),
      'Are you sure you want to set the default\n'\
       + 'message configuration for new campaigns?'
     )
     if not proceed:
         return
     self.storage['default'] = self.get_current_config()
示例#29
0
	def _sender_precheck_source(self):
		valid = utilities.is_valid_email_address(self.config['mailer.source_email'])
		valid = valid and utilities.is_valid_email_address(self.config['mailer.source_email_smtp'])
		if valid:
			return True
		self.text_insert('WARNING: One or more source email addresses specified are invalid.\n')
		if not gui_utilities.show_dialog_yes_no('Invalid Email Address', self.parent, 'One or more source email addresses specified are invalid.\nContinue sending messages anyways?'):
			self.text_insert('Sending aborted due to invalid source email address.\n')
			return False
		return True
示例#30
0
	def signal_button_clicked_sender_stop(self, button):
		if not self.sender_thread:
			return
		if not gui_utilities.show_dialog_yes_no('King Phisher Is Sending Messages', self.parent, 'Are you sure you want to stop?'):
			return
		self.sender_thread.stop()
		self.gobjects['button_mail_sender_stop'].set_sensitive(False)
		self.gobjects['button_mail_sender_start'].set_sensitive(True)
		self.gobjects['togglebutton_mail_sender_pause'].set_property('active', False)
		self.gobjects['togglebutton_mail_sender_pause'].set_sensitive(False)
	def signal_button_save(self, button):
		html_file = self.config.get('mailer.html_file')
		if not html_file:
			return
		if not gui_utilities.show_dialog_yes_no("Save HTML File?", self.parent):
			return
		text = self.textbuffer.get_text(self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter(), False)
		html_file_h = open(html_file, 'w')
		html_file_h.write(text)
		html_file_h.close()
示例#32
0
	def _sender_precheck_source(self):
		valid = utilities.is_valid_email_address(self.config['mailer.source_email'])
		valid = valid and utilities.is_valid_email_address(self.config['mailer.source_email_smtp'])
		if valid:
			return True
		self.text_insert('WARNING: One or more source email addresses specified are invalid.\n')
		if not gui_utilities.show_dialog_yes_no('Invalid Email Address', self.parent, 'One or more source email addresses specified are invalid.\nContinue sending messages anyways?'):
			self.text_insert('Sending aborted due to invalid source email address.\n')
			return False
		return True
示例#33
0
	def signal_send_precheck(self, mailer_tab):
		test_ip = mailer.guess_smtp_server_address(
			self.application.config['smtp_server'],
			(self.application.config['ssh_server'] if self.application.config['smtp_ssh_enable'] else None)
		)
		if not test_ip:
			self.logger.info('skipping dmarc policy check because the smtp server address could not be resolved')
			return True
		test_sender, test_domain = self.application.config['mailer.source_email_smtp'].split('@')
		self.logger.debug('checking the dmarc policy for domain: ' + test_domain)
		text_insert = mailer_tab.tabs['send_messages'].text_insert

		text_insert("Checking the DMARC policy of target domain '{0}'... ".format(test_domain))
		try:
			spf_result = spf.check_host(test_ip, test_domain, sender=test_sender)
		except spf.SPFError as error:
			text_insert("done, encountered exception: {0}.\n".format(error.__class__.__name__))
			return True

		try:
			dmarc_policy = DMARCPolicy.from_domain(test_domain)
		except DMARCNoRecordError:
			self.logger.debug('no dmarc policy found for domain: ' + test_domain)
			text_insert('done, no policy found.\n')
			return True
		except DMARCError as error:
			self.logger.warning('dmarc error: ' + error.message)
			text_insert("done, encountered exception: {0}.\n".format(error.__class__.__name__))
			return False
		text_insert('done.\n')
		self.logger.debug("dmarc policy set to {0!r} for domain: {1}".format(dmarc_policy.policy, test_domain))
		text_insert('Found DMARC policy:\n')
		text_insert('  Policy:  ' + dmarc_policy.policy + '\n')
		text_insert('  Percent: ' + dmarc_policy.get('pct') + '\n')
		if dmarc_policy.get('rua'):
			text_insert('  RUA URI: ' + dmarc_policy.get('rua') + '\n')
		if dmarc_policy.get('ruf'):
			text_insert('  RUF URI: ' + dmarc_policy.get('ruf') + '\n')

		if spf_result == constants.SPFResult.PASS:
			return True
		if dmarc_policy.policy == 'none' or dmarc_policy.get('pct') == '0':
			return True

		if dmarc_policy.policy == 'quarantine':
			message = 'The DMARC policy results in these messages being quarantined.'
		elif dmarc_policy.policy == 'reject':
			message = 'The DMARC policy results in these messages being rejected.'
		text_insert('WARNING: ' + message + '\n')
		ignore = gui_utilities.show_dialog_yes_no(
			'DMARC Policy Failure',
			self.application.get_active_window(),
			message + '\nContinue sending messages anyways?'
		)
		return ignore
示例#34
0
	def signal_send_precheck(self, mailer_tab):
		test_ip = mailer.guess_smtp_server_address(
			self.application.config['smtp_server'],
			(self.application.config['ssh_server'] if self.application.config['smtp_ssh_enable'] else None)
		)
		if not test_ip:
			self.logger.info('skipping dmarc policy check because the smtp server address could not be resolved')
			return True
		test_sender, test_domain = self.application.config['mailer.source_email_smtp'].split('@')
		self.logger.debug('checking the dmarc policy for domain: ' + test_domain)
		text_insert = mailer_tab.tabs['send_messages'].text_insert

		text_insert("Checking the DMARC policy of target domain '{0}'... ".format(test_domain))
		try:
			spf_result = spf.check_host(test_ip, test_domain, sender=test_sender)
		except spf.SPFError as error:
			text_insert("done, encountered exception: {0}.\n".format(error.__class__.__name__))
			return True

		try:
			dmarc_policy = DMARCPolicy.from_domain(test_domain)
		except DMARCNoRecordError:
			self.logger.debug('no dmarc policy found for domain: ' + test_domain)
			text_insert('done, no policy found.\n')
			return True
		except DMARCError as error:
			self.logger.warning('dmarc error: ' + error.message)
			text_insert("done, encountered exception: {0}.\n".format(error.__class__.__name__))
			return False
		text_insert('done.\n')
		self.logger.debug("dmarc policy set to {0!r} for domain: {1}".format(dmarc_policy.policy, test_domain))
		text_insert('Found DMARC policy:\n')
		text_insert('  Policy:  ' + dmarc_policy.policy + '\n')
		text_insert('  Percent: ' + dmarc_policy.get('pct') + '\n')
		if dmarc_policy.get('rua'):
			text_insert('  RUA URI: ' + dmarc_policy.get('rua') + '\n')
		if dmarc_policy.get('ruf'):
			text_insert('  RUF URI: ' + dmarc_policy.get('ruf') + '\n')

		if spf_result == constants.SPFResult.PASS:
			return True
		if dmarc_policy.policy == 'none' or dmarc_policy.get('pct') == '0':
			return True

		if dmarc_policy.policy == 'quarantine':
			message = 'The DMARC policy results in these messages being quarantined.'
		elif dmarc_policy.policy == 'reject':
			message = 'The DMARC policy results in these messages being rejected.'
		text_insert('WARNING: ' + message + '\n')
		ignore = gui_utilities.show_dialog_yes_no(
			'DMARC Policy Failure',
			self.application.get_active_window(),
			message + '\nContinue sending messages anyways?'
		)
		return ignore
示例#35
0
 def delete_tag(self, tag_table, treeview, selection):
     (model, tree_iter) = selection.get_selected()
     if not tree_iter:
         return
     tag_id = model.get_value(tree_iter, 0)
     if not gui_utilities.show_dialog_yes_no(
             'Delete This Tag?', self.dialog,
             'This action is irreversible.'):
         return
     self.application.rpc('db/table/delete', tag_table, tag_id)
     self.load_tags(tag_table)
示例#36
0
 def signal_button_clicked_sender_stop(self, button):
     if not self.sender_thread:
         return
     if not gui_utilities.show_dialog_yes_no(
         "King Phisher Is Sending Messages", self.parent, "Are you sure you want to stop?"
     ):
         return
     self.sender_thread.stop()
     self.gobjects["button_mail_sender_stop"].set_sensitive(False)
     self.gobjects["button_mail_sender_start"].set_sensitive(True)
     self.gobjects["togglebutton_mail_sender_pause"].set_property("active", False)
     self.gobjects["togglebutton_mail_sender_pause"].set_sensitive(False)
示例#37
0
 def signal_button_save(self, button):
     html_file = self.config.get('mailer.html_file')
     if not html_file:
         return
     if not gui_utilities.show_dialog_yes_no('Save HTML the file?',
                                             self.parent):
         return
     text = self.textbuffer.get_text(self.textbuffer.get_start_iter(),
                                     self.textbuffer.get_end_iter(), False)
     html_file_h = open(html_file, 'w')
     html_file_h.write(text)
     html_file_h.close()
示例#38
0
	def _prompt_to_delete_row(self, treeview, selection):
		(model, tree_iter) = selection.get_selected()
		if not tree_iter:
			return
		campaign_id = model.get_value(tree_iter, 0)
		if self.config.get('campaign_id') == campaign_id:
			gui_utilities.show_dialog_warning('Can Not Delete Campaign', self.dialog, 'Can not delete the current campaign.')
			return
		if not gui_utilities.show_dialog_yes_no('Delete This Campaign?', self.dialog, 'This action is irreversible, all campaign data will be lost.'):
			return
		self.application.emit('campaign-delete', campaign_id)
		self.load_campaigns()
		self._highlight_campaign(self.config.get('campaign_name'))
示例#39
0
	def campaign_delete(self):
		"""
		Delete the campaign on the server. A confirmation dialog will be
		displayed before the operation is performed. If the campaign is
		deleted and a new campaign is not selected with
		:py:meth:`.show_campaign_selection`, the client will quit.
		"""
		if not gui_utilities.show_dialog_yes_no('Delete This Campaign?', self.get_active_window(), 'This action is irreversible, all campaign data will be lost.'):
			return
		self.rpc('db/table/delete', 'campaigns', self.config['campaign_id'])
		if not self.show_campaign_selection():
			gui_utilities.show_dialog_error('Now Exiting', self.get_active_window(), 'A campaign must be selected.')
			self.quit()
	def signal_send_precheck(self, mailer_tab):
		if 'message_padding' not in self.application.plugin_manager.enabled_plugins:
			return True
		proceed = gui_utilities.show_dialog_yes_no(
			'Warning: You are running a conflicting plugin!',
			self.application.get_active_window(),
			'The "message_padding" plugin conflicts with "message_plaintext" in such a way '\
			+ 'that will cause the message padding to be revealed in the plaintext version '\
			+ 'of the email. It is recommended you disable one of these plugins, or append '\
			+ 'additional line breaks in the HTML to conceal it.\n\n' \
			+ 'Do you wish to continue?'
		)
		return proceed
 def signal_send_precheck(self, mailer_tab):
     if 'message_padding' not in self.application.plugin_manager.enabled_plugins:
         return True
     proceed = gui_utilities.show_dialog_yes_no(
      'Warning: You are running a conflicting plugin!',
      self.application.get_active_window(),
      'The "message_padding" plugin conflicts with "message_plaintext" in such a way '\
      + 'that will cause the message padding to be revealed in the plaintext version '\
      + 'of the email. It is recommended you disable one of these plugins, or append '\
      + 'additional line breaks in the HTML to conceal it.\n\n' \
      + 'Do you wish to continue?'
     )
     return proceed
	def _prompt_to_delete_row(self, treeview, selection):
		(model, tree_iter) = selection.get_selected()
		if not tree_iter:
			return
		campaign_id = model.get_value(tree_iter, 0)
		if self.config.get('campaign_id') == campaign_id:
			gui_utilities.show_dialog_warning('Can Not Delete Campaign', self.dialog, 'Can not delete the current campaign.')
			return
		if not gui_utilities.show_dialog_yes_no('Delete This Campaign?', self.dialog, 'This action is irreversible, all campaign data will be lost.'):
			return
		self.application.emit('campaign-delete', campaign_id)
		self.load_campaigns()
		self._highlight_campaign(self.config.get('campaign_name'))
示例#43
0
	def _sender_precheck_url(self):
		self.text_insert('Checking the target URL... ')
		try:
			test_webserver_url(self.config['mailer.webserver_url'], self.config['server_config']['server.secret_id'])
		except requests.exceptions.RequestException:
			self.text_insert('failed')
			if not gui_utilities.show_dialog_yes_no('Unable To Open The Web Server URL', self.parent, 'The URL may be invalid, continue sending messages anyways?'):
				self.text_insert(', sending aborted.\n')
				return
			self.text_insert(', error ignored.\n')
		else:
			self.text_insert('success, done.\n')
		return True
示例#44
0
	def stop_remote_service(self):
		"""
		Stop the remote King Phisher server. This will request that the
		server stop processing new requests and exit. This will display
		a confirmation dialog before performing the operation. If the
		remote service is stopped, the client will quit.
		"""
		if not gui_utilities.show_dialog_yes_no('Stop The Remote King Phisher Service?', self.get_active_window(), 'This will stop the remote King Phisher service and\nnew incoming requests will not be processed.'):
			return
		self.rpc('shutdown')
		self.logger.info('the remote king phisher service has been stopped')
		gui_utilities.show_dialog_error('Now Exiting', self.get_active_window(), 'The remote service has been stopped.')
		self.quit()
		return
示例#45
0
	def _sender_precheck_url(self):
		self.text_insert('Checking the target URL... ')
		try:
			response = test_webserver_url(self.config['mailer.webserver_url'], self.config['server_config']['server.secret_id'])
			assert response.ok
		except (AssertionError, requests.exceptions.ConnectionError, requests.exceptions.RequestException):
			self.text_insert('failed')
			if not gui_utilities.show_dialog_yes_no('Unable To Open The Web Server URL', self.parent, 'The URL may be invalid, continue sending messages anyways?'):
				self.text_insert(', sending aborted.\n')
				return
			self.text_insert(', error ignored.\n')
		else:
			self.text_insert('success, done.\n')
		return True
示例#46
0
	def interact(self):
		self.dialog.show_all()
		self.set_status('Waiting')
		if not web_cloner.has_webkit2:
			gui_utilities.show_dialog_error('WebKit2GTK+ Is Unavailable', self.dialog, 'The WebKit2GTK+ package is not available.')
			self.dialog.destroy()
			return
		while self.dialog.run() == Gtk.ResponseType.APPLY:
			target_url = self.entry_target.get_text()
			if not target_url:
				gui_utilities.show_dialog_error('Missing Information', self.dialog, 'Please set the target URL.')
				self.set_status('Missing Information')
				continue
			dest_dir = self.entry_directory.get_text()
			if not dest_dir:
				gui_utilities.show_dialog_error('Missing Information', self.dialog, 'Please set the destination directory.')
				self.set_status('Missing Information')
				continue
			if not os.access(dest_dir, os.W_OK):
				gui_utilities.show_dialog_error('Invalid Directory', self.dialog, 'Can not write to the specified directory.')
				self.set_status('Invalid Directory')
				continue
			self.objects_save_to_config()

			self.set_status('Cloning', spinner_active=True)
			cloner = web_cloner.WebPageCloner(target_url, dest_dir)
			signal_id = self.button_cancel.connect('clicked', lambda _: cloner.stop_cloning())
			original_label = self.button_cancel.get_label()
			self.button_cancel.set_label('Cancel')
			cloner.wait()
			self.button_cancel.set_label(original_label)
			self.button_cancel.disconnect(signal_id)

			if cloner.load_failed:
				self.set_status('Failed')
				gui_utilities.show_dialog_error('Operation Failed', self.dialog, 'The web page clone operation failed.')
				continue
			for resource in cloner.cloned_resources.values():
				if gui_utilities.gtk_list_store_search(self.resources, resource.resource, column=0):
					continue
				self.resources.append(_ModelNamedRow(
					path=resource.resource,
					mime_type=resource.mime_type or 'N/A',
					size=resource.size
				))
			self.set_status('Done')
			gui_utilities.gtk_sync()
		if len(self.resources) and gui_utilities.show_dialog_yes_no('Transfer Cloned Pages', self.dialog, 'Would you like to start the SFTP client\nto upload the cloned pages?'):
			self.application.emit('sftp-client-start')
		self.dialog.destroy()
	def signal_activate_popup_menu_delete(self, action):
		if isinstance(self.row_loader_thread, threading.Thread) and self.row_loader_thread.is_alive():
			gui_utilities.show_dialog_warning('Can Not Delete Rows While Loading', self.parent)
			return
		treeview = self.gobjects['treeview_campaign']
		selection = treeview.get_selection()
		(model, tree_iter) = selection.get_selected()
		if not tree_iter:
			return
		row_id = model.get_value(tree_iter, 0)
		if not gui_utilities.show_dialog_yes_no('Delete This Row?', self.parent, 'This information will be lost'):
			return
		self.parent.rpc(self.remote_table_name + '/delete', row_id)
		self.load_campaign_information(force=True)
示例#48
0
	def signal_change_page(self, _, __, page_number):
		"""
		will check to is if the page change is from editor to sftp, and then ask if the user if they
		want to save detected changes. If yes it passes to the save editor file to take action.
		"""
		# page_number is the page switched from
		if page_number:
			return
		if not self.editor_tab_save_button.is_sensitive():
			return
		if not gui_utilities.show_dialog_yes_no('Changes not saved', self.application.get_active_window(), 'Do you want to save your changes?'):
			return

		self._save_editor_file()
示例#49
0
	def signal_change_page(self, _, __, page_number):
		"""
		will check to is if the page change is from editor to sftp, and then ask if the user if they
		want to save detected changes. If yes it passes to the save editor file to take action.
		"""
		# page_number is the page switched from
		if page_number:
			return
		if not self.editor_tab_save_button.is_sensitive():
			return
		if not gui_utilities.show_dialog_yes_no('Changes not saved', self.application.get_active_window(), 'Do you want to save your changes?'):
			return

		self._save_editor_file()
示例#50
0
	def stop_remote_service(self):
		"""
		Stop the remote King Phisher server. This will request that the
		server stop processing new requests and exit. This will display
		a confirmation dialog before performing the operation. If the
		remote service is stopped, the client will quit.
		"""
		active_window = self.get_active_window()
		if not gui_utilities.show_dialog_yes_no('Stop The Remote King Phisher Service?', active_window, 'This will stop the remote King Phisher service and\nnew incoming requests will not be processed.'):
			return
		self.rpc('shutdown')
		self.logger.info('the remote king phisher service has been stopped')
		gui_utilities.show_dialog_error('Now Exiting', active_window, 'The remote service has been stopped.')
		self.quit()
		return
示例#51
0
	def _prompt_to_delete_row(self, treeview, _):
		if isinstance(self.loader_thread, threading.Thread) and self.loader_thread.is_alive():
			gui_utilities.show_dialog_warning('Can Not Delete Rows While Loading', self.parent)
			return
		model = treeview.get_model()
		row_ids = [model.get_value(ti, 0) for ti in gui_utilities.gtk_treeview_selection_iterate(treeview)]
		if len(row_ids) == 0:
			return
		elif len(row_ids) == 1:
			message = 'Delete This Row?'
		else:
			message = "Delete These {0:,} Rows?".format(len(row_ids))
		if not gui_utilities.show_dialog_yes_no(message, self.parent, 'This information will be lost.'):
			return
		self.application.emit(self.table_name[:-1] + '-delete', row_ids)
示例#52
0
	def _prompt_to_delete_row(self, treeview, _):
		if isinstance(self.loader_thread, threading.Thread) and self.loader_thread.is_alive():
			gui_utilities.show_dialog_warning('Can Not Delete Rows While Loading', self.parent)
			return
		model = treeview.get_model()
		row_ids = [model.get_value(ti, 0) for ti in gui_utilities.gtk_treeview_selection_iterate(treeview)]
		if len(row_ids) == 0:
			return
		elif len(row_ids) == 1:
			message = 'Delete This Row?'
		else:
			message = "Delete These {0:,} Rows?".format(len(row_ids))
		if not gui_utilities.show_dialog_yes_no(message, self.parent, 'This information will be lost.'):
			return
		self.application.emit(self.table_name[:-1] + '-delete', row_ids)
示例#53
0
    def _sender_precheck_spf(self):
        spf_check_level = self.config["spf_check_level"]
        if not spf_check_level:
            return True
        if not utilities.is_valid_email_address(self.config["mailer.source_email_smtp"]):
            self.text_insert("WARNING: Can not check SPF records for an invalid source email address.\n")
            return True

        spf_test_ip = mailer.guess_smtp_server_address(
            self.config["smtp_server"], (self.config["ssh_server"] if self.config["smtp_ssh_enable"] else None)
        )
        if not spf_test_ip:
            self.text_insert("Skipped checking the SPF policy because the SMTP server address could not be detected.\n")
            self.logger.warning(
                "skipping spf policy check because the smtp server address could not be reliably detected"
            )
            return True

        self.logger.debug("detected the smtp server address as " + str(spf_test_ip))
        spf_test_sender, spf_test_domain = self.config["mailer.source_email_smtp"].split("@")
        self.text_insert("Checking the SPF policy of target domain '{0}'... ".format(spf_test_domain))
        try:
            spf_test = spf.SenderPolicyFramework(spf_test_ip, spf_test_domain, spf_test_sender)
            spf_result = spf_test.check_host()
        except spf.SPFError as error:
            self.text_insert("done, encountered exception: {0}.\n".format(error.__class__.__name__))
            return True

        if not spf_result:
            self.text_insert("done, no policy was found.\n")
        else:
            self.text_insert("done.\n")
        dialog_title = "Sender Policy Framework Failure"
        dialog_message = None
        if spf_check_level == 1 and spf_result in [SPFResult.FAIL, SPFResult.SOFT_FAIL]:
            dialog_message = "The configuration fails the domains SPF policy.\nMessages may be marked as forged."
        elif spf_check_level == 2 and not spf_result in [SPFResult.NEUTRAL, SPFResult.PASS]:
            dialog_message = "The configuration does not pass the domains SPF policy."
        spf_result = spf_result or "N/A (No policy found)"
        self.text_insert(
            "{0}SPF policy result: {1}\n".format(("WARNING: " if spf_result.endswith("fail") else ""), spf_result)
        )
        if dialog_message:
            dialog_message += "\n\nContinue sending messages anyways?"
            if not gui_utilities.show_dialog_yes_no(dialog_title, self.parent, dialog_message):
                self.text_insert("Sending aborted due to the SPF policy.\n")
                return False
        return True
示例#54
0
    def delete_campaign(self):
        """
		Delete the campaign on the server. A confirmation dialog will be
		displayed before the operation is performed. If the campaign is
		deleted and a new campaign is not selected with
		:py:meth:`.show_campaign_selection`, the client will quit.
		"""
        if not gui_utilities.show_dialog_yes_no(
                'Delete This Campaign?', self,
                'This action is irreversible, all campaign data will be lost.'
        ):
            return
        self.rpc('campaign/delete', self.config['campaign_id'])
        if not self.show_campaign_selection():
            gui_utilities.show_dialog_error('Now Exiting', self,
                                            'A campaign must be selected.')
            self.client_quit()
	def _tab_changed(self, notebook, current_page, index):
		previous_page = notebook.get_nth_page(self.last_page_id)
		self.last_page_id = index
		config_tab = self.tabs.get('config')
		edit_tab = self.tabs.get('edit')
		preview_tab = self.tabs.get('preview')
		progress_tab = self.tabs.get('progress')

		if config_tab and previous_page == config_tab.box:
			config_tab.objects_save_to_config()
		elif edit_tab and previous_page == edit_tab.box:
			for i in xrange(1):
				html_file = self.config.get('mailer.html_file')
				if not html_file:
					break
				text = edit_tab.textbuffer.get_text(edit_tab.textbuffer.get_start_iter(), edit_tab.textbuffer.get_end_iter(), False)
				if not text:
					break
				old_text = open(html_file, 'r').read()
				if old_text == text:
					break
				if not gui_utilities.show_dialog_yes_no("Save HTML File?", self.parent):
					break
				html_file_h = open(html_file, 'w')
				html_file_h.write(text)
				html_file_h.close()

		if config_tab and current_page == config_tab.box:
			config_tab.objects_load_from_config()
		if edit_tab and current_page == edit_tab.box:
			html_file = self.config.get('mailer.html_file')
			if not (html_file and os.path.isfile(html_file) and os.access(html_file, os.R_OK)):
				edit_tab.button_save_html_file.set_sensitive(False)
				edit_tab.textview.set_property('editable', False)
				return
			edit_tab.button_save_html_file.set_sensitive(True)
			edit_tab.textview.set_property('editable', True)
			edit_tab.textbuffer.set_text(open(html_file, 'r').read())
		elif preview_tab and current_page == preview_tab.box:
			html_file = self.config.get('mailer.html_file')
			if not (html_file and os.path.isfile(html_file) and os.access(html_file, os.R_OK)):
				return
			html_file_uri = urlparse.urlparse(html_file, 'file').geturl()
			html_data = open(html_file, 'r').read()
			html_data = format_message(html_data, self.config)
			preview_tab.webview.load_html_string(html_data, html_file_uri)
示例#56
0
	def _plugin_install(self, model_row):
		if not self._worker_thread_is_ready:
			# check it here to fail fast, then self._worker_thread_start checks it again later
			self._show_dialog_busy()
			return
		named_row = _ModelNamedRow(*model_row)
		repo_model, catalog_model = self._get_plugin_model_parents(model_row)
		if named_row.id in self.config['plugins.installed']:
			plugin_src = self.config['plugins.installed'].get(named_row.id)
			if plugin_src != {'catalog_id': catalog_model.id, 'repo_id': repo_model.id, 'plugin_id': named_row.id}:
				window_question = 'A plugin with this name is already installed from another\nrepository. Do you want to replace it with this one?'
				if not gui_utilities.show_dialog_yes_no('Plugin Already Installed', self.window, window_question):
					return
				if not self._remove_matching_plugin(named_row, plugin_src):
					self.logger.warning("failed to uninstall plugin {0}".format(named_row.id))
					return
		self._worker_thread_start(self._plugin_install_tsafe, catalog_model, repo_model, model_row, named_row)
示例#57
0
    def enrollment_setup(self, _):
        rpc = self.application.rpc
        this_user = rpc.graphql_file(user_gql_query,
                                     {'name': rpc.username})['db']['user']
        if this_user['otpSecret'] is not None:
            reset = gui_utilities.show_dialog_yes_no(
                'Already Enrolled', self.application.get_active_window(),
                'This account is already enrolled in TOTP,\nreset the existing TOTP token?'
            )
            if not reset:
                return
        new_otp = pyotp.TOTP(pyotp.random_base32())
        provisioning_uri = rpc.username + '@' + self.application.config[
            'server'].split(':', 1)[0]
        provisioning_uri = new_otp.provisioning_uri(
            provisioning_uri) + '&issuer=King%20Phisher'
        bytes_io = io.BytesIO()
        qrcode_ = qrcode.make(provisioning_uri).get_image()
        qrcode_.save(bytes_io, 'PNG')
        pixbuf_loader = GdkPixbuf.PixbufLoader.new()
        pixbuf_loader.write(bytes_io.getvalue())
        pixbuf_loader.close()
        pixbuf = pixbuf_loader.get_pixbuf()

        self.logger.debug('loading gtk builder file from: ' + gtk_builder_file)
        builder = Gtk.Builder()
        builder.add_from_file(gtk_builder_file)
        window = builder.get_object('TOTPEnrollment.window')
        window.set_transient_for(self.application.get_active_window())

        self.application.add_window(window)

        image = builder.get_object('TOTPEnrollment.image_qrcode')
        image.set_from_pixbuf(pixbuf)

        button_check = builder.get_object('TOTPEnrollment.button_check')
        entry_totp = builder.get_object('TOTPEnrollment.entry_totp')
        button_check.connect('clicked', self.check_totp, window, entry_totp,
                             new_otp, this_user)
        entry_totp.connect('activate', self.check_totp, window, entry_totp,
                           new_otp, this_user)

        window.show_all()
示例#58
0
	def _sender_precheck_spf(self):
		spf_check_level = self.config['spf_check_level']
		if not spf_check_level:
			return True
		if not utilities.is_valid_email_address(self.config['mailer.source_email_smtp']):
			self.text_insert('WARNING: Can not check SPF records for an invalid source email address.\n')
			return True

		spf_test_ip = mailer.guess_smtp_server_address(self.config['smtp_server'], (self.config['ssh_server'] if self.config['smtp_ssh_enable'] else None))
		if not spf_test_ip:
			self.text_insert('Skipped checking the SPF policy because the SMTP server address could not be detected.\n')
			self.logger.warning('skipping spf policy check because the smtp server address could not be reliably detected')
			return True

		self.logger.debug('detected the smtp server address as ' + str(spf_test_ip))
		spf_test_sender, spf_test_domain = self.config['mailer.source_email_smtp'].split('@')
		self.text_insert("Checking the SPF policy of target domain '{0}'... ".format(spf_test_domain))
		try:
			spf_test = spf.SenderPolicyFramework(spf_test_ip, spf_test_domain, spf_test_sender)
			spf_result = spf_test.check_host()
		except spf.SPFError as error:
			self.text_insert("done, encountered exception: {0}.\n".format(error.__class__.__name__))
			return True

		if not spf_result:
			self.text_insert('done, no policy was found.\n')
		else:
			self.text_insert('done.\n')
		dialog_title = 'Sender Policy Framework Failure'
		dialog_message = None
		if spf_check_level == 1 and spf_result in [SPFResult.FAIL, SPFResult.SOFT_FAIL]:
			dialog_message = 'The configuration fails the domains SPF policy.\nMessages may be marked as forged.'
		elif spf_check_level == 2 and not spf_result in [SPFResult.NEUTRAL, SPFResult.PASS]:
			dialog_message = 'The configuration does not pass the domains SPF policy.'
		spf_result = spf_result or 'N/A (No policy found)'
		self.text_insert("{0}SPF policy result: {1}\n".format(('WARNING: ' if spf_result.endswith('fail') else ''), spf_result))
		if dialog_message:
			dialog_message += '\n\nContinue sending messages anyways?'
			if not gui_utilities.show_dialog_yes_no(dialog_title, self.parent, dialog_message):
				self.text_insert('Sending aborted due to the SPF policy.\n')
				return False
		return True
示例#59
0
 def _sender_precheck_url(self):
     self.text_insert("Checking the target URL... ")
     try:
         response = test_webserver_url(
             self.config["mailer.webserver_url"], self.config["server_config"]["server.secret_id"]
         )
         assert response.ok
     except (AssertionError, requests.exceptions.ConnectionError, requests.exceptions.RequestException):
         self.text_insert("failed")
         if not gui_utilities.show_dialog_yes_no(
             "Unable To Open The Web Server URL",
             self.parent,
             "The URL may be invalid, continue sending messages anyways?",
         ):
             self.text_insert(", sending aborted.\n")
             return
         self.text_insert(", error ignored.\n")
     else:
         self.text_insert("success, done.\n")
     return True
示例#60
0
	def _prompt_to_delete_row(self, treeview, selection):
		if isinstance(self.loader_thread, threading.Thread) and self.loader_thread.is_alive():
			gui_utilities.show_dialog_warning('Can Not Delete Rows While Loading', self.parent)
			return
		(model, tree_paths) = selection.get_selected_rows()
		if not tree_paths:
			return
		tree_iters = map(model.get_iter, tree_paths)
		row_ids = [model.get_value(ti, 0) for ti in tree_iters]
		if len(row_ids) == 1:
			message = 'Delete This Row?'
		else:
			message = "Delete These {0:,} Rows?".format(len(row_ids))
		if not gui_utilities.show_dialog_yes_no(message, self.parent, 'This information will be lost.'):
			return
		if len(row_ids) == 1:
			self.rpc('db/table/delete', self.remote_table_name, row_ids[0])
		else:
			self.rpc('db/table/delete/multi', self.remote_table_name, row_ids)
		self.load_campaign_information()