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)
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 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')
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()
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')
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')
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)
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')
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')
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)