Ejemplo n.º 1
0
 def send_response(self, code, message=None):
     super(KingPhisherRequestHandler, self).send_response(code, message)
     signals.send_safe('response-sent',
                       self.logger,
                       self,
                       code=code,
                       message=message)
Ejemplo n.º 2
0
def on_session_after_flush(session, flush_context):
	for signal, session_attribute in _flush_signal_map:
		objs = collections.defaultdict(list)
		for obj in getattr(session, session_attribute):
			objs[obj.__tablename__].append(obj)
		for table, targets in objs.items():
			signals.send_safe(signal, logger, table, targets=tuple(targets), session=session)
Ejemplo n.º 3
0
 def _handle_page_visit_creds(self, session, visit_id):
     username, password = self.get_query_creds()
     if username is None:
         return
     cred_count = 0
     query = session.query(db_models.Credential)
     query = query.filter_by(message_id=self.message_id,
                             username=username,
                             password=password)
     if query.count() == 0:
         cred = db_models.Credential(campaign_id=self.campaign_id,
                                     message_id=self.message_id,
                                     visit_id=visit_id)
         cred.username = username
         cred.password = password
         session.add(cred)
         session.commit()
         self.logger.debug(
             "credential id: {0} created for message id: {1}".format(
                 cred.id, cred.message_id))
         campaign = db_manager.get_row_by_id(session, db_models.Campaign,
                                             self.campaign_id)
         cred_count = len(campaign.credentials)
     if cred_count > 0 and ((cred_count in [1, 5, 10]) or
                            ((cred_count % 25) == 0)):
         self.server.job_manager.job_run(
             self.issue_alert,
             (self.campaign_id, 'credentials', cred_count))
     signals.send_safe('credentials-received',
                       self.logger,
                       self,
                       username=username,
                       password=password)
Ejemplo n.º 4
0
def forward_signal_update(mapper, connection, target):
    signals.send_safe('db-table-update',
                      logger,
                      target.__tablename__,
                      mapper=mapper,
                      connection=connection,
                      target=target)
Ejemplo n.º 5
0
def forward_signal_insert(mapper, connection, target):
    signals.send_safe('db-table-insert',
                      logger,
                      target.__tablename__,
                      mapper=mapper,
                      connection=connection,
                      target=target)
Ejemplo n.º 6
0
	def handle_email_opened(self, query):
		# image size: 43 Bytes
		img_data = '47494638396101000100800100000000ffffff21f90401000001002c00000000'
		img_data += '010001000002024c01003b'
		img_data = binascii.a2b_hex(img_data)
		self.send_response(200)
		self.send_header('Content-Type', 'image/gif')
		self.send_header('Content-Length', str(len(img_data)))
		self.end_headers()
		self.wfile.write(img_data)

		msg_id = self.get_query('id')
		if not msg_id:
			return
		self.semaphore_acquire()
		query = self._session.query(db_models.Message)
		query = query.filter_by(id=msg_id, opened=None)
		message = query.first()
		if message and not message.campaign.has_expired:
			message.opened = db_models.current_timestamp()
			message.opener_ip = self.get_client_ip()
			message.opener_user_agent = self.headers.get('user-agent', None)
			self._session.commit()
		signals.send_safe('email-opened', self.logger, self)
		self.semaphore_release()
Ejemplo n.º 7
0
def on_session_after_flush(session, flush_context):
	for signal, session_attribute in _flush_signal_map:
		objs = collections.defaultdict(list)
		for obj in getattr(session, session_attribute):
			objs[obj.__tablename__].append(obj)
		for table, targets in objs.items():
			signals.send_safe(signal, logger, table, targets=tuple(targets), session=session)
