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: 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)
def render_POST(self, request): request.responseHeaders.addRawHeader(b"content-type", b"application/json") response = { 'Error': None, 'Url': "", 'Url_components': None, 'Token': "", 'Email': "", 'Hostname': "", 'Auth': '' } try: try: token_type = request.args.get('type', None)[0] if token_type not in [ 'web', 'dns', 'web_image', 'ms_word', 'adobe_pdf', 'windows_dir', 'clonedsite', 'qr_code', 'svn', 'smtp', 'sql_server', 'aws_keys', 'signed_exe', 'fast_redirect', 'slow_redirect' ]: raise Exception() except: raise Exception('Unknown type') try: email = request.args.get('email', None)[0] webhook = request.args.get('webhook', None)[0] if not email and not webhook: response['Error'] = 1 raise Exception('No email/webhook supplied') except IndexError: response['Error'] = 1 raise Exception('No email supplied') try: memo = ''.join(request.args.get('memo', None)) if not memo: response['Error'] = 2 raise Exception('No memo supplied') except TypeError: response['Error'] = 2 raise Exception('No memo supplied') if webhook and not is_webhook_valid(webhook): response['Error'] = 3 raise Exception( 'Invalid webhook supplied. Confirm you can POST to this URL.' ) alert_email_enabled = False if not email else True alert_webhook_enabled = False if not webhook else True canarytoken = Canarytoken() if token_type == "web": #always enable the browser scanner by default browser_scanner = True else: browser_scanner = False canarydrop = Canarydrop( type=token_type, generate=True, alert_email_enabled=alert_email_enabled, alert_email_recipient=email, alert_webhook_enabled=alert_webhook_enabled, alert_webhook_url=webhook, canarytoken=canarytoken.value(), memo=memo, browser_scanner_enabled=browser_scanner) if settings.TWILIO_ENABLED: try: if not request.args['mobile'][0]: raise KeyError canarydrop['alert_sms_recipient'] = request.args['mobile'][ 0] canarydrop['alert_sms_enabled'] = True except KeyError: canarydrop['alert_sms_recipient'] = '' canarydrop['alert_sms_enabled'] = False save_canarydrop(canarydrop) response['Token'] = canarytoken.value() response['Url'] = canarydrop.get_url() response['Hostname'] = canarydrop.get_hostname() response['Auth'] = canarydrop['auth'] response['Email'] = email response['Url_components'] = list(canarydrop.get_url_components()) save_canarydrop(canarydrop) try: clonedsite = request.args['clonedsite'][0] if not clonedsite: raise KeyError cloned_token = { 'clonedsite': clonedsite, 'canarytoken': canarytoken.value() } canarydrop.clonedsite_token = save_clonedsite_token( cloned_token) canarydrop['clonedsite'] = clonedsite save_canarydrop(canarydrop) response[ 'clonedsite_js'] = canarydrop.get_cloned_site_javascript() response['clonedsite'] = clonedsite except (IndexError, KeyError): pass try: if not request.args.get('type', None)[0] == 'qr_code': raise Exception() response['qrcode_png'] = canarydrop.get_qrcode_data_uri_png() except: pass try: if not request.args.get('type', None)[0] == 'aws_keys': raise Exception() keys = get_aws_keys(token=canarytoken.value(), server=get_all_canary_domains()[0]) if not keys: raise Exception() response['aws_access_key_id'] = keys[0] response['aws_secret_access_key'] = keys[1] canarydrop['aws_access_key_id'] = keys[0] canarydrop['aws_secret_access_key'] = keys[1] save_canarydrop(canarydrop) except: pass try: if not request.args.get('type', None)[0] == 'web_image': raise Exception() 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) except: pass try: if request.args.get('type', None)[0] != 'signed_exe': raise Exception() 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['signed_exe'].filename filebody = fields['signed_exe'].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) response['file_name'] = filename response[ 'file_contents'] = "data:octet/stream;base64," + base64.b64encode( signed_contents) except: pass try: if request.args.get('type', None)[0] != 'fast_redirect': raise Exception() if not request.args['redirect_url'][0]: raise Exception() canarydrop['redirect_url'] = request.args['redirect_url'][0] save_canarydrop(canarydrop) except: pass try: if request.args.get('type', None)[0] != 'slow_redirect': raise Exception() if not request.args['redirect_url'][0]: raise Exception() canarydrop['redirect_url'] = request.args['redirect_url'][0] save_canarydrop(canarydrop) except: pass except Exception as e: if response['Error'] is None: response['Error'] = 255 log.err('Unexpected error: {err}'.format(err=e)) return simplejson.dumps(response)