Exemplo n.º 1
0
    def render_POST(self, request):
        request.responseHeaders.addRawHeader(b"content-type",
                                             b"application/json")
        response = {}
        try:
            token = request.args.get('token', None)[0]
            auth = request.args.get('auth', None)[0]
            setting = request.args.get('setting', None)[0]

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

            if setting not in [
                    'clonedsite', 'email_enable', 'webhook_enable',
                    'sms_enable', 'browser_scanner_enable', 'web_image_enable'
            ]:
                raise NoCanarytokenPresent()

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

        if setting == 'clonedsite':
            try:
                clonedsite = request.args['clonedsite'][0]
                if not clonedsite:
                    raise KeyError

                cloned_token = {'clonedsite': clonedsite, 'canarytoken': token}
                canarydrop.clonedsite_token = save_clonedsite_token(
                    cloned_token)
                save_canarydrop(canarydrop)
                response[
                    'clonedsite_js'] = canarydrop.get_cloned_site_javascript()
                response['clonedsite'] = clonedsite
            except (IndexError, KeyError):
                return NoResource().render(request)
        elif setting == "email_enable":
            canarydrop['alert_email_enabled'] = request.args['value'][
                0] == "on"
        elif setting == "webhook_enable":
            canarydrop['alert_webhook_enabled'] = request.args['value'][
                0] == "on"
        elif setting == "sms_enable":
            canarydrop['alert_sms_enabled'] = request.args['value'][0] == "on"
        elif setting == "browser_scanner_enable":
            canarydrop['browser_scanner_enabled'] = request.args['value'][
                0] == "on"
        elif setting == "web_image_enable":
            canarydrop['web_image_enabled'] = request.args['value'][0] == "on"

        save_canarydrop(canarydrop=canarydrop)
        response['result'] = 'success'

        return simplejson.dumps(response)
Exemplo n.º 2
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)
Exemplo n.º 3
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)

            if canarydrop.get('memo'):
                canarydrop['memo'] = unicode(canarydrop['memo'], "utf8")

        except (TypeError, NoCanarytokenPresent):
            return NoResource().render(request)
        g_api_key = get_canary_google_api_key()
        template = env.get_template('history.html')
        return template.render(canarydrop=canarydrop,
                               API_KEY=g_api_key).encode('utf8')
Exemplo n.º 4
0
    def __init__(self, generate=False, **kwargs):
        self._drop = {}
        for k, v in kwargs.iteritems():
            if k not in self.allowed_attrs:
                raise UnknownAttribute(attribute=k)
            self._drop[k] = v

        if 'canarytoken' not in self._drop:
            raise NoCanarytokenPresent()

        if 'timestamp' not in self._drop:
            self._drop['timestamp'] = datetime.datetime.utcnow()\
                                        .strftime("%s.%f")

        if 'imgur_token' in self._drop and not self._drop['imgur_token']:
            raise Exception('Missing imgur_token from Canarydrop')

        if 'user' not in self._drop or self._drop['user'] in ('None',
                                                              'Anonymous'):
            self._drop['user'] = AnonymousUser()
        else:
            self._drop['user'] = load_user(self._drop['user'])
            if not self._drop['user']:
                raise NoUser()

        if 'auth' not in self._drop:
            self._drop['auth'] = md5.md5(str(random.SystemRandom()\
                                  .randrange(1,2**128))).hexdigest()

        if self._drop.get('browser_scanner_enabled', '') in ('True', True):
            self._drop['browser_scanner_enabled'] = True
        else:
            self._drop['browser_scanner_enabled'] = False

        if self._drop.get('alert_email_enabled', '') in ('True', True):
            self._drop['alert_email_enabled'] = True
        else:
            self._drop['alert_email_enabled'] = False

        if self._drop.get('alert_webhook_enabled', '') in ('True', True):
            self._drop['alert_webhook_enabled'] = True
        else:
            self._drop['alert_webhook_enabled'] = False

        if self._drop.get('alert_sms_enabled', '') in ('True', True):
            self._drop['alert_sms_enabled'] = True
        else:
            self._drop['alert_sms_enabled'] = False

        if self._drop.get('web_image_enabled', '') in ('True', True):
            self._drop['web_image_enabled'] = True
        else:
            self._drop['web_image_enabled'] = False

        if generate:
            self.generate_random_url()
            self.generate_random_hostname()
Exemplo n.º 5
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, TypeError, 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

            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.º 6
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.º 7
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) > int(settings.MAX_UPLOAD_SIZE):
                    response['Error'] = 4
                    response[
                        'Message'] = 'File too large. File size must be < ' + str(
                            int(settings.MAX_UPLOAD_SIZE) /
                            (1024 * 1024)) + 'MB.'
                    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.º 8
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.º 9
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.º 10
0
    def render_GET(self, request):
        try:
            token = request.args.get('token', None)[0]
            fmt = request.args.get('fmt', None)[0]
            auth = request.args.get('auth', None)[0]
            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token))
            if not canarydrop:
                raise NoCanarytokenPresent()
            if not canarydrop['auth'] or canarydrop['auth'] != auth:
                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))
            elif fmt == 'awskeys':
                request.setHeader("Content-Type", "text/plain")
                request.setHeader("Content-Disposition",
                                  'attachment; filename=credentials')
                text="[default]\naws_access_key={id}\naws_secret_access_key={k}\nregion={r}\noutput={o}"\
                        .format(id=canarydrop['aws_access_key_id'], k=canarydrop['aws_secret_access_key'], r=canarydrop['region'], o=canarydrop['output'])
                return text
            elif fmt == 'incidentlist_json':
                request.setHeader("Content-Type", "text/plain")
                request.setHeader("Content-Disposition",
                                  'attachment; filename={token}_history.json'\
                                  .format(token=token))
                return simplejson.dumps(canarydrop['triggered_list'], indent=4)
            elif fmt == 'incidentlist_csv':
                request.setHeader("Content-Type", "text/plain")
                request.setHeader("Content-Disposition",
                                  'attachment; filename={token}_history.csv'\
                                  .format(token=token))
                csvOutput = StringIO()
                incident_list = canarydrop['triggered_list']

                writer = csv.writer(csvOutput)

                details = []
                for key in incident_list:
                    for element in incident_list[key].keys():
                        details.append(element)

                headers = ["Timestamp"] + details
                writer.writerow(headers)
                items = []
                for item in details:
                    for key in incident_list:
                        items.append(incident_list[key][item])

                for key in incident_list:
                    data = [
                        datetime.datetime.fromtimestamp(
                            float(key)).strftime('%Y-%m-%d %H:%M:%S.%s')
                    ] + items
                    writer.writerow(data)

                return csvOutput.getvalue()

        except Exception as e:
            log.err('Unexpected error in download: {err}'.format(err=e))

        return NoResource().render(request)