Ejemplo n.º 8
0
 def wrapper(handler_instance, *args, **kwargs):
     if log_call and rpc_logger.isEnabledFor(logging.DEBUG):
         args_repr = ', '.join(map(repr, args))
         if kwargs:
             for key, value in sorted(kwargs.items()):
                 args_repr += ", {0}={1!r}".format(key, value)
         msg = "calling RPC method {0}({1})".format(
             function.__name__, args_repr)
         rpc_logger.debug(msg)
     signals.send_safe('rpc-method-call',
                       rpc_logger,
                       path[1:-1],
                       request_handler=handler_instance,
                       args=args,
                       kwargs=kwargs)
     if database_access:
         session = db_manager.Session()
         try:
             result = function(handler_instance, session, *args,
                               **kwargs)
         finally:
             session.close()
     else:
         result = function(handler_instance, *args, **kwargs)
     signals.send_safe('rpc-method-called',
                       rpc_logger,
                       path[1:-1],
                       request_handler=handler_instance,
                       args=args,
                       kwargs=kwargs,
                       retval=result)
     return result
Ejemplo n.º 9
0
	def handle_email_opened(self, query):
		# image size: 43 Bytes
		img_data = '47494638396101000100800100000000ffffff21f90401000001002c00000000'
		img_data += '010001000002024c01003b'
		img_data = binascii.a2b_hex(img_data)
		self.send_response(200)
		self.send_header('Content-Type', 'image/gif')
		self.send_header('Content-Length', str(len(img_data)))
		self.end_headers()
		self.wfile.write(img_data)

		msg_id = self.get_query('id')
		if not msg_id:
			return
		self.semaphore_acquire()
		session = db_manager.Session()
		query = session.query(db_models.Message)
		query = query.filter_by(id=msg_id, opened=None)
		message = query.first()
		if message and not message.campaign.has_expired:
			message.opened = db_models.current_timestamp()
			message.opener_ip = self.get_client_ip()
			message.opener_user_agent = self.headers.get('user-agent', None)
			session.commit()
		session.close()
		signals.send_safe('email-opened', self.logger, self)
		self.semaphore_release()
Ejemplo n.º 10
0
	def _handle_page_visit_creds(self, campaign, visit_id):
		query_creds = self.get_query_creds()
		if query_creds.username is None:
			return
		cred_count = 0
		cred = self._get_db_creds(query_creds)
		if cred is None:
			if db_manager.get_row_by_id(self._session, db_models.Visit, self._visit_id) is None:
				self.logger.warning('discarding credentials because there is no visit associated with the request')
				return
			cred = db_models.Credential(
				campaign_id=campaign.id,
				message_id=self.message_id,
				visit_id=visit_id,
				**query_creds._asdict()
			)
			cred.regex_validated = db_validation.validate_credential(cred, campaign)
			self._session.add(cred)
			self._session.commit()
			self.logger.debug("credential id: {0} created for message id: {1}".format(cred.id, cred.message_id))
			campaign = db_manager.get_row_by_id(self._session, db_models.Campaign, self.campaign_id)
			cred_count = len(campaign.credentials)
		if cred_count > 0 and ((cred_count in [1, 5, 10]) or ((cred_count % 25) == 0)):
			self.server.job_manager.job_run(self.issue_alert, (self.campaign_id, 'credentials', cred_count))
		signals.send_safe('credentials-received', self.logger, self, username=query_creds.username, password=query_creds.password)
Ejemplo n.º 11
0
def rpc_logout(handler):
	rpc_session = handler.rpc_session
	if rpc_session.event_socket is not None:
		rpc_session.event_socket.close()
	handler.server.session_manager.remove(handler.rpc_session_id)
	logger = logging.getLogger('KingPhisher.Server.Authentication')
	logger.info("successful logout request from {0} for user {1}".format(handler.client_address[0], rpc_session.user))
	signals.send_safe('rpc-user-logged-out', logger, handler, session=handler.rpc_session_id, name=rpc_session.user)
Ejemplo n.º 12
0
def rpc_logout(handler):
	rpc_session = handler.rpc_session
	if rpc_session.event_socket is not None:
		rpc_session.event_socket.close()
	handler.server.session_manager.remove(handler.rpc_session_id)
	logger = logging.getLogger('KingPhisher.Server.Authentication')
	logger.info("successful logout request from {0} for user {1}".format(handler.client_address[0], rpc_session.user))
	signals.send_safe('rpc-user-logged-out', logger, handler, session=handler.rpc_session_id, name=rpc_session.user)
