Exemplo n.º 1
0
    def render_GET(self, request):
        try:
            token  = request.args.get('token', None)[0]
            fmt    = request.args.get('fmt', None)[0]

            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token))
            if not canarydrop:
                raise NoCanarytokenPresent()

            if fmt == 'zip':
                request.setHeader("Content-Type", "application/zip")
                request.setHeader("Content-Disposition",
                                  'attachment; filename={token}.zip'\
                                  .format(token=token))
                return make_canary_zip(hostname=
                            canarydrop.get_hostname(with_random=False))
            elif fmt == 'msword':
                request.setHeader("Content-Type",
                                  "application/vnd.openxmlformats-officedocument"+\
                                                      ".wordprocessingml.document")
                request.setHeader("Content-Disposition",
                                  'attachment; filename={token}.docx'\
                                  .format(token=token))
                return make_canary_msword(url=canarydrop.get_url())
            elif fmt == 'pdf':
                request.setHeader("Content-Type", "application/pdf")
                request.setHeader("Content-Disposition",
                                  'attachment; filename={token}.pdf'\
                                  .format(token=token))
                return make_canary_pdf(hostname=canarydrop.get_hostname(nxdomain=True, with_random=False))
        except Exception as e:
            log.err('Unexpected error in download: {err}'.format(err=e))


        return NoResource().render(request)
 def poll(self, imgur_token=None):
     try:
         count = get_imgur_count(imgur_id=imgur_token["id"])
         if count > imgur_token["count"]:
             canarydrop = Canarydrop(**get_canarydrop(canarytoken=imgur_token["canarytoken"]))
             self.dispatch(canarydrop=canarydrop, count=count, imgur_id=imgur_token["id"])
             imgur_token["count"] = count
             save_imgur_token(imgur_token=imgur_token)
     except Exception as e:
         log.err("Imgur error: {error}".format(error=e))
    def validateTo(self, user):
        # Only messages directed to the "console" user are accepted.
        try:
            token = Canarytoken(value=user.dest.local)
            self.canarydrop = Canarydrop(**get_canarydrop(canarytoken=token.value()))
            return lambda: CanaryMessage(esmtp=self)
        except (NoCanarytokenPresent, NoCanarytokenFound):
            log.err("No token in recipient address: {address}".format(address=user.dest.local))
        except Exception as e:
            log.err(e)

        raise smtp.SMTPBadRcpt(user)
Exemplo n.º 4
0
    def render_GET(self, request):
        # A GET request to a token URL can trigger one of a few responses:
        # 1. Check if link has been clicked on (rather than loaded from an
        #    <img>) by looking at the Accept header, then:
        #  1a. If browser security if enabled, serve that page and stop.
        #  1b. If fortune in enabled, serve a fortune and stop.
        # 2. Otherwise we'll serve an image:
        #  2a. If a custom image is attached to the canarydrop, serve that and stop.
        #  2b. Serve our default 1x1 gif

        request.setHeader("Server", "Apache")
        try:
            token = Canarytoken(value=request.path)
            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token.value()))
            if request.args.get("ts_key", [None])[0]:
                canarydrop._drop["hit_time"] = request.args.get("ts_key", [None])[0]
            else:
                canarydrop._drop["hit_time"] = datetime.datetime.utcnow().strftime("%s.%f")
            useragent = request.getHeader("User-Agent")
            src_ip = request.getHeader("x-forwarded-for")

            # location and refere are for cloned sites
            location = request.args.get("l", [None])[0]
            referer = request.args.get("r", [None])[0]
            self.dispatch(canarydrop=canarydrop, src_ip=src_ip, useragent=useragent, location=location, referer=referer)

            if "text/html" in request.getHeader("Accept"):
                if canarydrop["browser_scanner_enabled"]:
                    template = env.get_template("browser_scanner.html")
                    return template.render(key=canarydrop._drop["hit_time"], canarytoken=token.value()).encode("utf8")

                elif TOKEN_RETURN == "fortune":
                    try:
                        fortune = subprocess.check_output("/usr/games/fortune")
                        template = env.get_template("fortune.html")
                        return template.render(fortune=fortune).encode("utf8")
                    except Exception as e:
                        log.err("Could not get a fortune: {e}".format(e=e))

            if canarydrop["web_image_enabled"] and os.path.exists(canarydrop["web_image_path"]):
                mimetype = "image/" + canarydrop["web_image_path"][-3:]
                with open(canarydrop["web_image_path"], "r") as f:
                    contents = f.read()
                request.setHeader("Content-Type", mimetype)
                return contents

        except Exception as e:
            log.err("Error in render GET: {error}".format(error=e))

        request.setHeader("Content-Type", "image/gif")
        return self.GIF
