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 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.safe_send('email-opened', self.logger, self)
def __init__(self, timeout='30m'): """ :param timeout: The length of time in seconds for which sessions are valid. :type timeout: int, str """ self.logger = logging.getLogger('KingPhisher.Server.SessionManager') timeout = smoke_zephyr.utilities.parse_timespan(timeout) self.session_timeout = datetime.timedelta(seconds=timeout) self._sessions = {} self._lock = threading.Lock() # get valid sessions from the database expired = 0 session = db_manager.Session() oldest = db_models.current_timestamp() - self.session_timeout for stored_session in session.query(db_models.AuthenticatedSession): if stored_session.last_seen < oldest: expired += 1 continue auth_session = AuthenticatedSession.from_db_authenticated_session(stored_session) self._sessions[stored_session.id] = auth_session session.query(db_models.AuthenticatedSession).delete() session.commit() self.logger.info("restored {0:,} valid session{1} and skipped {2:,} expired session{3} from the database".format( len(self._sessions), ('' if len(self._sessions) == 1 else 's'), expired, ('' if expired == 1 else 's') ))
def __init__(self, timeout='30m'): """ :param timeout: The length of time in seconds for which sessions are valid. :type timeout: int, str """ self.logger = logging.getLogger('KingPhisher.Server.SessionManager') timeout = smoke_zephyr.utilities.parse_timespan(timeout) self.session_timeout = datetime.timedelta(seconds=timeout) self._sessions = {} self._lock = threading.Lock() # get valid sessions from the database expired = 0 session = db_manager.Session() oldest = db_models.current_timestamp() - self.session_timeout for stored_session in session.query(db_models.AuthenticatedSession): if stored_session.last_seen < oldest: expired += 1 continue auth_session = AuthenticatedSession.from_db_authenticated_session( stored_session) self._sessions[stored_session.id] = auth_session session.query(db_models.AuthenticatedSession).delete() session.commit() self.logger.info( "restored {0:,} valid session{1} and skipped {2:,} expired session{3} from the database" .format(len(self._sessions), ('' if len(self._sessions) == 1 else 's'), expired, ('' if expired == 1 else 's')))
def __init__(self, user): """ :param user: The unique identifier for the authenticated user. """ self.user = user self.created = db_models.current_timestamp() self.last_seen = self.created self._event_socket = None
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_if_exists('server.set_message_opened_on_visit', True): message.opened = db_models.current_timestamp() message.opener_ip = self.get_client_ip() message.opener_user_agent = self.headers.get('user-agent', None) set_new_visit = True visit_id = make_uid() if self.visit_id: set_new_visit = False query = session.query(db_models.LandingPage) query = query.filter_by(campaign_id=self.campaign_id, hostname=self.vhost, page=self.request_path[1:]) if query.count(): visit = db_manager.get_row_by_id(session, db_models.Visit, self.visit_id) if visit.message_id == self.message_id: visit_id = self.visit_id visit.visit_count += 1 else: set_new_visit = True if 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.visitor_ip = client_ip visit.visitor_details = self.headers.get('user-agent', '') session.add(visit) visit_count = len(campaign.visits) if visit_count > 0 and ((visit_count in [1, 10, 25]) or ((visit_count % 50) == 0)): alert_text = "{0} visits reached for campaign: {{campaign_name}}".format(visit_count) self.server.job_manager.job_run(self.issue_alert, (alert_text, self.campaign_id)) 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()
def __init__(self, user): """ :param user: The user object of the authenticated user. :type user: :py:class:`~king_phisher.server.database.models.User` """ self.user = user.id self.user_is_admin = user.is_admin self.created = db_models.current_timestamp() self.last_seen = self.created self._event_socket = None
def rpc_test_login(self, username, password, otp=None): session = db_manager.Session() user = session.query(db_models.User).filter_by(name=username).first() if not user: user = db_models.User(name=username) user.last_login = db_models.current_timestamp() session.add(user) session.commit() session_id = self.server.session_manager.put(user) session.close() return True, constants.ConnectionErrorReason.SUCCESS, session_id
def clean(self): """Remove sessions which have expired.""" should_lock = not self._lock.locked() if should_lock: self._lock.acquire() oldest = db_models.current_timestamp() - self.session_timeout remove = [] for session_id, session in self._sessions.items(): if session.last_seen < oldest: remove.append(session_id) for session_id in remove: del self._sessions[session_id] if should_lock: self._lock.release() return
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 = db_models.current_timestamp() 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
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()
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()
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
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) 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
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 session = db_manager.Session() query = session.query(db_models.Message) query = query.filter_by(id=msg_id, opened=None) message = query.first() if message: message.opened = db_models.current_timestamp() session.commit() session.close()
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 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()
def get(self, session_id, update_timestamp=True): """ Look up an :py:class:`.AuthenticatedSession` instance from it's unique identifier and optionally update the last seen timestamp. If the session is not found or has expired, None will be returned. :param str session_id: The unique identifier of the session to retrieve. :param bool update_timestamp: Whether or not to update the last seen timestamp for the session. :return: The session if it exists and is active. :rtype: :py:class:`.AuthenticatedSession` """ if session_id is None: return None now = db_models.current_timestamp() with self._lock: session = self._sessions.get(session_id) if session is None: return None if session.last_seen < now - self.session_timeout: del self._sessions[session_id] return None if update_timestamp: session.last_seen = now return session
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()
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_if_exists( 'server.set_message_opened_on_visit', True): message.opened = db_models.current_timestamp() message.opener_ip = self.get_client_ip() message.opener_user_agent = self.headers.get('user-agent', None) set_new_visit = True visit_id = None if self.visit_id: visit_id = self.visit_id set_new_visit = False query = session.query(db_models.LandingPage) query = query.filter_by(campaign_id=self.campaign_id, hostname=self.vhost, page=self.request_path[1:]) if query.count(): visit = db_manager.get_row_by_id(session, db_models.Visit, self.visit_id) if visit.message_id == self.message_id: visit.visit_count += 1 visit.last_visit = db_models.current_timestamp() else: set_new_visit = True visit_id = None if visit_id is None: visit_id = make_uid() if 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.visitor_ip = client_ip visit.visitor_details = self.headers.get('user-agent', '') session.add(visit) visit_count = len(campaign.visits) if visit_count > 0 and ((visit_count in (1, 10, 25)) or ((visit_count % 50) == 0)): alert_text = "{0} visits reached for campaign: {{campaign_name}}".format( visit_count) self.server.job_manager.job_run(self.issue_alert, (alert_text, self.campaign_id)) signals.safe_send('visit-received', self.logger, self) if visit_id is None: self.logger.error('the visit id has not been set') raise RuntimeError('the visit id has not been set') 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()
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 self.logger.info( "handling a page visit for campaign id: {0} from IP address: {1}". format(self.campaign_id, self.client_address[0])) message_id = self.message_id campaign_id = self.campaign_id session = db_manager.Session() campaign = db_manager.get_row_by_id(session, db_models.Campaign, self.campaign_id) message = db_manager.get_row_by_id(session, db_models.Message, self.message_id) if message.opened == None and self.config.get_if_exists( 'server.set_message_opened_on_visit', True): message.opened = db_models.current_timestamp() set_new_visit = True if self.visit_id: set_new_visit = False visit_id = self.visit_id query = session.query(db_models.LandingPage) query = query.filter_by(campaign_id=self.campaign_id, hostname=self.vhost, page=self.request_path[1:]) if query.count(): visit = db_manager.get_row_by_id(session, db_models.Visit, visit_id) if visit.message_id == message_id: visit.visit_count += 1 else: set_new_visit = True if set_new_visit: visit_id = make_uid() 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=campaign_id, message_id=message_id) visit.visitor_ip = self.client_address[0] visit.visitor_details = self.headers.get('user-agent', '') session.add(visit) visit_count = len(campaign.visits) if visit_count > 0 and ((visit_count in [1, 10, 25]) or ((visit_count % 50) == 0)): alert_text = "{0} vists reached for campaign: {{campaign_name}}".format( visit_count) self.server.job_manager.job_run(self.issue_alert, (alert_text, campaign_id)) username = None for pname in ['username', 'user', 'u']: username = (self.get_query_parameter(pname) or self.get_query_parameter(pname.title()) or self.get_query_parameter(pname.upper())) if username: break if username: password = None for pname in ['password', 'pass', 'p']: password = (self.get_query_parameter(pname) or self.get_query_parameter(pname.title()) or self.get_query_parameter(pname.upper())) if password: break password = (password or '') cred_count = 0 query = session.query(db_models.Credential) query = query.filter_by(message_id=message_id, username=username, password=password) if query.count() == 0: cred = db_models.Credential(campaign_id=campaign_id, message_id=message_id, visit_id=visit_id) cred.username = username cred.password = password session.add(cred) cred_count = len(campaign.credentials) if cred_count > 0 and ((cred_count in [1, 5, 10]) or ((cred_count % 25) == 0)): alert_text = "{0} credentials submitted for campaign: {{campaign_name}}".format( cred_count) self.server.job_manager.job_run(self.issue_alert, (alert_text, campaign_id)) trained = self.get_query_parameter('trained') if isinstance(trained, str) and trained.lower() in ['1', 'true', 'yes']: message.trained = True session.commit() session.close()
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
def handle_deaddrop_visit(self, query): self.send_response(200) self.end_headers() data = self.get_query('token') if not data: self.logger.warning('dead drop request received with no \'token\' parameter') return try: data = base64.b64decode(data) except (binascii.Error, TypeError): self.logger.error('dead drop request received with invalid \'token\' data') return data = xor.xor_decode(data) try: data = json.loads(data) except ValueError: self.logger.error('dead drop request received with invalid \'token\' data') return deaddrop_id = data.get('deaddrop_id') if deaddrop_id is None: self.logger.error('dead drop request received with no \'deaddrop_id\' key') return elif deaddrop_id == self.config.get('server.secret_id'): # this allows us to test the logic to this point at least self.logger.debug('dead drop request received with the test id') return self.semaphore_acquire() deployment = db_manager.get_row_by_id(self._session, db_models.DeaddropDeployment, deaddrop_id) if not deployment: self.semaphore_release() self.logger.error('dead drop request received for an unknown campaign') return if deployment.campaign.has_expired: self.semaphore_release() self.logger.info('dead drop request received for an expired campaign') return local_username = data.get('local_username') local_hostname = data.get('local_hostname') if local_username is None or local_hostname is None: self.semaphore_release() self.logger.error('dead drop request received with missing data') return local_ip_addresses = data.get('local_ip_addresses') if isinstance(local_ip_addresses, (list, tuple)): local_ip_addresses = ' '.join(local_ip_addresses) query = self._session.query(db_models.DeaddropConnection) query = query.filter_by(deployment_id=deployment.id, local_username=local_username, local_hostname=local_hostname) connection = query.first() if connection: connection.count += 1 connection.last_seen = db_models.current_timestamp() new_connection = False else: connection = db_models.DeaddropConnection(campaign_id=deployment.campaign_id, deployment_id=deployment.id) connection.ip = self.get_client_ip() connection.local_username = local_username connection.local_hostname = local_hostname connection.local_ip_addresses = local_ip_addresses self._session.add(connection) new_connection = True self._session.commit() query = self._session.query(db_models.DeaddropConnection) query = query.filter_by(campaign_id=deployment.campaign_id) visit_count = query.count() self.semaphore_release() if new_connection and visit_count > 0 and ((visit_count in [1, 3, 5]) or ((visit_count % 10) == 0)): self.server.job_manager.job_run(self.issue_alert, (deployment.campaign_id, 'deaddrop_connections', visit_count)) return
def handle_deaddrop_visit(self, query): self.send_response(200) self.end_headers() data = self.get_query('token') if not data: self.logger.warning('dead drop request received with no \'token\' parameter') return try: data = base64.b64decode(data) except (binascii.Error, TypeError): self.logger.error('dead drop request received with invalid \'token\' data') return data = xor.xor_decode(data) try: data = json.loads(data) except ValueError: self.logger.error('dead drop request received with invalid \'token\' data') return self.semaphore_acquire() session = db_manager.Session() deployment = db_manager.get_row_by_id(session, db_models.DeaddropDeployment, data.get('deaddrop_id')) if not deployment: session.close() self.semaphore_release() self.logger.error('dead drop request received for an unknown campaign') return if deployment.campaign.has_expired: session.close() self.semaphore_release() self.logger.info('dead drop request received for an expired campaign') return local_username = data.get('local_username') local_hostname = data.get('local_hostname') if local_username is None or local_hostname is None: session.close() self.semaphore_release() self.logger.error('dead drop request received with missing data') return local_ip_addresses = data.get('local_ip_addresses') if isinstance(local_ip_addresses, (list, tuple)): local_ip_addresses = ' '.join(local_ip_addresses) query = session.query(db_models.DeaddropConnection) query = query.filter_by(deployment_id=deployment.id, local_username=local_username, local_hostname=local_hostname) connection = query.first() if connection: connection.count += 1 connection.last_seen = db_models.current_timestamp() new_connection = False else: connection = db_models.DeaddropConnection(campaign_id=deployment.campaign_id, deployment_id=deployment.id) connection.ip = self.get_client_ip() connection.local_username = local_username connection.local_hostname = local_hostname connection.local_ip_addresses = local_ip_addresses session.add(connection) new_connection = True session.commit() query = session.query(db_models.DeaddropConnection) query = query.filter_by(campaign_id=deployment.campaign_id) visit_count = query.count() session.close() self.semaphore_release() if new_connection and visit_count > 0 and ((visit_count in [1, 3, 5]) or ((visit_count % 10) == 0)): self.server.job_manager.job_run(self.issue_alert, (deployment.campaign_id, 'deaddrop_connections', visit_count)) return