Ejemplo n.º 13
0
def rpc_login(handler, session, username, password, otp=None):
    logger = logging.getLogger('KingPhisher.Server.Authentication')
    if not ipaddress.ip_address(handler.client_address[0]).is_loopback:
        logger.warning(
            "failed login request from {0} for user {1}, (invalid source address)"
            .format(handler.client_address[0], username))
        raise ValueError('invalid source address for login')
    fail_default = (False, ConnectionErrorReason.ERROR_INVALID_CREDENTIALS,
                    None)
    fail_otp = (False, ConnectionErrorReason.ERROR_INVALID_OTP, None)

    if not (username and password):
        logger.warning(
            "failed login request from {0} for user {1}, (missing username or password)"
            .format(handler.client_address[0], username))
        return fail_default
    if not handler.server.forked_authenticator.authenticate(
            username, password):
        logger.warning(
            "failed login request from {0} for user {1}, (authentication failed)"
            .format(handler.client_address[0], username))
        return fail_default

    user = db_manager.get_row_by_id(session, db_models.User, username)
    if not user:
        logger.info('creating new user object with id: ' + username)
        user = db_models.User(id=username)
        session.add(user)
        session.commit()
    elif user.otp_secret:
        if otp is None:
            logger.debug(
                "failed login request from {0} for user {1}, (missing otp)".
                format(handler.client_address[0], username))
            return fail_otp
        if not (isinstance(otp, str) and len(otp) == 6 and otp.isdigit()):
            logger.warning(
                "failed login request from {0} for user {1}, (invalid otp)".
                format(handler.client_address[0], username))
            return fail_otp
        totp = pyotp.TOTP(user.otp_secret)
        now = datetime.datetime.now()
        if not otp in (totp.at(now + datetime.timedelta(seconds=offset))
                       for offset in (0, -30, 30)):
            logger.warning(
                "failed login request from {0} for user {1}, (invalid otp)".
                format(handler.client_address[0], username))
            return fail_otp
    session_id = handler.server.session_manager.put(username)
    logger.info("successful login request from {0} for user {1}".format(
        handler.client_address[0], username))
    signals.send_safe('rpc-user-logged-in',
                      logger,
                      handler,
                      session=session_id,
                      name=username)
    return True, ConnectionErrorReason.SUCCESS, session_id
Ejemplo n.º 14
0
		def wrapper(handler_instance, *args, **kwargs):
			if log_call:
				_log_rpc_call(handler_instance, function.__name__, *args, **kwargs)
			signals.send_safe('rpc-method-call', rpc_logger, path[1:-1], request_handler=handler_instance, args=args, kwargs=kwargs)
			if database_access:
				session = db_manager.Session()
				try:
					result = function(handler_instance, session, *args, **kwargs)
				finally:
					session.close()
			else:
				result = function(handler_instance, *args, **kwargs)
			signals.send_safe('rpc-method-called', rpc_logger, path[1:-1], request_handler=handler_instance, args=args, kwargs=kwargs, retval=result)
			return result
Ejemplo n.º 15
0
	def issue_alert(self, campaign_id, table, count):
		"""
		Send a campaign alert for the specified table.

		:param int campaign_id: The campaign subscribers to send the alert to.
		:param str table: The type of event to use as the sender when it is forwarded.
		:param int count: The number associated with the event alert.
		"""
		session = db_manager.Session()
		campaign = db_manager.get_row_by_id(session, db_models.Campaign, campaign_id)
		alert_subscriptions = tuple(subscription for subscription in campaign.alert_subscriptions if not subscription.has_expired)
		if not alert_subscriptions:
			self.server.logger.debug("no active alert subscriptions are present for campaign id: {0} ({1})".format(campaign.id, campaign.name))
			session.close()
			return
		if not signals.campaign_alert.receivers:
			self.server.logger.warning('users are subscribed to campaign alerts, and no signal handlers are connected')
			session.close()
			return
		if not signals.campaign_alert.has_receivers_for(table):
			self.server.logger.info('users are subscribed to campaign alerts, and no signal handlers are connected for sender: ' + table)
			session.close()
			return

		for subscription in alert_subscriptions:
			results = signals.send_safe('campaign-alert', self.server.logger, table, alert_subscription=subscription, count=count)
			if any((result for (_, result) in results)):
				continue
			self.server.logger.warning("user {0} is subscribed to campaign alerts, and no signal handlers succeeded to send an alert".format(subscription.user.name))
		session.close()
		return
