def render_POST(self, request): request.responseHeaders.addRawHeader(b"content-type", b"application/json") response = { 'Error': None, 'Url': "", 'Token': "", 'Email': "", 'Hostname': "", 'Auth': ''} try: 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') alert_email_enabled = False if not email else True alert_webhook_enabled = False if not webhook else True canarytoken = Canarytoken() try: browser_scanner = request.args['subtype'][0] == 'browserscanner' except: browser_scanner = False canarydrop = Canarydrop(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 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) save_canarydrop(canarydrop) response['clonedsite_js'] = CLONED_SITE_JS\ .replace('CLONED_SITE_DOMAIN', clonedsite)\ .replace('CANARYTOKEN_SITE', canarydrop.get_random_site())\ .replace('CANARYTOKEN', response['Token']) response['clonedsite'] = clonedsite except (IndexError, KeyError): pass try: imgur_id = request.args['imgur'][0] if not imgur_id: raise KeyError imgur_token = {'id': imgur_id, 'canarytoken': canarytoken.value()} canarydrop.imgur_token = save_imgur_token(imgur_token) save_canarydrop(canarydrop) response['imgur_count'] = imgur_token['count'] response['imgur_id'] = imgur_id except (IndexError, KeyError): pass try: linkedin_user = request.args['linkedin_user'][0] linkedin_password = request.args['linkedin_password'][0] if not linkedin_user and not linkedin_password: raise KeyError create_linkedin_account(username=linkedin_user, password=linkedin_password, canarydrop=canarydrop) response['linkedin_account'] = linkedin_user response['linkedin_account_views'] = \ get_linkedin_account(username=linkedin_user)['count'] except (IndexError, KeyError): pass try: bitcoin_address = request.args['bitcoin_address'][0] if not bitcoin_address: raise KeyError create_bitcoin_account(address=bitcoin_address) btc = get_bitcoin_account(address=bitcoin_address) response['bitcoin_address'] = bitcoin_address response['bitcoin_balance'] = btc['balance'] except (IndexError, KeyError): pass try: qrcode = pyqrcode.create(canarydrop.get_url()).png_as_base64_str(scale=5) response['qrcode_png'] = "data:image/png;base64,{qrcode}".format(qrcode=qrcode) 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)
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)