Exemplo n.º 5
0
    def render_GET(self, request):

        try:
            token = request.args.get('token', None)[0]
            auth  = request.args.get('auth', None)[0]
            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token))
            if not canarydrop['auth'] or canarydrop['auth'] != auth:
                raise NoCanarytokenPresent()

        except (TypeError, NoCanarytokenPresent):
            return NoResource().render(request)

        template = env.get_template('manage.html')
        return template.render(canarydrop=canarydrop).encode('utf8')
Exemplo n.º 6
0
    def render_GET(self, request):
        try:
            token = Canarytoken(value=request.path)
            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token.value()))
            useragent = request.getHeader('User-Agent')
            src_ip    = request.getHeader('x-forwarded-for')
            self.dispatch(canarydrop=canarydrop, src_ip=src_ip, 
                          useragent=useragent)
        except:
            log.err('No canarytoken seen in: {path}'.format(path=request.path))

        request.setHeader("Content-Type", "image/gif")
        request.setHeader("Server",       "Apache")
        return self.GIF
    def poll(self, linkedin_account=None):
        try:
            current_count = get_linkedin_viewer_count(
                                username=linkedin_account['username'],
                                password=linkedin_account['password'])
        except LinkedInFailure as e:
            log.err('Could not retrieve linkedin view count: {error}'\
                    .format(error=e))
            return

        if current_count > linkedin_account['count']:
            canarydrop = Canarydrop(**get_canarydrop(
                            canarytoken=linkedin_account['canarytoken']))
            self.dispatch(canarydrop=canarydrop, count=current_count, 
                          linkedin_username=linkedin_account['username'])
            linkedin_account['count'] = current_count
            save_linkedin_account(linkedin_account=linkedin_account)
    def poll(self, bitcoin_account=None):
        try:
            current_balance = get_bitcoin_address_balance(
                                address=bitcoin_account['address'])
        except BitcoinFailure as e:
            log.err('Could not retrieve bitcoin balance: {error}'\
                    .format(error=e))
            return

        if current_balance> bitcoin_account['balance']:
            canarydrop = Canarydrop(**get_canarydrop(
                            canarytoken=bitcoin_account['canarytoken']))
            self.dispatch(canarydrop=canarydrop, new_balance=current_balance, 
                          old_balance=bitcoin_account['balance'],
                          address=bitcoin_account['address'])
            bitcoin_account['balance'] = current_balance
            save_bitcoin_account(bitcoin_account=bitcoin_account)
Exemplo n.º 9
0
    def render_GET(self, request):

        try:
            token = request.args.get('token', None)[0]
            auth  = request.args.get('auth', None)[0]
            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token))
            if not canarydrop['auth'] or canarydrop['auth'] != auth:
                raise NoCanarytokenPresent()
            if canarydrop.get('triggered_list', None):
                for timestamp in canarydrop['triggered_list'].keys():
                    formatted_timestamp = datetime.datetime.fromtimestamp(
                                float(timestamp)).strftime('%Y %b %d %H:%M:%S')
                    canarydrop['triggered_list'][formatted_timestamp] = canarydrop['triggered_list'].pop(timestamp)

        except (TypeError, NoCanarytokenPresent):
            return NoResource().render(request)
        g_api_key = get_canary_google_api_key()
        template = env.get_template('manage.html')
        return template.render(canarydrop=canarydrop, API_KEY=g_api_key).encode('utf8')
Exemplo n.º 10
0
    def render_POST(self, request):
        try:
            fields = cgi.FieldStorage(
                fp = request.content,
                headers = request.getAllHeaders(),
                environ = {'REQUEST_METHOD':'POST',
                'CONTENT_TYPE': request.getAllHeaders()['content-type'],
                }
            )#hacky way to parse out file contents and filenames

            token  = request.args.get('token', None)[0]
            fmt    = request.args.get('fmt', None)[0]
            if fmt not in ['authenticode']:
                raise Exception('Unsupported token type for POST.')

            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token))
            if not canarydrop:
                raise NoCanarytokenPresent()

            if fmt == 'authenticode':
                filename = fields['file_for_signing'].filename
                filebody = fields['file_for_signing'].value
                if len(filebody) > settings.MAX_UPLOAD_SIZE:
                    raise Exception('File too large')

                if not filename.lower().endswith(('exe','dll')):
                    raise Exception('Uploaded authenticode file must be an exe or dll')
                signed_contents = make_canary_authenticode_binary(hostname=
                            canarydrop.get_hostname(with_random=False, as_url=True),
                            filebody=filebody)
                request.setHeader("Content-Type", "octet/stream")
                request.setHeader("Content-Disposition",
                                  'attachment; filename={filename}.signed'\
                                  .format(filename=filename))
                return signed_contents


        except Exception as e:
            log.err('Unexpected error in POST download: {err}'.format(err=e))
            template = env.get_template('error.html')
            return template.render(error=e.message).encode('utf8')

        return NoResource().render(request)