Ejemplo n.º 16
0
def _send_safe_campaign_alerts(campaign, signal_name, sender, **kwargs):
    alert_subscriptions = tuple(
        subscription for subscription in campaign.alert_subscriptions
        if not subscription.has_expired)
    logger = logging.getLogger('KingPhisher.Server.CampaignAlerts')
    logger.debug(
        "dispatching campaign alerts for '{0}' (sender: {1!r}) to {2:,} active subscriptions"
        .format(signal_name, sender, len(alert_subscriptions)))
    if not alert_subscriptions:
        return
    signal = blinker.signal(signal_name)
    if not signal.receivers:
        logger.warning(
            "users are subscribed to '{0}', and no signal handlers are connected"
            .format(signal_name))
        return
    if not signal.has_receivers_for(sender):
        logger.info(
            "users are subscribed to '{0}', and no signal handlers are connected for sender: {1}"
            .format(signal_name, sender))
        return
    for subscription in alert_subscriptions:
        results = signals.send_safe(signal_name,
                                    logger,
                                    sender,
                                    alert_subscription=subscription,
                                    **kwargs)
        if any((result for (_, result) in results)):
            continue
        logger.warning(
            "user {0} is subscribed to '{1}', and no signal handlers succeeded to send an alert"
            .format(subscription.user.name, signal_name))
Ejemplo n.º 17
0
	def on_init(self):
		self.config = self.server.config
		regex_prefix = '^'
		if self.config.get('server.vhost_directories'):
			regex_prefix += r'[\w\.\-]+\/'
			for path, handler in self.handler_map.items():
				if path.startswith(rest_api.REST_API_BASE):
					del self.handler_map[path]
					self.handler_map[regex_prefix + path] = handler
		self.handler_map[regex_prefix + 'kpdd$'] = self.handle_deaddrop_visit
		self.handler_map[regex_prefix + 'kp\\.js$'] = self.handle_javascript_hook
		self.web_socket_handler = self.server.ws_manager.dispatch

		tracking_image = self.config.get('server.tracking_image')
		tracking_image = tracking_image.replace('.', '\\.')
		self.handler_map[regex_prefix + tracking_image + '$'] = self.handle_email_opened
		signals.send_safe('request-received', self.logger, self)
Ejemplo n.º 18
0
	def on_init(self):
		self.config = self.server.config
		regex_prefix = '^'
		if self.config.get('server.vhost_directories'):
			regex_prefix += r'[\w\.\-]+\/'
			for path, handler in self.handler_map.items():
				if path.startswith(rest_api.REST_API_BASE):
					del self.handler_map[path]
					self.handler_map[regex_prefix + path] = handler
		self.handler_map[regex_prefix + 'kpdd$'] = self.handle_deaddrop_visit
		self.handler_map[regex_prefix + 'kp\\.js$'] = self.handle_javascript_hook
		self.web_socket_handler = self.server.ws_manager.dispatch

		tracking_image = self.config.get('server.tracking_image')
		tracking_image = tracking_image.replace('.', '\\.')
		self.handler_map[regex_prefix + tracking_image + '$'] = self.handle_email_opened
		signals.send_safe('request-received', self.logger, self)
