def result(ip, workout_id): api = shodan.Shodan(SHODAN_API_KEY) workout = ds_client.get(ds_client.key('cybergym-workout', workout_id)) if workout: if workout['type'] == 'shodan': ip_list = [] ip_list.append(ip) info = api.host(ip_list, history=True) for tmp in info["data"]: has_screenshot = helpers.get_screenshot(tmp) if has_screenshot is not None: info["screenshot"] = has_screenshot["data"] page_template = 'results.jinja' return render_template( page_template, resultInfo=info, workoutid=workout_id, ) else: return redirect('/invalid/' + workout_id) else: return redirect('/invalid/' + workout_id)
def default(workout_id): api = shodan.Shodan(SHODAN_API_KEY) page_template = 'index.jinja' workout = ds_client.get(ds_client.key('cybergym-workout', workout_id)) if workout: if workout['type'] == 'shodan': if request.method == 'POST': logger.info(f'POST to /{workout_id}') try: query = request.form.get('shodan_query') page_num = request.form.get('page_number') result = api.search(query, limit=10) result_count = api.count(query) print(result.keys()) return render_template( page_template, shodanResults=result, resultCount=result_count, query=query, page_num=page_num, workoutid=workout_id, ) except shodan.APIError as e: logger.info(e) e_template = 'invalid_query.jinja' return render_template(e_template) return render_template(page_template) else: return redirect('/invalid/' + workout_id) else: return redirect('/invalid/' + workout_id)
def cipher_info(workout_id): page_template = 'pages/arena-cipher-info.jinja' key = ds_client.key('cybergym-workout', workout_id) workout = ds_client.get(key) if workout: if workout['name'] == 'Trojan Arena Level 2': return render_template(page_template, workout_id=workout_id) else: return redirect('/invalid')
def arena(workout_id): page_template = 'pages/johnny-arena-landing.jinja' key = ds_client.key('cybergym-workout', workout_id) workout = ds_client.get(key) if workout: if workout['name'] == 'Trojan Arena Level 2': return render_template(page_template, workout_id=workout_id) else: return redirect('/invalid')
def view_all_query_results(query, page, workout_id): api = shodan.Shodan(SHODAN_API_KEY) workout = ds_client.get(ds_client.key('cybergy-workout', workout_id)) if workout: if workout['type'] == 'shodan': if request.method == "POST": result = api.search(query, page=page) else: return redirect('/invalid/' + workout_id) else: return redirect('/invalid/' + workout_id)
def loader(workout_id): key = ds_client.key('cybergym-workout', workout_id) workout = ds_client.get(key) if workout: if workout['type'] == 'shodan': data = populate_datastore(workout_id=workout_id) logger.info(data) return redirect('/' + workout_id) else: return redirect('/invalid/' + workout_id) else: return redirect('/invalid/' + workout_id)
def login(workout_id): page_template = 'pages/login.jinja' key = ds_client.key('cybergym-workout', workout_id) workout = ds_client.get(key) # Check if valid workout and valid workout type if not workout: return redirect('/invalid') else: if workout['type'] == 'johnnyhash': if request.method == 'GET': return render_template(page_template, workout_id=workout_id) elif request.method == 'POST': username = request.form.get('username', None) password = request.form.get('password', None) print(username, password) if username is None or password is None: login_error = 'You must submit a username and password' return render_template( page_template, login_error=login_error, workout_id=workout_id, ) elif username == 'johnny' and password == workout[ 'container_info']['correct_password']: # These are the correct credentials, so the cookie for "logged_in" is set to true resp = make_response( redirect('/hidden/{}'.format(workout_id))) resp.set_cookie('logged_in', 'true') workout_token = workout['assessment']['questions'][0][ 'key'] app.logger.info( f'Posting Complete to buildthewarrior{dns_suffix}/complete' ) publish_status(workout_id, workout_token) return resp else: login_error = 'Please check your username and password and try again' return render_template( page_template, login_error=login_error, workout_id=workout_id, ) else: return redirect('/invalid')
def hidden(workout_id): # This portion sets a cookie with the key "logged_in" to true when a user has authenticated # They must be authenticated before viewing this page key = ds_client.key('cybergym-workout', workout_id) workout = ds_client.get(key) logged_in = request.cookies.get('logged_in', None) if workout: if logged_in is None or logged_in != 'true': return redirect('/login/{}'.format(workout_id)) else: page_template = 'pages/hidden.jinja' return render_template(page_template, workout_id=workout_id) else: return redirect('/invalid')
def loader(workout_id): key = ds_client.key('cybergym-workout', workout_id) workout = ds_client.get(key) app.logger.info('workout_type : %s' % workout['type']) if workout: if workout['type'] == 'johnnycipher': if workout['container_info']['cipher_one']['cipher'] == '': set_ciphers(workout_id) return redirect('/caesar/' + workout_id) elif workout['type'] == 'johnnyhash': if workout['container_info']['correct_password'] == '': gen_pass(workout_id) return redirect('/md5_page/' + workout_id) else: return redirect('/invalid')
def data(workout_id): page_template = 'raw_data.jinja' workout = ds_client.get(ds_client.key('cybergym-workout', workout_id)) if workout: if workout['type'] == 'shodan': if request.method == "POST": logger.info(f"Sending POST to /data/{workout_id}") return render_template( page_template, rawData=request.form.get('data'), workoutid=workout_id, ) if request.method == "GET": logger.info(f'GET /data/{workout_id}') print(type(request.get_data())) else: return redirect('/invalid/' + workout_id) else: return redirect('/invalid/' + workout_id)
def caesar(workout_id): page_template = 'pages/cipher.jinja' key = ds_client.key('cybergym-workout', workout_id) workout = ds_client.get(key) # Only valid workouts can access if workout: if workout['type'] == 'johnnycipher': firstcipher = workout['container_info']['cipher_one']['cipher'] secondcipher = workout['container_info']['cipher_two']['cipher'] thirdcipher = workout['container_info']['cipher_three']['cipher'] if request.method == 'GET': return render_template( page_template, workout_id=workout_id, firstcipher=firstcipher, secondcipher=secondcipher, thirdcipher=thirdcipher, ) elif request.method == 'POST': plaintext = request.get_json() # ['id'] helps determine which cipher is to be evaluated app.logger.info('Checking cipher with id : %d' % int(plaintext['id'])) data = check_caesar(workout_id, str(plaintext['cipher']), int(plaintext['id'])) return jsonify({ 'message1': data['cipher1']['cipher'], 'status1': data['cipher1']['status'], 'message2': data['cipher2']['cipher'], 'status2': data['cipher2']['status'], 'message3': data['cipher3']['cipher'], 'status3': data['cipher3']['status'], }) else: return redirect('/invalid') else: return redirect('/invalid')
def md5_page(workout_id): page_template = 'pages/md5_page.jinja' key = ds_client.key('cybergym-workout', workout_id) workout = ds_client.get(key) # Only valid workouts should access page if workout: # Valid workout_id and type: if workout['type'] == 'johnnyhash': if request.method == 'GET': return render_template(page_template, pass_hash=workout['container_info'] ['correct_password_hash'], workout_id=workout_id) elif request.method == 'POST': if 'password_file' not in request.files: # User did not submit a file. Show error and let them upload again return render_template( page_template, upload_error="You must choose a file to upload", workout_id=workout_id, pass_hash=workout['container_info'] ['correct_password_hash']) else: # Check to be sure that the user has submitted a file. input_file = request.files['password_file'] if input_file.filename == '': # User has submitted a blank file. Show error and let them upload again. return render_template( page_template, upload_error="You must choose a file to upload", pass_hash=workout['container_info'] ['correct_password_hash'], workout_id=workout_id, ) # At this point, we have a csv file to process raw_input = io.StringIO( input_file.stream.read().decode("UTF8"), newline=None) passwords = raw_input.read().split('\n') hashes = [] for password in passwords: hashes.append({ 'plaintext': password, 'hash': hashlib.md5(password.encode('utf-8')).hexdigest() }) return render_template( page_template, hashed_passwords=hashes, pass_hash=workout['container_info'] ['correct_password_hash'], workout_id=workout_id, ) else: # Valid workout_id, but not correct workout type return redirect('/invalid') else: # Workout ID doesn't exist ... return redirect('/invalid')