Exemplo n.º 11
0
    def render_GET(self, request):
        try:
            token = Canarytoken(value=request.path)
            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token.value()))
            useragent = request.getHeader('User-Agent')
            src_ip    = request.getHeader('x-forwarded-for')

            #location and refere are for cloned sites
            location  = request.args.get('l', [None])[0]
            referer   = request.args.get('r', [None])[0]

            self.dispatch(canarydrop=canarydrop, src_ip=src_ip,
                          useragent=useragent, location=location,
                          referer=referer)
        except:
            log.err('No canarytoken seen in: {path}'.format(path=request.path))

        request.setHeader("Content-Type", "image/gif")
        request.setHeader("Server",       "Apache")
        return self.GIF
Exemplo n.º 12
0
    def query(self, query, src_ip):
        """
        Check if the query should be answered dynamically, otherwise dispatch to
        the fallback resolver.
        """
        self.logfile.write('%r\n' % query)
        self.logfile.flush()

        if query.type == dns.NS:
            return defer.succeed(self._do_ns_response(name=query.name.name))

        if query.type != dns.A:
            return defer.succeed(self._do_no_response(query=query))
            #return defer.fail(error.DomainError())

        try:
            token = Canarytoken(value=query.name.name)

            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token.value()))

            src_data = self.look_for_source_data(token=token.value(), value=query.name.name)

            self.dispatch(canarydrop=canarydrop, src_ip=src_ip, src_data=src_data)

#            return defer.succeed(
#                            self._do_dynamic_response(name=query.name.name,
#                                                      response=response))
        except NoCanarytokenPresent:
            log.err('No token seen in query: {query}'.format(query=query.name.name))
        except Exception as e:
            log.err(e)

        if query.name.name in settings.NXDOMAINS:
            return defer.fail(error.DomainError())

        return defer.succeed(self._do_dynamic_response(name=query.name.name))
Exemplo n.º 13
0
    def render_POST(self, request):
        try:
            try:
                token = request.args.get('token', None)[0]
                auth  = request.args.get('auth',  None)[0]

                canarydrop = Canarydrop(**get_canarydrop(canarytoken=token))
                if not canarydrop['auth'] or canarydrop['auth'] != auth:
                    raise NoCanarytokenPresent()

            except (IndexError, NoCanarytokenPresent):
                return NoResource().render(request)

            try:
                email_enable_status = request.args.get('email_enable', None)[0] == "on"
            except (TypeError, IndexError):
                email_enable_status = False

            try:
                sms_enable_status = request.args.get('sms_enable', None)[0] == "on"
            except (TypeError, IndexError):
                sms_enable_status = False

            canarydrop['alert_email_enabled'] = email_enable_status
            canarydrop['alert_sms_enabled']   = sms_enable_status

            save_canarydrop(canarydrop=canarydrop)

            template = env.get_template('manage.html')
            return template.render(canarydrop=canarydrop, saved=True,
                                        settings=settings).encode('utf8')

        except Exception as e:
            template = env.get_template('manage.html')
            return template.render(canarydrop=canarydrop, error=e,
                                        settings=settings).encode('utf8')