Ejemplo n.º 19
0
	def _handle_page_visit_creds(self, session, visit_id):
		username, password = self.get_query_creds()
		if username is None:
			return
		cred_count = 0
		query = session.query(db_models.Credential)
		query = query.filter_by(message_id=self.message_id, username=username, password=password)
		if query.count() == 0:
			cred = db_models.Credential(campaign_id=self.campaign_id, message_id=self.message_id, visit_id=visit_id)
			cred.username = username
			cred.password = password
			session.add(cred)
			session.commit()
			self.logger.debug("credential id: {0} created for message id: {1}".format(cred.id, cred.message_id))
			campaign = db_manager.get_row_by_id(session, db_models.Campaign, self.campaign_id)
			cred_count = len(campaign.credentials)
		if cred_count > 0 and ((cred_count in [1, 5, 10]) or ((cred_count % 25) == 0)):
			self.server.job_manager.job_run(self.issue_alert, (self.campaign_id, 'credentials', cred_count))
		signals.send_safe('credentials-received', self.logger, self, username=username, password=password)
Ejemplo n.º 20
0
    def _maintenance(self, interval):
        """
		Execute periodic maintenance related tasks.

		:param int interval: The interval of time (in seconds) at which this method is being executed.
		"""
        self.logger.debug('running periodic maintenance tasks')
        now = db_models.current_timestamp()
        session = db_manager.Session()
        campaigns = session.query(db_models.Campaign).filter(
            db_models.Campaign.expiration != None).filter(
                db_models.Campaign.expiration < now).filter(
                    db_models.Campaign.expiration >= now -
                    datetime.timedelta(seconds=interval))
        for campaign in campaigns:
            signals.send_safe('campaign-expired', self.logger, campaign)
            _send_safe_campaign_alerts(campaign, 'campaign-alert-expired',
                                       campaign)
        session.close()
Ejemplo n.º 21
0
		def wrapper(handler_instance, *args, **kwargs):
			if log_call and rpc_logger.isEnabledFor(logging.DEBUG):
				args_repr = ', '.join(map(repr, args))
				if kwargs:
					for key, value in sorted(kwargs.items()):
						args_repr += ", {0}={1!r}".format(key, value)
				msg = "calling RPC method {0}({1})".format(function.__name__, args_repr)
				rpc_logger.debug(msg)
			signals.send_safe('rpc-method-call', rpc_logger, path[1:-1], request_handler=handler_instance, args=args, kwargs=kwargs)
			if database_access:
				session = db_manager.Session()
				try:
					result = function(handler_instance, session, *args, **kwargs)
				finally:
					session.close()
			else:
				result = function(handler_instance, *args, **kwargs)
			signals.send_safe('rpc-method-called', rpc_logger, path[1:-1], request_handler=handler_instance, args=args, kwargs=kwargs, retval=result)
			return result
Ejemplo n.º 22
0
	def _maintenance(self, interval):
		"""
		Execute periodic maintenance related tasks.

		:param int interval: The interval of time (in seconds) at which this method is being executed.
		"""
		self.logger.debug('running periodic maintenance tasks')
		now = db_models.current_timestamp()
		session = db_manager.Session()
		campaigns = session.query(db_models.Campaign).filter(
			db_models.Campaign.expiration != None
		).filter(
			db_models.Campaign.expiration < now
		).filter(
			db_models.Campaign.expiration >= now - datetime.timedelta(seconds=interval)
		)
		for campaign in campaigns:
			signals.send_safe('campaign-expired', self.logger, campaign)
			_send_safe_campaign_alerts(campaign, 'campaign-alert-expired', campaign)
		session.close()
Ejemplo n.º 23
0
def rpc_login(handler, session, username, password, otp=None):
	logger = logging.getLogger('KingPhisher.Server.Authentication')
	if not ipaddress.ip_address(handler.client_address[0]).is_loopback:
		logger.warning("failed login request from {0} for user {1}, (invalid source address)".format(handler.client_address[0], username))
		raise ValueError('invalid source address for login')
	fail_default = (False, ConnectionErrorReason.ERROR_INVALID_CREDENTIALS, None)
	fail_otp = (False, ConnectionErrorReason.ERROR_INVALID_OTP, None)

	if not (username and password):
		logger.warning("failed login request from {0} for user {1}, (missing username or password)".format(handler.client_address[0], username))
		return fail_default
	if not handler.server.forked_authenticator.authenticate(username, password):
		logger.warning("failed login request from {0} for user {1}, (authentication failed)".format(handler.client_address[0], username))
		return fail_default

	user = session.query(db_models.User).filter_by(name=username).first()
	if not user:
		logger.info('creating new user object with name: ' + username)
		user = db_models.User(name=username)
	elif user.has_expired:
		logger.warning("failed login request from {0} for user {1}, (user has expired)".format(handler.client_address[0], username))
		return fail_default
	elif user.otp_secret:
		if otp is None:
			logger.debug("failed login request from {0} for user {1}, (missing otp)".format(handler.client_address[0], username))
			return fail_otp
		if not (isinstance(otp, str) and len(otp) == 6 and otp.isdigit()):
			logger.warning("failed login request from {0} for user {1}, (invalid otp)".format(handler.client_address[0], username))
			return fail_otp
		totp = pyotp.TOTP(user.otp_secret)
		now = datetime.datetime.now()
		if otp not in (totp.at(now + datetime.timedelta(seconds=offset)) for offset in (0, -30, 30)):
			logger.warning("failed login request from {0} for user {1}, (invalid otp)".format(handler.client_address[0], username))
			return fail_otp
	user.last_login = db_models.current_timestamp()
	session.add(user)
	session.commit()
	session_id = handler.server.session_manager.put(user.id)
	logger.info("successful login request from {0} for user {1}".format(handler.client_address[0], username))
	signals.send_safe('rpc-user-logged-in', logger, handler, session=session_id, name=username)
	return True, ConnectionErrorReason.SUCCESS, session_id
Ejemplo n.º 24
0
	def _handle_page_visit_creds(self, campaign, visit_id):
		query_creds = self.get_query_creds()
		if query_creds.username is None:
			return
		cred_count = 0
		cred = self._get_db_creds(query_creds)
		if cred is None:
			cred = db_models.Credential(
				campaign_id=campaign.id,
				message_id=self.message_id,
				visit_id=visit_id,
				**query_creds._asdict()
			)
			cred.regex_validated = db_validation.validate_credential(cred, campaign)
			self._session.add(cred)
			self._session.commit()
			self.logger.debug("credential id: {0} created for message id: {1}".format(cred.id, cred.message_id))
			campaign = db_manager.get_row_by_id(self._session, db_models.Campaign, self.campaign_id)
			cred_count = len(campaign.credentials)
		if cred_count > 0 and ((cred_count in [1, 5, 10]) or ((cred_count % 25) == 0)):
			self.server.job_manager.job_run(self.issue_alert, (self.campaign_id, 'credentials', cred_count))
		signals.send_safe('credentials-received', self.logger, self, username=query_creds.username, password=query_creds.password)
Ejemplo n.º 25
0
    def issue_alert(self, campaign_id, table, count):
        """
		Send a campaign alert for the specified table.

		:param int campaign_id: The campaign subscribers to send the alert to.
		:param str table: The type of event to use as the sender when it is forwarded.
		:param int count: The number associated with the event alert.
		"""
        session = db_manager.Session()
        campaign = db_manager.get_row_by_id(session, db_models.Campaign,
                                            campaign_id)
        now = datetime.datetime.utcnow()
        alert_subscriptions = tuple(
            subscription for subscription in campaign.alert_subscriptions
            if subscription.mute_timestamp is None
            or subscription.mute_timestamp > now)
        if not alert_subscriptions:
            self.server.logger.debug(
                "no active alert subscriptions are present for campaign id: {0} ({1})"
                .format(campaign.id, campaign.name))
            session.close()
            return
        if not signals.campaign_alert.receivers:
            self.server.logger.warning(
                'users are subscribed to campaign alerts, and no signal handlers are connected'
            )
            session.close()
            return
        if not signals.campaign_alert.has_receivers_for(table):
            self.server.logger.info(
                'users are subscribed to campaign alerts, and no signal handlers are connected for sender: '
                + table)
            session.close()
            return

        for subscription in alert_subscriptions:
            results = signals.send_safe('campaign-alert',
                                        self.server.logger,
                                        table,
                                        alert_subscription=subscription,
                                        count=count)
            if any((result for (_, result) in results)):
                continue
            self.server.logger.warning(
                "user {0} is subscribed to campaign alerts, and no signal handlers succeeded to send an alert"
                .format(subscription.user.id))
        session.close()
        return