Exemplo n.º 14
0
    def render_POST(self, request):
        try:
            try:
                token = request.args.get('token', None)[0]
                auth  = request.args.get('auth',  None)[0]

                canarydrop = Canarydrop(**get_canarydrop(canarytoken=token))
                if not canarydrop['auth'] or canarydrop['auth'] != auth:
                    raise NoCanarytokenPresent()

            except (IndexError, NoCanarytokenPresent):
                return NoResource().render(request)

            try:
                email_enable_status = request.args.get('email_enable', None)[0] == "on"
            except (TypeError, IndexError):
                email_enable_status = False

            try:
                webhook_enable_status = request.args.get('webhook_enable', None)[0] == "on"
            except (TypeError, IndexError):
                webhook_enable_status = False

            try:
                sms_enable_status = request.args.get('sms_enable', None)[0] == "on"
            except (TypeError, IndexError):
                sms_enable_status = False

            try:
                web_image_status = request.args.get('web_image_enable', None)[0] == "on"
            except (TypeError, IndexError):
                web_image_status = False

            try:
                token_fmt = request.args.get('fmt', None)[0]
            except (TypeError, IndexError):
                token_fmt = ''

            canarydrop['alert_email_enabled'] = email_enable_status
            canarydrop['alert_webhook_enabled'] = webhook_enable_status
            canarydrop['alert_sms_enabled']   = sms_enable_status
            canarydrop['web_image_enabled']   = web_image_status

            if token_fmt == 'web_image':
                if not settings.WEB_IMAGE_UPLOAD_PATH:
                    raise Exception("Image upload not supported, set CANARY_WEB_IMAGE_UPLOAD_PATH in frontend.env.")

                fields = cgi.FieldStorage(
                    fp = request.content,
                    headers = request.getAllHeaders(),
                    environ = {'REQUEST_METHOD':'POST',
                    'CONTENT_TYPE': request.getAllHeaders()['content-type'],
                    }
                )

                filename = fields['web_image'].filename
                filebody = fields['web_image'].value

                if len(filebody) > settings.MAX_UPLOAD_SIZE:
                    raise Exception('File too large')

                if not filename.lower().endswith(('.png','.gif','.jpg')):
                    raise Exception('Uploaded image must be a PNG, GIF or JPG')
                ext = filename.lower()[-4:]

                #create a random local filename
                r = hashlib.md5(os.urandom(32)).hexdigest()
                filepath = os.path.join(settings.WEB_IMAGE_UPLOAD_PATH,
                                    r[:2],
                                    r[2:])+ext
                if not os.path.exists(os.path.dirname(filepath)):
                    try:
                        os.makedirs(os.path.dirname(filepath))
                    except OSError as exc: # Guard against race condition
                        if exc.errno != errno.EEXIST:
                            raise

                with open(filepath, "w") as f:
                    f.write(filebody)

                canarydrop['web_image_enabled'] = True
                canarydrop['web_image_path'] = filepath
            save_canarydrop(canarydrop=canarydrop)
            g_api_key = get_canary_google_api_key()
            template = env.get_template('manage.html')
            return template.render(canarydrop=canarydrop, saved=True,
                                        settings=settings, API_KEY=g_api_key).encode('utf8')

        except Exception as e:
            import traceback
            log.err('Exception in manage.html: {e}, {stack}'.format(e=e, stack=traceback.format_exc()))
            template = env.get_template('manage.html')
            return template.render(canarydrop=canarydrop, error=e,
                                        settings=settings).encode('utf8')
Exemplo n.º 15
0
    def render_POST(self, request):
        try:
            key = request.args["key"][0]
            token = Canarytoken(value=request.path)
            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token.value()))
            # if key and token args are present, we are either:
            #    -posting browser info
            #    -getting an aws trigger (key == aws_s3)
            # store the info and don't re-render
            if key and token:
                if key == "aws_s3":
                    try:
                        canarydrop._drop["hit_time"] = datetime.datetime.utcnow().strftime("%s.%f")
                        src_ip = request.args["RemoteIP"][0]
                        additional_info = {
                            "AWS Log Data": {k: v for k, v in request.args.iteritems() if k not in ["key", "src_ip"]}
                        }
                        self.dispatch(canarydrop=canarydrop, src_ip=src_ip, additional_info=additional_info)
                    except Exception as e:
                        log.err("Error in s3 post: {error}".format(error=e))
                elif "secretkeeper_photo" in request.args:
                    log.err("Saving secretkeeper_photo")
                    try:
                        fields = cgi.FieldStorage(
                            fp=request.content,
                            headers=request.getAllHeaders(),
                            environ={"REQUEST_METHOD": "POST", "CONTENT_TYPE": request.getAllHeaders()["content-type"]},
                        )  # hacky way to parse out file contents and filenames
                        filename = fields["secretkeeper_photo"].filename
                        filebody = fields["secretkeeper_photo"].value

                        if len(filebody) > MAX_UPLOAD_SIZE:
                            raise Exception("File too large")

                        r = hashlib.md5(os.urandom(32)).hexdigest()
                        filepath = os.path.join(WEB_IMAGE_UPLOAD_PATH, r[:2], r[2:]) + ".png"
                        if not os.path.exists(os.path.dirname(filepath)):
                            try:
                                os.makedirs(os.path.dirname(filepath))
                            except OSError as exc:  # Guard against race condition
                                if exc.errno != errno.EEXIST:
                                    raise

                        with open(filepath, "w") as f:
                            f.write(filebody)

                        canarydrop.add_additional_info_to_hit(
                            hit_time=key, additional_info={"secretkeeper_photo": filepath}
                        )
                    except Exception as e:
                        log.err("Error in secretkeeper_photo post: {error}".format(error=e))
                else:
                    additional_info = {
                        k: v for k, v in request.args.iteritems() if k not in ["key", "canarytoken", "name"]
                    }
                    canarydrop.add_additional_info_to_hit(
                        hit_time=key, additional_info={request.args["name"][0]: additional_info}
                    )
                return "success"
            else:
                return self.render_GET(request)
        except Exception as e:
            return self.render_GET(request)