Ejemplo n.º 26
0
def _send_safe_campaign_alerts(campaign, signal_name, sender, **kwargs):
	alert_subscriptions = tuple(subscription for subscription in campaign.alert_subscriptions if not subscription.has_expired)
	logger = logging.getLogger('KingPhisher.Server.CampaignAlerts')
	logger.debug("dispatching campaign alerts for '{0}' (sender: {1!r}) to {2:,} active subscriptions".format(signal_name, sender, len(alert_subscriptions)))
	if not alert_subscriptions:
		return
	signal = blinker.signal(signal_name)
	if not signal.receivers:
		logger.warning("users are subscribed to '{0}', and no signal handlers are connected".format(signal_name))
		return
	if not signal.has_receivers_for(sender):
		logger.info("users are subscribed to '{0}', and no signal handlers are connected for sender: {1}".format(signal_name, sender))
		return
	for subscription in alert_subscriptions:
		results = signals.send_safe(signal_name, logger, sender, alert_subscription=subscription, **kwargs)
		if any((result for (_, result) in results)):
			continue
		logger.warning("user {0} is subscribed to '{1}', and no signal handlers succeeded to send an alert".format(subscription.user.name, signal_name))
Ejemplo n.º 27
0
def forward_signal_delete(mapper, connection, target):
	signals.send_safe('db-table-delete', logger, target.__tablename__, mapper=mapper, connection=connection, target=target)
Ejemplo n.º 28
0
	def handle_page_visit(self):
		if not self.message_id:
			return
		if self.message_id == self.config.get('server.secret_id'):
			return
		if not self.campaign_id:
			return
		client_ip = self.get_client_ip()
		headers = []

		campaign = db_manager.get_row_by_id(self._session, db_models.Campaign, self.campaign_id)
		if campaign.has_expired:
			self.logger.info("ignoring page visit for expired campaign id: {0} from IP address: {1}".format(self.campaign_id, client_ip))
			return
		self.logger.info("handling a page visit for campaign id: {0} from IP address: {1}".format(self.campaign_id, client_ip))
		message = db_manager.get_row_by_id(self._session, db_models.Message, self.message_id)

		if message.opened is None and self.config.get('server.set_message_opened_on_visit'):
			message.opened = db_models.current_timestamp()
			message.opener_ip = self.get_client_ip()
			message.opener_user_agent = self.headers.get('user-agent', None)

		query = self._session.query(db_models.LandingPage)
		query = query.filter_by(campaign_id=self.campaign_id, hostname=self.vhost, page=self.request_path[1:])
		landing_page = query.first()

		set_new_visit = True
		visit_id = None
		if self.visit_id:
			visit_id = self.visit_id
			set_new_visit = False
			if landing_page:
				visit = db_manager.get_row_by_id(self._session, db_models.Visit, self.visit_id)
				if visit.message_id == self.message_id:
					visit.count += 1
					visit.last_seen = db_models.current_timestamp()
					self._session.commit()
				else:
					set_new_visit = True
					visit_id = None

		if visit_id is None:
			visit_id = utilities.make_visit_uid()

		if landing_page and set_new_visit:
			kp_cookie_name = self.config.get('server.cookie_name')
			cookie = "{0}={1}; Path=/; HttpOnly".format(kp_cookie_name, visit_id)
			headers.append(('Set-Cookie', cookie))
			visit = db_models.Visit(id=visit_id, campaign_id=self.campaign_id, message_id=self.message_id)
			visit.ip = client_ip
			visit.first_landing_page_id = landing_page.id
			visit.user_agent = self.headers.get('user-agent', '')
			self._session.add(visit)
			self._session.commit()
			self.logger.debug("visit id: {0} created for message id: {1}".format(visit_id, self.message_id))
			visit_count = len(campaign.visits)
			if visit_count > 0 and ((visit_count in (1, 10, 25)) or ((visit_count % 50) == 0)):
				self.server.job_manager.job_run(self.issue_alert, (self.campaign_id, 'visits', visit_count))
			signals.send_safe('visit-received', self.logger, self)

		self._handle_page_visit_creds(campaign, visit_id)
		trained = self.get_query('trained')
		if isinstance(trained, str) and trained.lower() in ['1', 'true', 'yes']:
			message.trained = True
			self._session.commit()
		return headers
Ejemplo n.º 29
0
	def send_response(self, code, message=None):
		super(KingPhisherRequestHandler, self).send_response(code, message)
		signals.send_safe('response-sent', self.logger, self, code=code, message=message)
Ejemplo n.º 30
0
def forward_signal_insert(mapper, connection, target):
	signals.send_safe('db-table-insert', logger, target.__tablename__, mapper=mapper, connection=connection, target=target)
Ejemplo n.º 31
0
	def handle_page_visit(self):
		if not self.message_id:
			return
		if self.message_id == self.config.get('server.secret_id'):
			return
		if not self.campaign_id:
			return
		client_ip = self.get_client_ip()

		session = db_manager.Session()
		campaign = db_manager.get_row_by_id(session, db_models.Campaign, self.campaign_id)
		if campaign.has_expired:
			self.logger.info("ignoring page visit for expired campaign id: {0} from IP address: {1}".format(self.campaign_id, client_ip))
			session.close()
			return
		self.logger.info("handling a page visit for campaign id: {0} from IP address: {1}".format(self.campaign_id, client_ip))
		message = db_manager.get_row_by_id(session, db_models.Message, self.message_id)

		if message.opened is None and self.config.get('server.set_message_opened_on_visit'):
			message.opened = db_models.current_timestamp()
			message.opener_ip = self.get_client_ip()
			message.opener_user_agent = self.headers.get('user-agent', None)

		query = session.query(db_models.LandingPage)
		query = query.filter_by(campaign_id=self.campaign_id, hostname=self.vhost, page=self.request_path[1:])
		landing_page = query.first()

		set_new_visit = True
		visit_id = None
		if self.visit_id:
			visit_id = self.visit_id
			set_new_visit = False
			if landing_page:
				visit = db_manager.get_row_by_id(session, db_models.Visit, self.visit_id)
				if visit.message_id == self.message_id:
					visit.count += 1
					visit.last_seen = db_models.current_timestamp()
					session.commit()
				else:
					set_new_visit = True
					visit_id = None

		if visit_id is None:
			visit_id = utilities.make_visit_uid()

		if landing_page and set_new_visit:
			kp_cookie_name = self.config.get('server.cookie_name')
			cookie = "{0}={1}; Path=/; HttpOnly".format(kp_cookie_name, visit_id)
			self.send_header('Set-Cookie', cookie)
			visit = db_models.Visit(id=visit_id, campaign_id=self.campaign_id, message_id=self.message_id)
			visit.ip = client_ip
			visit.first_landing_page_id = landing_page.id
			visit.user_agent = self.headers.get('user-agent', '')
			session.add(visit)
			session.commit()
			self.logger.debug("visit id: {0} created for message id: {1}".format(visit_id, self.message_id))
			visit_count = len(campaign.visits)
			if visit_count > 0 and ((visit_count in (1, 10, 25)) or ((visit_count % 50) == 0)):
				self.server.job_manager.job_run(self.issue_alert, (self.campaign_id, 'visits', visit_count))
			signals.send_safe('visit-received', self.logger, self)

		self._handle_page_visit_creds(session, visit_id)
		trained = self.get_query('trained')
		if isinstance(trained, str) and trained.lower() in ['1', 'true', 'yes']:
			message.trained = True
			session.commit()
		session.close()