Updated a lot
|
@ -1,21 +1,25 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDXTCCAkWgAwIBAgIJAP1fDj/HP2uuMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
MIIESTCCAzGgAwIBAgIJAIaxYiOmR5/yMA0GCSqGSIb3DQEBCwUAMIG6MQswCQYD
|
||||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
VQQGEwJVUzELMAkGA1UECAwCQ1QxEzARBgNVBAcMCk5ldyBMb25kb24xKjAoBgNV
|
||||||
aWRnaXRzIFB0eSBMdGQwHhcNMTYwODE3MTUyMTMyWhcNMTcwODE3MTUyMTMyWjBF
|
BAoMIVVuaXRlZCBTdGF0ZXMgQ29hc3QgR3VhcmQgQWNhZGVteTETMBEGA1UECwwK
|
||||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
Q3liZXIgVGVhbTEfMB0GA1UEAwwWZ2l0aHViLmNvbS9Kb2huSGFtbW9uZDEnMCUG
|
||||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
CSqGSIb3DQEJARYYam9obmhhbW1vbmQwMTBAZ21haWwuY29tMB4XDTE3MDEwMjAx
|
||||||
CgKCAQEA5pWsXxqGQzZ98uxLdNpOYWDEWk/dqeJJwTu1oUzkhUkZDbgTfxOzrLnO
|
NDQwOVoXDTE4MDEwMjAxNDQwOVowgboxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD
|
||||||
SeePBMzGIPQKE/l4jesX58JK69657Yhqzvie9/4i5A+vyQ3V7BQnCI92YYTPHltP
|
VDETMBEGA1UEBwwKTmV3IExvbmRvbjEqMCgGA1UECgwhVW5pdGVkIFN0YXRlcyBD
|
||||||
HLvKJ9FkR0ves8o4vLRUFNwAz8zS4piUEhMCMbbZEYRx3+cSH3xu8RQYcwzdw0Tv
|
b2FzdCBHdWFyZCBBY2FkZW15MRMwEQYDVQQLDApDeWJlciBUZWFtMR8wHQYDVQQD
|
||||||
gHUu8lU/nLrOR+p+ovfh/ZlriMGQtSU1F1CBk/wyMESj0ELJx61A3omzIr7rMXiQ
|
DBZnaXRodWIuY29tL0pvaG5IYW1tb25kMScwJQYJKoZIhvcNAQkBFhhqb2huaGFt
|
||||||
fDsvfl+GcB+qt+zfuYSPJXAXoY1R6ojAJjXC2LBR1z0C6y7xS7o37HCFUBNWavHq
|
bW9uZDAxMEBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
d1EzZqNf6Mwa1XYWmJ/appqt1brK3wIDAQABo1AwTjAdBgNVHQ4EFgQUWhlBuC7J
|
AQC4FWxCUkvF10cSg5QnT2NNFTHYRfJT/KU4rQYQKIOAkXhODqVjpOtHNHkY+2N8
|
||||||
jiUEhpmbMIdzbC7RlK8wHwYDVR0jBBgwFoAUWhlBuC7JjiUEhpmbMIdzbC7RlK8w
|
GuqECkqUVUXtu2hyH4CN1qmhmF4+qCGfs4UvNDF1rmbTlT1CNlOs5wh8i02acy8A
|
||||||
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAE93tp9oWgVU1oUyjh8Hm
|
4SVLquybiEWKIbKnBCPileFTRG0ZvesVVTOOPBpI2D1xh4kdriBBwx0+J/NM0L0w
|
||||||
b0z0VCSPzp/IQ4Ja8ElmL6GF/GsJ9jeH2Yfi/EWO1XFKMY2xGbHci/MSxOX0+ZjS
|
e1MGgqDzjEc9AZ/ewZrhUlKkFWfk3ezU3z1brqDfi1YgzQfboZaXFN7yOzG2tdO4
|
||||||
EgSbYt8lKCBnxYA3OO8F2PyLKEyB7GQ9B++2giSFGnkLUHw0DmWz1LZ81n/Dd2iV
|
EysGs97DuVno84LlZCF/7ZwYgIORP4jVWOkUhtv6yj0uoqrkwQSw7LvoCf6mU2n9
|
||||||
L8tFJwwhaGpoutqcWgEm4whBOgQp/IWCQ1Cy3YDHaORGB4TOAETuvcqhAeTEyltz
|
zR+xIwPs68xuuTXbfLdmSfn5AgMBAAGjUDBOMB0GA1UdDgQWBBRw9d7+KE7rC1ch
|
||||||
99Bz7+vSnZ3m3YgibTl2WdWsBEeXS7ghT0mLPBHQPH61hJxqWaBvhoiZiT0b1I73
|
j3W38kzB2R6bUTAfBgNVHSMEGDAWgBRw9d7+KE7rC1chj3W38kzB2R6bUTAMBgNV
|
||||||
JcuDpEJx3r2vAXj6JUIRer2TK080IMBvBKTGr4ZSacO3rg7gOweud/NYo4cCgUvC
|
HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBqXIRW8vqLougRyb5xjCvQ4evP
|
||||||
pA==
|
fe6ycRGARxqoAPJedpOncDXXJADZfqEMUDYPC0YQXcZUB51o2glwbPdvGRX22d3N
|
||||||
|
zJHzwN3YnwT27h/yQFWQ6q6vFqlS1RwyTm168VKi5M23H0q0dFYI/jY9SO0BIJHw
|
||||||
|
poBNeSLwHcQ1QZYudBkOXqf4VM5IRSKxCFGOdlLuRcFoP56u83stbLli/pMxBdMF
|
||||||
|
WT3fajTIGmVQMmTHwpbXqLhMDvZHFzg30MO8uncM38DCB64wPFyWBXN98mADnol5
|
||||||
|
qwFYJ+l+BS+l3T0FrAav9NtQMzJ1FRnUO5gY8cdOU/Xji9vxkBWrvaPxcNHG
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDXTCCAkWgAwIBAgIJAJD7t75jgxkMMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
|
||||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
|
||||||
aWRnaXRzIFB0eSBMdGQwHhcNMTYwMjE0MjIwMjM0WhcNMTcwMjEzMjIwMjM0WjBF
|
|
||||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
|
||||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
|
||||||
CgKCAQEAoUeVnOJidItTApBwBLrGo0rKh77skVEQHObEVNAKSF2rHf66Ix/Um4J6
|
|
||||||
OGG440pEGzDiY+2lS8VP40JsZmNXV9920SpJLE6Pv0tb7Nth0B5lrorM9M3Mj6BC
|
|
||||||
D5E17opvoQFFOu/mjc7elLvHamap2AsqAbk1siyGIC8DecIiNoyMsZeB0d/HZhNi
|
|
||||||
My8gX8j7I+UMrrn01qriSu3GTh79a3mq4nMC0xtomZZc5jLXZ1C5+dXSGuLpHaqE
|
|
||||||
kqq80CxmCo0cvAuU6f+WJ+2EXGAJdawvBIGcRbOyYd5WC7GXWSD8EOosI+/7fcaf
|
|
||||||
kAXy6CYJfng4oDZgJxgNgZ8x5uujZwIDAQABo1AwTjAdBgNVHQ4EFgQU5FXGhyiD
|
|
||||||
kvpqEgmkVkW9lZgZEp8wHwYDVR0jBBgwFoAU5FXGhyiDkvpqEgmkVkW9lZgZEp8w
|
|
||||||
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAnGBGn8Cj67RFMwc19cpw
|
|
||||||
YLBKu3J6p84Q5gqH5hbR2welyidGTkebbyviUmfoxBg1N3OkpNuq+l/M8yPSWTJB
|
|
||||||
Ij4DNvqHBAICI9eGy3oaaR9tPAvj0bRQXCR5rWHeC9jJrcQblqViKz87UcAX0SVC
|
|
||||||
WQLtiANgZCFTh0zNMeyn4GRoObwN244KpQdUxNt9ssh4p4/hY9hZ+1BBA4D2Rku3
|
|
||||||
ncweJ3bQhEkeQIdtl0MIZF5QM+3P++mcRBbim1JcyBdl2Ew4RQVtObdomTStrR+p
|
|
||||||
zq52cPJgDo83K1j+VOs/R2R/wFv2bfRwY+QrnsHBF8006l/GDtbUTjx0zdHKeIsT
|
|
||||||
Nw==
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
rm -f server.py certificate.crt privateKey.key
|
|
|
@ -1,28 +0,0 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQChR5Wc4mJ0i1MC
|
|
||||||
kHAEusajSsqHvuyRURAc5sRU0ApIXasd/rojH9Sbgno4YbjjSkQbMOJj7aVLxU/j
|
|
||||||
QmxmY1dX33bRKkksTo+/S1vs22HQHmWuisz0zcyPoEIPkTXuim+hAUU67+aNzt6U
|
|
||||||
u8dqZqnYCyoBuTWyLIYgLwN5wiI2jIyxl4HR38dmE2IzLyBfyPsj5QyuufTWquJK
|
|
||||||
7cZOHv1rearicwLTG2iZllzmMtdnULn51dIa4ukdqoSSqrzQLGYKjRy8C5Tp/5Yn
|
|
||||||
7YRcYAl1rC8EgZxFs7Jh3lYLsZdZIPwQ6iwj7/t9xp+QBfLoJgl+eDigNmAnGA2B
|
|
||||||
nzHm66NnAgMBAAECggEBAIzF4v2RTMbVZZtzX5OBRCj7+1QJfoxI6XuQogY1oQQR
|
|
||||||
Xm9MDETkX7ttZCkagztBc7kYLkNzBzjf/R8st1mXlIGK+DcSZdRarnYW3SIdS39R
|
|
||||||
SQfU95kmmUs0YvUblqukAlPSvA75n5Bf5UCFt0ZUXiPJet0OQKRI4Lnuz2XT4fEh
|
|
||||||
0lUJTKxU6kZwAM37mRtHlJnQ59/qEGPwCz5fe+wAfzwznRVoGB9VQU00k8TX0TT/
|
|
||||||
JZPPvP2rMcCoiCa6on4Z9gHEtSZN60g35aAcp22SgIk5hxL6bc1OjLN6jDUiVrHf
|
|
||||||
oYcTGwODzpbyMiSO5N+fGJc0f5VvsTZpwUX8oLAKEAECgYEAzvDbAkLpsU6nYjhs
|
|
||||||
SNqsToUhnLYKVtDgHdR4Rx6xnIqNp0Zl/o27lWn9ZT9XTwYtkUzm+Vv1iyYvMIY4
|
|
||||||
3U+0K1vf/Z3fXAptSjwqhRrAEwj6dGu4qsXKcPnabGfNjZqRhx3vAD+T65KQXMrY
|
|
||||||
OhGFC3wuFug1RhQzFUmPt2uYDgECgYEAx4OSHovko6LpuJBto07nuWCRs4aKofzW
|
|
||||||
9imdyAau3PbR34RTs0Wwu+LLY8Q8FKor1Eur+8Dp00WJgI2tLE+iVN9aupK/SdVx
|
|
||||||
ed9UDLnI20nCrf4LFV/HDk7nXLnlvUn2Ndq9lUxi/5AhAfTzibG3q/DwVB5vqdyk
|
|
||||||
PdYm+GSwAWcCgYEAv9aEELqbDWWOwfzwVTFyXnAIUtBnEUgdG0omHjgUCrxeyNz4
|
|
||||||
HFyjssVIxJ1NgNKHV5Vk4XEgVViWknM7L959dVx8bw31S8vWuOTBvhaoTH0cQOTD
|
|
||||||
knw9STI2DBzGbykFE67qKt7Fb7K05XCdtmcbYSRDTbUB/e8n0+oXsr+pfAECgYEA
|
|
||||||
i+aLmJXZ3pDHON81shULUicQJAXMwmfsSDLIa9Gb3l/IrOY6VvQgSK9wlWWuB4OI
|
|
||||||
NlZVo7QTgk05bQZrjy3ME52HHlr2fYyJBL+ATWgdGv+u3pjMJtHBYBweChxkp4Xs
|
|
||||||
erkGxWEJ7lCfhKLB/yS6OXw62ZF6FW8dUCsRqo3YCTMCgYEAr94W8AIlq7uiE7N+
|
|
||||||
jlRzfedml2JcrDzOLDqcixZh454Q5bMSfJJqoCeLxqHQacQhwngVjztn9EtBr+GC
|
|
||||||
IFNYCdCoeBtVnWkizKtKohlwAjmxNY9SENFRwCzF5waQErf1PTcPJvD7JG/4S9vL
|
|
||||||
t84Xs6f6CImQis+03rwtQ3XRc3w=
|
|
||||||
-----END PRIVATE KEY-----
|
|
|
@ -1,345 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
from flask import Flask
|
|
||||||
from flask import render_template, request, session, g, url_for, flash, get_flashed_messages, redirect
|
|
||||||
import sqlite3
|
|
||||||
import json
|
|
||||||
import sys, os
|
|
||||||
from colorama import *
|
|
||||||
import sys
|
|
||||||
from threading import Thread
|
|
||||||
from time import sleep
|
|
||||||
|
|
||||||
from uuid import uuid4
|
|
||||||
|
|
||||||
import flag_server
|
|
||||||
|
|
||||||
from passlib.hash import sha256_crypt
|
|
||||||
from contextlib import closing
|
|
||||||
|
|
||||||
flag_rotation_seconds = 60
|
|
||||||
correct_answers = {}
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
|
|
||||||
# ===========================================================================
|
|
||||||
|
|
||||||
DATABASE = '/tmp/attack.db'
|
|
||||||
CONFIG = 'services.json'
|
|
||||||
CERTIFICATE = 'certificate.crt'
|
|
||||||
PRIVATE_KEY = 'privateKey.key'
|
|
||||||
|
|
||||||
SECRET_KEY = 'this_key_needs_to_be_used_for_session_variables'
|
|
||||||
|
|
||||||
if DATABASE == '$DATABASE':
|
|
||||||
error("This server has not yet been configured with a database file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
if CONFIG == '$CONFIGURATION':
|
|
||||||
error("This server has not yet been configured with a configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
if CERTIFICATE == '$CERTIFICATE_FILE':
|
|
||||||
error("This server has not yet been configured with a certificate!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
if PRIVATE_KEY == '$PRIVATEKEY_FILE':
|
|
||||||
error("This server has not yet been configured with a private key!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
app = Flask( __name__ )
|
|
||||||
|
|
||||||
app.config.from_object(__name__)
|
|
||||||
|
|
||||||
needed_configurations = [
|
|
||||||
"app_title", "app_about", "app_navigation_logged_out",
|
|
||||||
"app_navigation_logged_in", "services"
|
|
||||||
]
|
|
||||||
|
|
||||||
def flag_rotator( services ):
|
|
||||||
global correct_answers
|
|
||||||
|
|
||||||
round = 0
|
|
||||||
while 1:
|
|
||||||
print "FLAG ROUND", round, "="*50
|
|
||||||
correct_answers = {}
|
|
||||||
|
|
||||||
for service in services:
|
|
||||||
flag = flag_server.generate_flag()
|
|
||||||
flag_server.save_flag( flag, "services/" + service['folder_name'] )
|
|
||||||
correct_answers[ flag ] = service['points']
|
|
||||||
|
|
||||||
round += 1
|
|
||||||
sleep( flag_rotation_seconds )
|
|
||||||
|
|
||||||
|
|
||||||
if not ( os.path.exists(CONFIG) ):
|
|
||||||
error("This configuration file '" + CONFIG + "' does not seem to exist!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
success("The configuration file exists!")
|
|
||||||
handle = open( CONFIG )
|
|
||||||
configuration = json.loads(handle.read().replace("\n","").replace("\t",""))
|
|
||||||
try:
|
|
||||||
for needed_config in needed_configurations:
|
|
||||||
assert configuration[needed_config]
|
|
||||||
except Exception as e:
|
|
||||||
error("Configuration file '" + sys.argv[1] + "' does not have the following configuration tag:")
|
|
||||||
warning(e.message)
|
|
||||||
error("Please fix this and re-run the server.")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
success("The configuration looks good!")
|
|
||||||
|
|
||||||
success("Starting the flag rotator...")
|
|
||||||
|
|
||||||
flag_rotation = Thread( target = flag_rotator, args = ( configuration['services'],) )
|
|
||||||
flag_rotation.daemon = True
|
|
||||||
flag_rotation.start()
|
|
||||||
|
|
||||||
success("Spinning up the server...")
|
|
||||||
|
|
||||||
def init_db():
|
|
||||||
with closing(connect_db()) as db:
|
|
||||||
with app.open_resource('schema.sql', mode='r') as f:
|
|
||||||
db.cursor().executescript(f.read())
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
def connect_db():
|
|
||||||
return sqlite3.connect( app.config['DATABASE'] )
|
|
||||||
|
|
||||||
@app.before_request
|
|
||||||
def before_request():
|
|
||||||
g.db = connect_db()
|
|
||||||
|
|
||||||
@app.teardown_request
|
|
||||||
def teardown_request(exception):
|
|
||||||
db = getattr(g, 'db', None)
|
|
||||||
if db is not None:
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
def render( template_name, **kwargs ):
|
|
||||||
return render_template( template_name,
|
|
||||||
app_title = configuration['app_title'],
|
|
||||||
app_navigation_logged_out = configuration['app_navigation_logged_out'],
|
|
||||||
app_navigation_logged_in = configuration['app_navigation_logged_in'],
|
|
||||||
**kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.route("/login", methods=["GET", "POST"])
|
|
||||||
def login():
|
|
||||||
|
|
||||||
error = ""
|
|
||||||
if request.method == "POST":
|
|
||||||
|
|
||||||
cur = g.db.execute('select username, password from users')
|
|
||||||
# username, password_hash
|
|
||||||
users = dict(( row[0], row[1] ) for row in cur.fetchall())
|
|
||||||
|
|
||||||
if not request.form['username'] in users.iterkeys():
|
|
||||||
error = 'This username is not in the database!'
|
|
||||||
else:
|
|
||||||
|
|
||||||
if not ( sha256_crypt.verify( request.form['password'], users[request.form['username']] ) ):
|
|
||||||
error = "Incorrect password!"
|
|
||||||
else:
|
|
||||||
|
|
||||||
session_login( request.form['username'] )
|
|
||||||
|
|
||||||
return redirect( "challenges" )
|
|
||||||
|
|
||||||
return render( 'login.html', error = error )
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/register", methods=["GET", "POST"])
|
|
||||||
def register():
|
|
||||||
|
|
||||||
cur = g.db.execute('select username from users')
|
|
||||||
|
|
||||||
usernames = [row[0] for row in cur.fetchall() ]
|
|
||||||
|
|
||||||
error = ""
|
|
||||||
if request.method == "POST":
|
|
||||||
|
|
||||||
if unicode(request.form['username']) in usernames:
|
|
||||||
error = 'This username is already in use!'
|
|
||||||
elif (request.form['password'] == ""):
|
|
||||||
error = "You must supply a password!"
|
|
||||||
elif request.form['password'] != request.form['confirm']:
|
|
||||||
error = 'Your passwords do not match!'
|
|
||||||
else:
|
|
||||||
|
|
||||||
# I use this for command-line submission...
|
|
||||||
identifier = str(uuid4())
|
|
||||||
|
|
||||||
|
|
||||||
cur = g.db.execute('insert into users (username, password, solved_challenges, score, last_submission, uuid) values ( ?, ?, ?, ?, ?, ? )', [
|
|
||||||
request.form['username'],
|
|
||||||
sha256_crypt.encrypt( request.form['password']),
|
|
||||||
"", # No challenges completed
|
|
||||||
0, # no score.
|
|
||||||
0, # no last submission time,
|
|
||||||
identifier # and a completely unique idenitifier
|
|
||||||
] )
|
|
||||||
|
|
||||||
g.db.commit()
|
|
||||||
|
|
||||||
|
|
||||||
flash("Hello " + request.form['username'] + ", you have successfully registered!")
|
|
||||||
session_login( request.form['username'] )
|
|
||||||
return redirect( "challenges" )
|
|
||||||
|
|
||||||
return render( 'register.html', error = error )
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/scoreboard")
|
|
||||||
def scoreboard():
|
|
||||||
|
|
||||||
cur = g.db.execute('select username, score from users order by score desc, last_submission asc')
|
|
||||||
response = cur.fetchall()
|
|
||||||
|
|
||||||
users = [ { "username": row[0], "score": row[1] } for row in response]
|
|
||||||
|
|
||||||
return render("scoreboard.html", users = users )
|
|
||||||
|
|
||||||
@app.route("/logout")
|
|
||||||
def logout():
|
|
||||||
|
|
||||||
session_logout()
|
|
||||||
return redirect("about")
|
|
||||||
|
|
||||||
@app.route("/")
|
|
||||||
@app.route("/about")
|
|
||||||
def about(): return render("about.html", app_about=configuration['app_about'])
|
|
||||||
|
|
||||||
@app.route("/challenges")
|
|
||||||
def challenges_page():
|
|
||||||
|
|
||||||
if not ( session['logged_in'] ):
|
|
||||||
return render("login.html", error = "You must log in to be able to see the challenges!")
|
|
||||||
try:
|
|
||||||
cur = g.db.execute('select uuid from users where username =?',
|
|
||||||
[ session['username'],] )
|
|
||||||
|
|
||||||
uuid = cur.fetchone()[0]
|
|
||||||
except Exception as e:
|
|
||||||
print error(e.message)
|
|
||||||
uuid = ''
|
|
||||||
|
|
||||||
return render("challenges.html", challenges = configuration['services'], url=request.url_root, session_value = uuid )
|
|
||||||
|
|
||||||
@app.route("/check_answer", methods=["GET", "POST"])
|
|
||||||
def check_answer():
|
|
||||||
|
|
||||||
global correct_answers
|
|
||||||
|
|
||||||
if request.method == "POST":
|
|
||||||
if request.form['answer'] in session['solved_challenges']:
|
|
||||||
|
|
||||||
return json.dumps({'correct': -1});
|
|
||||||
|
|
||||||
if ( request.form['answer'] in correct_answers.keys() ):
|
|
||||||
|
|
||||||
flag = request.form['answer']
|
|
||||||
|
|
||||||
new_score = int(session['score']) + correct_answers[flag]
|
|
||||||
cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')) where username = (?)", [
|
|
||||||
new_score,
|
|
||||||
session['username']
|
|
||||||
] );
|
|
||||||
|
|
||||||
session['solved_challenges'].append( request.form['answer'] )
|
|
||||||
session['score'] = new_score
|
|
||||||
g.db.commit();
|
|
||||||
|
|
||||||
return json.dumps({'correct': 1, 'new_score': new_score});
|
|
||||||
else:
|
|
||||||
return json.dumps({'correct': 0});
|
|
||||||
|
|
||||||
@app.route("/submit", methods=[ "POST" ])
|
|
||||||
def submit():
|
|
||||||
|
|
||||||
global correct_answers
|
|
||||||
|
|
||||||
if request.method == "POST":
|
|
||||||
|
|
||||||
if ( request.form['flag'] in correct_answers.keys() ):
|
|
||||||
|
|
||||||
flag = request.form['flag']
|
|
||||||
|
|
||||||
cur = g.db.execute('select score, solved_challenges from users where uuid = (?)',
|
|
||||||
[ request.form['uuid'], ])
|
|
||||||
|
|
||||||
|
|
||||||
current_score, solved_challenges = cur.fetchone()
|
|
||||||
|
|
||||||
solved_challenges = solved_challenges.split()
|
|
||||||
|
|
||||||
if ( flag in solved_challenges ):
|
|
||||||
return 'You already submitted this flag!\n'
|
|
||||||
|
|
||||||
print solved_challenges
|
|
||||||
|
|
||||||
new_score = current_score + correct_answers[flag]
|
|
||||||
solved_challenges.append( flag + " " )
|
|
||||||
cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')), solved_challenges = (?) where uuid = (?)", [
|
|
||||||
new_score,
|
|
||||||
' '.join(solved_challenges),
|
|
||||||
request.form['uuid']
|
|
||||||
] );
|
|
||||||
|
|
||||||
# session['solved_challenges'].append( request.form['flag'] )
|
|
||||||
session['score'] = new_score
|
|
||||||
g.db.commit();
|
|
||||||
|
|
||||||
# return json.dumps({'correct': 1, 'new_score': new_score});
|
|
||||||
return 'Correct!\n';
|
|
||||||
else:
|
|
||||||
# return json.dumps({'correct': 0});
|
|
||||||
return 'Incorrect!\n';
|
|
||||||
|
|
||||||
def session_login( username ):
|
|
||||||
|
|
||||||
flash("You were successfully logged in!")
|
|
||||||
|
|
||||||
cur = g.db.execute('select solved_challenges, score from users where username = (?)',
|
|
||||||
[username])
|
|
||||||
|
|
||||||
solved_challenges, score = cur.fetchone()
|
|
||||||
|
|
||||||
session['logged_in'] = True
|
|
||||||
session['username'] = username
|
|
||||||
session['score'] = score
|
|
||||||
session['solved_challenges'] = []
|
|
||||||
|
|
||||||
def session_logout():
|
|
||||||
|
|
||||||
flash("You have been successfully logged out.")
|
|
||||||
|
|
||||||
session['logged_in'] = False
|
|
||||||
session.pop('username')
|
|
||||||
session.pop('score')
|
|
||||||
|
|
||||||
if ( __name__ == "__main__" ):
|
|
||||||
context = (CERTIFICATE, PRIVATE_KEY)
|
|
||||||
app.run( host="0.0.0.0", debug=False, ssl_context=context, port = 444 )
|
|
|
@ -1,345 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
from flask import Flask
|
|
||||||
from flask import render_template, request, session, g, url_for, flash, get_flashed_messages, redirect
|
|
||||||
import sqlite3
|
|
||||||
import json
|
|
||||||
import sys, os
|
|
||||||
from colorama import *
|
|
||||||
import sys
|
|
||||||
from threading import Thread
|
|
||||||
from time import sleep
|
|
||||||
|
|
||||||
from uuid import uuid4
|
|
||||||
|
|
||||||
import flag_server
|
|
||||||
|
|
||||||
from passlib.hash import sha256_crypt
|
|
||||||
from contextlib import closing
|
|
||||||
|
|
||||||
flag_rotation_seconds = 60
|
|
||||||
correct_answers = {}
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
|
|
||||||
# ===========================================================================
|
|
||||||
|
|
||||||
DATABASE = '$DATABASE'
|
|
||||||
CONFIG = '$CONFIGURATION'
|
|
||||||
CERTIFICATE = '$CERTIFICATE_FILE'
|
|
||||||
PRIVATE_KEY = '$PRIVATEKEY_FILE'
|
|
||||||
|
|
||||||
SECRET_KEY = 'this_key_needs_to_be_used_for_session_variables'
|
|
||||||
|
|
||||||
if DATABASE == '$DATABASE':
|
|
||||||
error("This server has not yet been configured with a database file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
if CONFIG == '$CONFIGURATION':
|
|
||||||
error("This server has not yet been configured with a configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
if CERTIFICATE == '$CERTIFICATE_FILE':
|
|
||||||
error("This server has not yet been configured with a certificate!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
if PRIVATE_KEY == '$PRIVATEKEY_FILE':
|
|
||||||
error("This server has not yet been configured with a private key!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
app = Flask( __name__ )
|
|
||||||
|
|
||||||
app.config.from_object(__name__)
|
|
||||||
|
|
||||||
needed_configurations = [
|
|
||||||
"app_title", "app_about", "app_navigation_logged_out",
|
|
||||||
"app_navigation_logged_in", "services"
|
|
||||||
]
|
|
||||||
|
|
||||||
def flag_rotator( services ):
|
|
||||||
global correct_answers
|
|
||||||
|
|
||||||
round = 0
|
|
||||||
while 1:
|
|
||||||
print "FLAG ROUND", round, "="*50
|
|
||||||
correct_answers = {}
|
|
||||||
|
|
||||||
for service in services:
|
|
||||||
flag = flag_server.generate_flag()
|
|
||||||
flag_server.save_flag( flag, "services/" + service['folder_name'] )
|
|
||||||
correct_answers[ flag ] = service['points']
|
|
||||||
|
|
||||||
round += 1
|
|
||||||
sleep( flag_rotation_seconds )
|
|
||||||
|
|
||||||
|
|
||||||
if not ( os.path.exists(CONFIG) ):
|
|
||||||
error("This configuration file '" + CONFIG + "' does not seem to exist!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
success("The configuration file exists!")
|
|
||||||
handle = open( CONFIG )
|
|
||||||
configuration = json.loads(handle.read().replace("\n","").replace("\t",""))
|
|
||||||
try:
|
|
||||||
for needed_config in needed_configurations:
|
|
||||||
assert configuration[needed_config]
|
|
||||||
except Exception as e:
|
|
||||||
error("Configuration file '" + sys.argv[1] + "' does not have the following configuration tag:")
|
|
||||||
warning(e.message)
|
|
||||||
error("Please fix this and re-run the server.")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
success("The configuration looks good!")
|
|
||||||
|
|
||||||
success("Starting the flag rotator...")
|
|
||||||
|
|
||||||
flag_rotation = Thread( target = flag_rotator, args = ( configuration['services'],) )
|
|
||||||
flag_rotation.daemon = True
|
|
||||||
flag_rotation.start()
|
|
||||||
|
|
||||||
success("Spinning up the server...")
|
|
||||||
|
|
||||||
def init_db():
|
|
||||||
with closing(connect_db()) as db:
|
|
||||||
with app.open_resource('schema.sql', mode='r') as f:
|
|
||||||
db.cursor().executescript(f.read())
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
def connect_db():
|
|
||||||
return sqlite3.connect( app.config['DATABASE'] )
|
|
||||||
|
|
||||||
@app.before_request
|
|
||||||
def before_request():
|
|
||||||
g.db = connect_db()
|
|
||||||
|
|
||||||
@app.teardown_request
|
|
||||||
def teardown_request(exception):
|
|
||||||
db = getattr(g, 'db', None)
|
|
||||||
if db is not None:
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
def render( template_name, **kwargs ):
|
|
||||||
return render_template( template_name,
|
|
||||||
app_title = configuration['app_title'],
|
|
||||||
app_navigation_logged_out = configuration['app_navigation_logged_out'],
|
|
||||||
app_navigation_logged_in = configuration['app_navigation_logged_in'],
|
|
||||||
**kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.route("/login", methods=["GET", "POST"])
|
|
||||||
def login():
|
|
||||||
|
|
||||||
error = ""
|
|
||||||
if request.method == "POST":
|
|
||||||
|
|
||||||
cur = g.db.execute('select username, password from users')
|
|
||||||
# username, password_hash
|
|
||||||
users = dict(( row[0], row[1] ) for row in cur.fetchall())
|
|
||||||
|
|
||||||
if not request.form['username'] in users.iterkeys():
|
|
||||||
error = 'This username is not in the database!'
|
|
||||||
else:
|
|
||||||
|
|
||||||
if not ( sha256_crypt.verify( request.form['password'], users[request.form['username']] ) ):
|
|
||||||
error = "Incorrect password!"
|
|
||||||
else:
|
|
||||||
|
|
||||||
session_login( request.form['username'] )
|
|
||||||
|
|
||||||
return redirect( "challenges" )
|
|
||||||
|
|
||||||
return render( 'login.html', error = error )
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/register", methods=["GET", "POST"])
|
|
||||||
def register():
|
|
||||||
|
|
||||||
cur = g.db.execute('select username from users')
|
|
||||||
|
|
||||||
usernames = [row[0] for row in cur.fetchall() ]
|
|
||||||
|
|
||||||
error = ""
|
|
||||||
if request.method == "POST":
|
|
||||||
|
|
||||||
if unicode(request.form['username']) in usernames:
|
|
||||||
error = 'This username is already in use!'
|
|
||||||
elif (request.form['password'] == ""):
|
|
||||||
error = "You must supply a password!"
|
|
||||||
elif request.form['password'] != request.form['confirm']:
|
|
||||||
error = 'Your passwords do not match!'
|
|
||||||
else:
|
|
||||||
|
|
||||||
# I use this for command-line submission...
|
|
||||||
identifier = str(uuid4())
|
|
||||||
|
|
||||||
|
|
||||||
cur = g.db.execute('insert into users (username, password, solved_challenges, score, last_submission, uuid) values ( ?, ?, ?, ?, ?, ? )', [
|
|
||||||
request.form['username'],
|
|
||||||
sha256_crypt.encrypt( request.form['password']),
|
|
||||||
"", # No challenges completed
|
|
||||||
0, # no score.
|
|
||||||
0, # no last submission time,
|
|
||||||
identifier # and a completely unique idenitifier
|
|
||||||
] )
|
|
||||||
|
|
||||||
g.db.commit()
|
|
||||||
|
|
||||||
|
|
||||||
flash("Hello " + request.form['username'] + ", you have successfully registered!")
|
|
||||||
session_login( request.form['username'] )
|
|
||||||
return redirect( "challenges" )
|
|
||||||
|
|
||||||
return render( 'register.html', error = error )
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/scoreboard")
|
|
||||||
def scoreboard():
|
|
||||||
|
|
||||||
cur = g.db.execute('select username, score from users order by score desc, last_submission asc')
|
|
||||||
response = cur.fetchall()
|
|
||||||
|
|
||||||
users = [ { "username": row[0], "score": row[1] } for row in response]
|
|
||||||
|
|
||||||
return render("scoreboard.html", users = users )
|
|
||||||
|
|
||||||
@app.route("/logout")
|
|
||||||
def logout():
|
|
||||||
|
|
||||||
session_logout()
|
|
||||||
return redirect("about")
|
|
||||||
|
|
||||||
@app.route("/")
|
|
||||||
@app.route("/about")
|
|
||||||
def about(): return render("about.html", app_about=configuration['app_about'])
|
|
||||||
|
|
||||||
@app.route("/challenges")
|
|
||||||
def challenges_page():
|
|
||||||
|
|
||||||
if not ( session['logged_in'] ):
|
|
||||||
return render("login.html", error = "You must log in to be able to see the challenges!")
|
|
||||||
try:
|
|
||||||
cur = g.db.execute('select uuid from users where username =?',
|
|
||||||
[ session['username'],] )
|
|
||||||
|
|
||||||
uuid = cur.fetchone()[0]
|
|
||||||
except Exception as e:
|
|
||||||
print error(e.message)
|
|
||||||
uuid = ''
|
|
||||||
|
|
||||||
return render("challenges.html", challenges = configuration['services'], url=request.url_root, session_value = uuid )
|
|
||||||
|
|
||||||
@app.route("/check_answer", methods=["GET", "POST"])
|
|
||||||
def check_answer():
|
|
||||||
|
|
||||||
global correct_answers
|
|
||||||
|
|
||||||
if request.method == "POST":
|
|
||||||
if request.form['answer'] in session['solved_challenges']:
|
|
||||||
|
|
||||||
return json.dumps({'correct': -1});
|
|
||||||
|
|
||||||
if ( request.form['answer'] in correct_answers.keys() ):
|
|
||||||
|
|
||||||
flag = request.form['answer']
|
|
||||||
|
|
||||||
new_score = int(session['score']) + correct_answers[flag]
|
|
||||||
cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')) where username = (?)", [
|
|
||||||
new_score,
|
|
||||||
session['username']
|
|
||||||
] );
|
|
||||||
|
|
||||||
session['solved_challenges'].append( request.form['answer'] )
|
|
||||||
session['score'] = new_score
|
|
||||||
g.db.commit();
|
|
||||||
|
|
||||||
return json.dumps({'correct': 1, 'new_score': new_score});
|
|
||||||
else:
|
|
||||||
return json.dumps({'correct': 0});
|
|
||||||
|
|
||||||
@app.route("/submit", methods=[ "POST" ])
|
|
||||||
def submit():
|
|
||||||
|
|
||||||
global correct_answers
|
|
||||||
|
|
||||||
if request.method == "POST":
|
|
||||||
|
|
||||||
if ( request.form['flag'] in correct_answers.keys() ):
|
|
||||||
|
|
||||||
flag = request.form['flag']
|
|
||||||
|
|
||||||
cur = g.db.execute('select score, solved_challenges from users where uuid = (?)',
|
|
||||||
[ request.form['uuid'], ])
|
|
||||||
|
|
||||||
|
|
||||||
current_score, solved_challenges = cur.fetchone()
|
|
||||||
|
|
||||||
solved_challenges = solved_challenges.split()
|
|
||||||
|
|
||||||
if ( flag in solved_challenges ):
|
|
||||||
return 'You already submitted this flag!\n'
|
|
||||||
|
|
||||||
print solved_challenges
|
|
||||||
|
|
||||||
new_score = current_score + correct_answers[flag]
|
|
||||||
solved_challenges.append( flag + " " )
|
|
||||||
cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')), solved_challenges = (?) where uuid = (?)", [
|
|
||||||
new_score,
|
|
||||||
' '.join(solved_challenges),
|
|
||||||
request.form['uuid']
|
|
||||||
] );
|
|
||||||
|
|
||||||
# session['solved_challenges'].append( request.form['flag'] )
|
|
||||||
session['score'] = new_score
|
|
||||||
g.db.commit();
|
|
||||||
|
|
||||||
# return json.dumps({'correct': 1, 'new_score': new_score});
|
|
||||||
return 'Correct!\n';
|
|
||||||
else:
|
|
||||||
# return json.dumps({'correct': 0});
|
|
||||||
return 'Incorrect!\n';
|
|
||||||
|
|
||||||
def session_login( username ):
|
|
||||||
|
|
||||||
flash("You were successfully logged in!")
|
|
||||||
|
|
||||||
cur = g.db.execute('select solved_challenges, score from users where username = (?)',
|
|
||||||
[username])
|
|
||||||
|
|
||||||
solved_challenges, score = cur.fetchone()
|
|
||||||
|
|
||||||
session['logged_in'] = True
|
|
||||||
session['username'] = username
|
|
||||||
session['score'] = score
|
|
||||||
session['solved_challenges'] = []
|
|
||||||
|
|
||||||
def session_logout():
|
|
||||||
|
|
||||||
flash("You have been successfully logged out.")
|
|
||||||
|
|
||||||
session['logged_in'] = False
|
|
||||||
session.pop('username')
|
|
||||||
session.pop('score')
|
|
||||||
|
|
||||||
if ( __name__ == "__main__" ):
|
|
||||||
context = (CERTIFICATE, PRIVATE_KEY)
|
|
||||||
app.run( host="0.0.0.0", debug=False, ssl_context=context, port = 444 )
|
|
|
@ -1,176 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-14 17:03:36
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice, seed
|
|
||||||
from time import mktime, gmtime, sleep
|
|
||||||
from string import digits as nums
|
|
||||||
from json import loads
|
|
||||||
import sys
|
|
||||||
|
|
||||||
service_name = "Balloon Saloon"
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string + "\n"
|
|
||||||
|
|
||||||
def info( string ):
|
|
||||||
print Fore.CYAN + "[.] " + string + "\n"
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
def info( string ): pass
|
|
||||||
|
|
||||||
def get_port():
|
|
||||||
handle = open("../../services.json")
|
|
||||||
data = handle.read()
|
|
||||||
data = loads(data.replace("\n",'').replace('\t',''))
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
port = None
|
|
||||||
for service in data['services']:
|
|
||||||
if service_name == service['title']:
|
|
||||||
port = int(service['port'])
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
error("Port number not found in the configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
return port
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host = '0.0.0.0'
|
|
||||||
port = get_port()
|
|
||||||
board = \
|
|
||||||
'''
|
|
||||||
| |
|
|
||||||
1 | 2 | 3
|
|
||||||
____|_____|_____
|
|
||||||
| |
|
|
||||||
4 | 5 | 6
|
|
||||||
____|_____|_____
|
|
||||||
| |
|
|
||||||
7 | 8 | 9
|
|
||||||
| |
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self ):
|
|
||||||
self.send( "> ", newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
info( "Received connection from " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
# Client-side: ...
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
# run self.functions()...
|
|
||||||
pass
|
|
||||||
|
|
||||||
except:
|
|
||||||
log( Fore.YELLOW + self.client_address[0] + " dropped connection!" )
|
|
||||||
'''
|
|
||||||
|
|
||||||
self.send("There are 9 places the balloon can land, but it floats away at RANDOM!")
|
|
||||||
self.send( board )
|
|
||||||
self.send("Can you hit the balloon? I'm going to let the balloon go ... RIGHT NOW!")
|
|
||||||
|
|
||||||
random_seed = int( mktime(gmtime()) )
|
|
||||||
seed(random_seed)
|
|
||||||
|
|
||||||
position = None
|
|
||||||
entered = -1
|
|
||||||
while int(entered) - 1 != position:
|
|
||||||
self.send("What spot will you shoot?")
|
|
||||||
entered = self.receive()
|
|
||||||
position = randint(0, 8)
|
|
||||||
try:
|
|
||||||
if ( int(entered) - 1 == position ):
|
|
||||||
self.send("You shot the balloon! Here is your reward")
|
|
||||||
self.send(get_flag())
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.send( "Aww, you missed! Here's where the balloon was:")
|
|
||||||
balloon = board.replace( str(position + 1), 'O' )
|
|
||||||
for i in nums:
|
|
||||||
balloon = balloon.replace( str(i), ' ' )
|
|
||||||
self.send( balloon )
|
|
||||||
self.send("Try again!")
|
|
||||||
|
|
||||||
continue
|
|
||||||
except ValueError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
info( "Ended connection with " + str(self.client_address) + "." )
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_flag()
|
|
||||||
except:
|
|
||||||
error( "Could not get flag file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
info("Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.daemon = True
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
success( service_name + " started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
# Now let the main thread just wait...
|
|
||||||
while ( True ): sleep(10)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: John Hammond
|
|
||||||
# @Last Modified time: 2016-02-10 17:16:36
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice, seed
|
|
||||||
from time import mktime, gmtime
|
|
||||||
from string import digits as nums
|
|
||||||
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host, port = "0.0.0.0", 5029
|
|
||||||
logging = True
|
|
||||||
|
|
||||||
service_name = "Balloon Saloon"
|
|
||||||
|
|
||||||
board = \
|
|
||||||
'''
|
|
||||||
| |
|
|
||||||
1 | 2 | 3
|
|
||||||
____|_____|_____
|
|
||||||
| |
|
|
||||||
4 | 5 | 6
|
|
||||||
____|_____|_____
|
|
||||||
| |
|
|
||||||
7 | 8 | 9
|
|
||||||
| |
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self ):
|
|
||||||
self.send( "> ", newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
log( Fore.CYAN + "Received connection from " + \
|
|
||||||
str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
# Client-side: ...
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
# run self.functions()...
|
|
||||||
pass
|
|
||||||
|
|
||||||
except:
|
|
||||||
log( Fore.YELLOW + self.client_address[0] + " dropped connection!" )
|
|
||||||
'''
|
|
||||||
|
|
||||||
self.send("There are now 100 places the balloon can land, but it floats away at RANDOM!")
|
|
||||||
self.send( board )
|
|
||||||
self.send("Can you hit the balloon? I'm going to let the balloon go ... RIGHT NOW!")
|
|
||||||
|
|
||||||
random_seed = int( mktime(gmtime()) )
|
|
||||||
|
|
||||||
position = None
|
|
||||||
entered = -1
|
|
||||||
while int(entered) - 1 != position:
|
|
||||||
self.send("What spot will you shoot?")
|
|
||||||
entered = self.receive()
|
|
||||||
position = randint(0, 8)
|
|
||||||
try:
|
|
||||||
if ( int(entered) - 1 == position ):
|
|
||||||
self.send("You shot the balloon! Here is your reward")
|
|
||||||
self.send(get_flag())
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.send( "Aww, you missed! Here's where the balloon was:")
|
|
||||||
balloon = board.replace( str(position + 1), 'O' )
|
|
||||||
for i in nums:
|
|
||||||
balloon = balloon.replace( str(i), ' ' )
|
|
||||||
self.send( balloon )
|
|
||||||
self.send("Try again!")
|
|
||||||
|
|
||||||
continue
|
|
||||||
except ValueError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def log( string ):
|
|
||||||
if logging: print string
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
# Turn on colors...
|
|
||||||
init( autoreset=True )
|
|
||||||
|
|
||||||
log( Fore.CYAN + "Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
log( Fore.MAGENTA + Style.BRIGHT + service_name + \
|
|
||||||
Fore.GREEN + " server started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
30e62931eae444ed95d47d40878b56ff8cafc464
|
|
|
@ -1,123 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-14 17:03:10
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice, seed
|
|
||||||
from time import mktime, gmtime, sleep
|
|
||||||
from string import digits as nums
|
|
||||||
from json import loads
|
|
||||||
import sys
|
|
||||||
|
|
||||||
service_name = "Service Name"
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string + "\n"
|
|
||||||
|
|
||||||
def info( string ):
|
|
||||||
print Fore.CYAN + "[.] " + string + "\n"
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
def info( string ): pass
|
|
||||||
|
|
||||||
def get_port():
|
|
||||||
handle = open("../../services.json")
|
|
||||||
data = handle.read()
|
|
||||||
data = loads(data.replace("\n",'').replace('\t',''))
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
port = None
|
|
||||||
for service in data['services']:
|
|
||||||
if service_name == service['title']:
|
|
||||||
port = int(service['port'])
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
error("Port number not found in the configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
return port
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host = '0.0.0.0'
|
|
||||||
port = get_port()
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self ):
|
|
||||||
self.send( "> ", newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
info( "Received connection from " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
info( "Ended connection with " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_flag()
|
|
||||||
except:
|
|
||||||
error( "Could not get flag file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
info("Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.daemon = True
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
success( service_name + " started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
# Now let the main thread just wait...
|
|
||||||
while ( True ): sleep(10)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -1,146 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-14 17:03:45
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice, seed
|
|
||||||
from time import mktime, gmtime, sleep
|
|
||||||
from string import digits as nums
|
|
||||||
from json import loads
|
|
||||||
import sys
|
|
||||||
|
|
||||||
service_name = "BitBot"
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string + "\n"
|
|
||||||
|
|
||||||
def info( string ):
|
|
||||||
print Fore.CYAN + "[.] " + string + "\n"
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
def info( string ): pass
|
|
||||||
|
|
||||||
def get_port():
|
|
||||||
handle = open("../../services.json")
|
|
||||||
data = handle.read()
|
|
||||||
data = loads(data.replace("\n",'').replace('\t',''))
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
port = None
|
|
||||||
for service in data['services']:
|
|
||||||
if service_name == service['title']:
|
|
||||||
port = int(service['port'])
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
error("Port number not found in the configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
return port
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host = '0.0.0.0'
|
|
||||||
port = get_port()
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self, prompt = "" ):
|
|
||||||
self.send( prompt, newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
info( "Received connection from " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
# Client-side: ...
|
|
||||||
# try:
|
|
||||||
# run self.functions()...
|
|
||||||
|
|
||||||
flag = get_flag()
|
|
||||||
|
|
||||||
try:
|
|
||||||
for bit in flag:
|
|
||||||
sent = bin(ord(bit))[2:]
|
|
||||||
self.send( sent )
|
|
||||||
entered = self.receive()
|
|
||||||
if ( entered != sent ):
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
warning( "Dropped connection with " + str(self.client_address) + "." )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
info( "Ended connection with " + str(self.client_address) + "." )
|
|
||||||
|
|
||||||
|
|
||||||
# except:
|
|
||||||
# log( Fore.YELLOW + self.client_address[0] + " dropped connection!" )
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_flag()
|
|
||||||
except:
|
|
||||||
error( "Could not get flag file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
info("Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.daemon = True
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
success( service_name + " started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
# Now let the main thread just wait...
|
|
||||||
while ( True ): sleep(10)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -1 +0,0 @@
|
||||||
3ca209fda0cb0fe0f2f13ed9e19c80cbf7703d1e
|
|
|
@ -1,136 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-14 17:03:55
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice, seed
|
|
||||||
from time import mktime, gmtime, sleep
|
|
||||||
from string import digits as nums
|
|
||||||
from json import loads
|
|
||||||
import sys
|
|
||||||
|
|
||||||
service_name = "ByteBot"
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string + "\n"
|
|
||||||
|
|
||||||
def info( string ):
|
|
||||||
print Fore.CYAN + "[.] " + string + "\n"
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
def info( string ): pass
|
|
||||||
|
|
||||||
def get_port():
|
|
||||||
handle = open("../../services.json")
|
|
||||||
data = handle.read()
|
|
||||||
data = loads(data.replace("\n",'').replace('\t',''))
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
port = None
|
|
||||||
for service in data['services']:
|
|
||||||
if service_name == service['title']:
|
|
||||||
port = int(service['port'])
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
error("Port number not found in the configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
return port
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host = '0.0.0.0'
|
|
||||||
port = get_port()
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self, prompt = "" ):
|
|
||||||
self.send( prompt, newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
info( "Received connection from " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
flag = get_flag()
|
|
||||||
|
|
||||||
self.send("Hello! I'm the ByteBot! ", newline = False)
|
|
||||||
|
|
||||||
for bit in flag:
|
|
||||||
self.send( "Here is part of the flag: " + bit )
|
|
||||||
entered = self.receive()
|
|
||||||
if ( entered != bit ):
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
info( "Ended connection with " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_flag()
|
|
||||||
except:
|
|
||||||
error( "Could not get flag file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
info("Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.daemon = True
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
success( service_name + " started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
# Now let the main thread just wait...
|
|
||||||
while ( True ): sleep(10)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
a5fb5cc517e81ed61f184fed3f76d65822053e8b
|
|
|
@ -1,127 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-14 17:04:06
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice, seed
|
|
||||||
from time import mktime, gmtime, sleep
|
|
||||||
from string import digits as nums
|
|
||||||
from json import loads
|
|
||||||
import sys
|
|
||||||
from base64 import b64encode
|
|
||||||
|
|
||||||
service_name = "D-CODE"
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string + "\n"
|
|
||||||
|
|
||||||
def info( string ):
|
|
||||||
print Fore.CYAN + "[.] " + string + "\n"
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
def info( string ): pass
|
|
||||||
|
|
||||||
def get_port():
|
|
||||||
handle = open("../../services.json")
|
|
||||||
data = handle.read()
|
|
||||||
data = loads(data.replace("\n",'').replace('\t',''))
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
port = None
|
|
||||||
for service in data['services']:
|
|
||||||
if service_name == service['title']:
|
|
||||||
port = int(service['port'])
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
error("Port number not found in the configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
return port
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host = '0.0.0.0'
|
|
||||||
port = get_port()
|
|
||||||
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag', 'r' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self ):
|
|
||||||
self.send( "> ", newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
info( "Received connection from " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
# Client-side: ...
|
|
||||||
|
|
||||||
self.send( b64encode(get_flag()) )
|
|
||||||
|
|
||||||
info( "Ended connection with " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_flag()
|
|
||||||
except:
|
|
||||||
error( "Could not get flag file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
info("Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.daemon = True
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
success( service_name + " started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
# Now let the main thread just wait...
|
|
||||||
while ( True ): sleep(10)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
8041b71f6711756b2be286547b2024aef0fefadf
|
|
|
@ -1 +0,0 @@
|
||||||
2617780d830597c701758eb6a0ceafc52b84d82b
|
|
|
@ -1,129 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-14 17:04:24
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice, seed
|
|
||||||
from time import mktime, gmtime, sleep
|
|
||||||
from string import digits as nums
|
|
||||||
from json import loads
|
|
||||||
import sys
|
|
||||||
|
|
||||||
service_name = "Flagger"
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string + "\n"
|
|
||||||
|
|
||||||
def info( string ):
|
|
||||||
print Fore.CYAN + "[.] " + string + "\n"
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
def info( string ): pass
|
|
||||||
|
|
||||||
def get_port():
|
|
||||||
handle = open("../../services.json")
|
|
||||||
data = handle.read()
|
|
||||||
data = loads(data.replace("\n",'').replace('\t',''))
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
port = None
|
|
||||||
for service in data['services']:
|
|
||||||
if service_name == service['title']:
|
|
||||||
port = int(service['port'])
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
error("Port number not found in the configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
return port
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host = '0.0.0.0'
|
|
||||||
port = get_port()
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag', 'r' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self ):
|
|
||||||
self.send( "> ", newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
info( "Received connection from " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
# Client-side: ...
|
|
||||||
try:
|
|
||||||
self.send( get_flag() )
|
|
||||||
pass
|
|
||||||
|
|
||||||
except:
|
|
||||||
warning( self.client_address[0] + " dropped connection!" )
|
|
||||||
|
|
||||||
info( "Ended connection with " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_flag()
|
|
||||||
except:
|
|
||||||
error( "Could not get flag file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
info("Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.daemon = True
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
success( service_name + " started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
# Now let the main thread just wait...
|
|
||||||
while ( True ): sleep(10)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 10:40:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-08 18:41:39
|
|
||||||
|
|
||||||
from pwnlib import *
|
|
||||||
|
|
||||||
import socket
|
|
||||||
|
|
||||||
host = 'localhost'
|
|
||||||
port = 5060
|
|
||||||
|
|
||||||
s = tubes.remote.remote( host, port )
|
|
||||||
|
|
||||||
print s.recvuntil("> ")
|
|
||||||
s.sendline('y')
|
|
||||||
print s.recvuntil("> ")
|
|
||||||
|
|
||||||
while (True):
|
|
||||||
s.sendline('on')
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
print s.recv()
|
|
||||||
|
|
||||||
except:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print some_error_variable.message
|
|
||||||
print "It dropped connection!"
|
|
||||||
|
|
||||||
|
|
||||||
s.close()
|
|
|
@ -1 +0,0 @@
|
||||||
3ccc616747dbfaffe78b6e80701a77afd189f25f
|
|
|
@ -1,197 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-14 17:04:35
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice, seed
|
|
||||||
from time import mktime, gmtime, sleep
|
|
||||||
from string import digits as nums
|
|
||||||
from json import loads
|
|
||||||
import sys
|
|
||||||
|
|
||||||
service_name = "LampChamp 0"
|
|
||||||
|
|
||||||
debug = True
|
|
||||||
init( autoreset = True )
|
|
||||||
|
|
||||||
if (debug):
|
|
||||||
|
|
||||||
def success( string ):
|
|
||||||
print Fore.GREEN + Style.BRIGHT + "[+] " + string
|
|
||||||
|
|
||||||
def error( string ):
|
|
||||||
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
|
|
||||||
|
|
||||||
def warning( string ):
|
|
||||||
print Fore.YELLOW + "[!] " + string + "\n"
|
|
||||||
|
|
||||||
def info( string ):
|
|
||||||
print Fore.CYAN + "[.] " + string + "\n"
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
def success( string ): pass
|
|
||||||
def error( string ): pass
|
|
||||||
def warning( string ): pass
|
|
||||||
def info( string ): pass
|
|
||||||
|
|
||||||
def get_port():
|
|
||||||
handle = open("../../services.json")
|
|
||||||
data = handle.read()
|
|
||||||
data = loads(data.replace("\n",'').replace('\t',''))
|
|
||||||
handle.close()
|
|
||||||
|
|
||||||
port = None
|
|
||||||
for service in data['services']:
|
|
||||||
if service_name == service['title']:
|
|
||||||
port = int(service['port'])
|
|
||||||
|
|
||||||
if port == None:
|
|
||||||
error("Port number not found in the configuration file!")
|
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
return port
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host = '0.0.0.0'
|
|
||||||
port = get_port()
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
def center_text( text, width ):
|
|
||||||
sides = width / 2 - len(text) / 2
|
|
||||||
return " " * sides + text + " " * sides
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self ):
|
|
||||||
self.send( "> ", newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def print_banner( self ):
|
|
||||||
|
|
||||||
self.send( "=" * max_width)
|
|
||||||
self.send( center_text( "Welcome to LampChamp!", max_width ) )
|
|
||||||
|
|
||||||
self.send( "=" * max_width )
|
|
||||||
self.send( "" )
|
|
||||||
|
|
||||||
def prompt( self ):
|
|
||||||
ready = False
|
|
||||||
|
|
||||||
self.send( "To become the LampChamp, you must turn on ALL the lights!" )
|
|
||||||
self.send( "How many will there be? Well, you'll never know!" )
|
|
||||||
|
|
||||||
self.send("")
|
|
||||||
self.send( "Are you ready for this challenge? (y/n)" )
|
|
||||||
|
|
||||||
while ( not ready ):
|
|
||||||
|
|
||||||
entered = self.receive()
|
|
||||||
|
|
||||||
if ( entered.startswith( "y" ) ):
|
|
||||||
ready = True
|
|
||||||
else:
|
|
||||||
self.send( "Awww, why not? Come on, think it over! Are you ready? (y/n)" )
|
|
||||||
ready = False
|
|
||||||
|
|
||||||
self.send( "Awesome! Good luck!" )
|
|
||||||
self.send( "Here is your first task: " )
|
|
||||||
self.send( "" )
|
|
||||||
|
|
||||||
def test_lamps( self ):
|
|
||||||
|
|
||||||
'''
|
|
||||||
This initialize() function takes the place of the object's
|
|
||||||
__init__() constructor because that is annoying to overwrite with
|
|
||||||
a threaded SocketServer object.
|
|
||||||
'''
|
|
||||||
|
|
||||||
number_of_lamps = randint(100,300)
|
|
||||||
|
|
||||||
for i in range( number_of_lamps ):
|
|
||||||
|
|
||||||
self.send( lamps[i % len(lamps)] )
|
|
||||||
self.send( "Turn ON this lamp!" )
|
|
||||||
|
|
||||||
lamp_state = self.receive( ).lower()
|
|
||||||
if ( lamp_state == "on" or lamp_state == "turn on"):
|
|
||||||
self.send( "Congrats! You've now turned on " + str(i+1) + " lamps! " +\
|
|
||||||
"You're almost the LampChamp!" )
|
|
||||||
else:
|
|
||||||
self.send("Boo! You weren't able to turn the lamp on!")
|
|
||||||
self.send("You can't handle this challenge. Better luck next time!")
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.send("")
|
|
||||||
self.send("You did it! You got all the lamps!")
|
|
||||||
self.send("YOU ARE THE NEW LAMPCHAMP!!!")
|
|
||||||
self.send("Here is your reward:")
|
|
||||||
self.send( get_flag() )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
info( "Received connection from " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
# Client-side: ...
|
|
||||||
try:
|
|
||||||
self.print_banner()
|
|
||||||
self.prompt()
|
|
||||||
self.test_lamps()
|
|
||||||
except:
|
|
||||||
warning( self.client_address[0] + " dropped connection!" )
|
|
||||||
|
|
||||||
info( "Ended connection with " + str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_flag()
|
|
||||||
except:
|
|
||||||
error( "Could not get flag file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
info("Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.daemon = True
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
success( service_name + " started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
# Now let the main thread just wait...
|
|
||||||
while ( True ): sleep(10)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -1,257 +0,0 @@
|
||||||
# This file includes an array of strings that are used as the lamp images.
|
|
||||||
lamps = [
|
|
||||||
r'''
|
|
||||||
_____
|
|
||||||
/ \
|
|
||||||
/ \
|
|
||||||
/_________\
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
_| |_
|
|
||||||
(_____)
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
_____
|
|
||||||
/ \
|
|
||||||
/ \
|
|
||||||
/_________\
|
|
||||||
_|_|_
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
|_____|
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
______
|
|
||||||
___________________.' // \\
|
|
||||||
/ \\\\| // \\
|
|
||||||
| `""` ||.-.||
|
|
||||||
| ||'-'||
|
|
||||||
\___________________ \\ //
|
|
||||||
'.___\\_//
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
_...._
|
|
||||||
.' '.
|
|
||||||
/ \
|
|
||||||
| |
|
|
||||||
\ ~~ /
|
|
||||||
`\ || /`
|
|
||||||
|_||_|
|
|
||||||
{____}
|
|
||||||
{____}
|
|
||||||
()
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
_.-"```"-._
|
|
||||||
.' '.
|
|
||||||
/ .-. \
|
|
||||||
; | | ;
|
|
||||||
| | | |
|
|
||||||
; \_/ ;
|
|
||||||
\ (_) /
|
|
||||||
'. .'
|
|
||||||
`;_______;`
|
|
||||||
|_..--"`)
|
|
||||||
(_..--'`|
|
|
||||||
|_..--'`)
|
|
||||||
(_..--'`|
|
|
||||||
`-...-`
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
__
|
|
||||||
."` `".
|
|
||||||
/ \
|
|
||||||
| .-..-. |
|
|
||||||
\ \ / /
|
|
||||||
'.____.'
|
|
||||||
{_.="}
|
|
||||||
{_.="}
|
|
||||||
`-..-`
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
.
|
|
||||||
. .
|
|
||||||
.
|
|
||||||
|
|
|
||||||
. ~ ~ ~ ~ ~ ~ .
|
|
||||||
` `$'`$'`$'`$'`S '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
' '
|
|
||||||
. . '`$' `S''. .
|
|
||||||
`. `$' `$' `$` `$' `$' `$' .'
|
|
||||||
` , , , , , , , , , , '
|
|
||||||
( ) )
|
|
||||||
) * ( (
|
|
||||||
( * ) )
|
|
||||||
) * ( *
|
|
||||||
( * )
|
|
||||||
) * (
|
|
||||||
( * )
|
|
||||||
) * (
|
|
||||||
( * )
|
|
||||||
( * )
|
|
||||||
) * (
|
|
||||||
( * )
|
|
||||||
`@~@~@~@~@~@'
|
|
||||||
`@.@.@.@.@'
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
_____
|
|
||||||
/ \
|
|
||||||
|_____|
|
|
||||||
/ _ \
|
|
||||||
/ ( ) \
|
|
||||||
/ ` \
|
|
||||||
/ _ \
|
|
||||||
/ ( ) \
|
|
||||||
\ )\ /
|
|
||||||
\ ( ) /
|
|
||||||
\ ,-'( /
|
|
||||||
\/-----\/
|
|
||||||
| |
|
|
||||||
/ \
|
|
||||||
/_________\--._
|
|
||||||
.-._)
|
|
||||||
(__
|
|
||||||
`-|E
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
.88888888.
|
|
||||||
.8888888888.
|
|
||||||
.88 88.
|
|
||||||
.88 88.
|
|
||||||
.88 88.
|
|
||||||
.88 88.
|
|
||||||
.88 ::. 88.
|
|
||||||
.88 ':' 88.
|
|
||||||
.88 .::. 88.
|
|
||||||
.88 .:::: 88.
|
|
||||||
.88 ':::' 88.
|
|
||||||
.88 .:::. .:. .: 88.
|
|
||||||
.88 ::::: ':' ':' 88.
|
|
||||||
88 ':::' .::. 88
|
|
||||||
88 .::. .::::: .:. 88
|
|
||||||
88 '::' :::::' ':' 88
|
|
||||||
'88 .::::: .::. 88'
|
|
||||||
'88 .:::::' ::::: 88'
|
|
||||||
'88 ::::::. ':::' 88'
|
|
||||||
'88 ::::::::. 88'
|
|
||||||
'88 .:. ::::::::. 88'
|
|
||||||
'88 '::.::::::::::..88'
|
|
||||||
'88 .::::::::::::::88'
|
|
||||||
'88::::::::::::::88'
|
|
||||||
'88::::::::::::88'
|
|
||||||
88::::::::::::88
|
|
||||||
.888888888888888888.
|
|
||||||
.888%%%%%%%%%%%%%%888.
|
|
||||||
.888%%%%%%%%%%%%%%%%888.
|
|
||||||
.888%%%%%%%%%%%%%%%%%%888.
|
|
||||||
.888%%%%%%%%%%%%%%%%%%%%888.
|
|
||||||
888%%JGS%%%%%%%%%%%%%%%%%%%888
|
|
||||||
88888888888888888888888888888888
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
.--._.--.--.__.--.--.__.--.--.__.--.--._.--.
|
|
||||||
_(_ _Y_ _Y_ _Y_ _Y_ _)_
|
|
||||||
[___] [___] [___] [___] [___] [___]
|
|
||||||
/:' \ /:' \ /:' \ /:' \ /:' \ /:' \
|
|
||||||
|:: | |:: | |:: | |:: | |:: | |:: |
|
|
||||||
\::. / \::. / \::. / \::. / \::. / \::. /
|
|
||||||
\::./ \::./ \::./ \::./ \::./ \::./
|
|
||||||
'=' '=' '=' '=' '=' '='
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
_ _ _
|
|
||||||
'.` `.'
|
|
||||||
_ >_< _
|
|
||||||
_.-'`-.-=-.-`'-._
|
|
||||||
.;'.--./ \.--.';.
|
|
||||||
.' > \ / < '.
|
|
||||||
/.__./\__.';-=-;'.__/\.__.\
|
|
||||||
| \ / \/ \/ \ / |
|
|
||||||
; | | | | |
|
|
||||||
'._/\ /\ /\ /\_.'
|
|
||||||
`-` ;-.-;2 `-`
|
|
||||||
> <
|
|
||||||
.-'{___}'-.
|
|
||||||
'-.._____..-'
|
|
||||||
|||
|
|
||||||
|||
|
|
||||||
/'-'\
|
|
||||||
.-',_ _,'-.
|
|
||||||
/'-. .`. .-'\
|
|
||||||
.=' . `. .` . '=.
|
|
||||||
'-'`-./ \.-`'-'
|
|
||||||
'._.'
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
(~)
|
|
||||||
(' `)
|
|
||||||
).(
|
|
||||||
(`_~_ _ _~_')
|
|
||||||
/` / | \ '\
|
|
||||||
/ --- /----|----\ --- \
|
|
||||||
/_____ /_____|_____\ _____\
|
|
||||||
` / | \ '
|
|
||||||
`------/-------|-------\------'
|
|
||||||
`- - - /- - - - | - - - -\ - - -'
|
|
||||||
` /.\ | /.\ | /.\ | /.\ '
|
|
||||||
` \~/ | \~/ | \~/ | \~/ '
|
|
||||||
`\ /`\ /`\ /`\ /`\ /`\ /`\ /`\ /'
|
|
||||||
` ` ` (_`___`_) ` | ` `
|
|
||||||
) ( |
|
|
||||||
) ( *
|
|
||||||
( )
|
|
||||||
( )
|
|
||||||
` '
|
|
||||||
` '
|
|
||||||
` '
|
|
||||||
` '
|
|
||||||
` '
|
|
||||||
` '
|
|
||||||
` '
|
|
||||||
` '
|
|
||||||
`. .'
|
|
||||||
) ` ` (
|
|
||||||
( ~ ` ~` ~ )
|
|
||||||
------------------` ~ ~ ~ ~ '--------------
|
|
||||||
''',
|
|
||||||
r'''
|
|
||||||
___
|
|
||||||
.-"` `"-.
|
|
||||||
.' '.
|
|
||||||
/ \
|
|
||||||
/ # \
|
|
||||||
| # |
|
|
||||||
| |
|
|
||||||
; .-~~~-. ;
|
|
||||||
; ) ( ;
|
|
||||||
\ ( ) /
|
|
||||||
\ \ / /
|
|
||||||
\ ) ( /
|
|
||||||
| | | |
|
|
||||||
|__|_|__|
|
|
||||||
{=======}
|
|
||||||
}======={
|
|
||||||
{=======}
|
|
||||||
}======={
|
|
||||||
{=======}
|
|
||||||
`""u""`
|
|
||||||
''',
|
|
||||||
]
|
|
|
@ -1,86 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# @Author: john
|
|
||||||
# @Date: 2016-02-08 08:44:14
|
|
||||||
# @Last Modified by: john
|
|
||||||
# @Last Modified time: 2016-02-08 16:35:22
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import SocketServer
|
|
||||||
from colorama import *
|
|
||||||
from random import randint, choice
|
|
||||||
|
|
||||||
# DECLARE ALL INITIAL CONSTANTS
|
|
||||||
host, port = "0.0.0.0", 5000
|
|
||||||
logging = True
|
|
||||||
|
|
||||||
service_name = "QR-uiz"
|
|
||||||
|
|
||||||
class Service(SocketServer.BaseRequestHandler):
|
|
||||||
|
|
||||||
def get_flag():
|
|
||||||
|
|
||||||
h = open( 'flag' )
|
|
||||||
the_flag = h.read()
|
|
||||||
h.close()
|
|
||||||
return the_flag
|
|
||||||
|
|
||||||
def send( self, string, newline = True ):
|
|
||||||
if newline: string = string + "\n"
|
|
||||||
|
|
||||||
self.request.sendall( string )
|
|
||||||
|
|
||||||
def receive( self ):
|
|
||||||
self.send( "> ", newline=False )
|
|
||||||
return self.request.recv( 4096 ).strip()
|
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
'''
|
|
||||||
This handle() function is like the main function of the server;
|
|
||||||
it is what is ran after each connection.
|
|
||||||
'''
|
|
||||||
|
|
||||||
# Server-side: ...
|
|
||||||
log( Fore.CYAN + "Received connection from " + \
|
|
||||||
str(self.client_address) + "!" )
|
|
||||||
|
|
||||||
# Client-side: ...
|
|
||||||
try:
|
|
||||||
# run self.functions()...
|
|
||||||
pass
|
|
||||||
|
|
||||||
except:
|
|
||||||
log( Fore.YELLOW + self.client_address[0] + " dropped connection!" )
|
|
||||||
|
|
||||||
class ThreadedService(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def log( string ):
|
|
||||||
if logging: print string
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
# Turn on colors...
|
|
||||||
init( autoreset=True )
|
|
||||||
|
|
||||||
try:
|
|
||||||
get_flag()
|
|
||||||
except:
|
|
||||||
log( Fore.RED + Style.BRIGHT + "Could not get flag file!")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
log( Fore.CYAN + "Starting server..." )
|
|
||||||
|
|
||||||
server = ThreadedService((host, port), Service)
|
|
||||||
server.allow_reuse_address = True
|
|
||||||
|
|
||||||
log( Fore.MAGENTA + Style.BRIGHT + service_name + \
|
|
||||||
Fore.GREEN + " server started on " + str(server.server_address) + "!")
|
|
||||||
|
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
|
||||||
server_thread.start()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -1,176 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# Author: John Hammond
|
|
||||||
# Date: 11JAN2016
|
|
||||||
# Description:
|
|
||||||
# This script should install all the necessary dependencies and generate a self-signing
|
|
||||||
# certificate to be used by a CTF server you can run on your own local machine.
|
|
||||||
# If you configure your own CTF with a .json file, you can give that to the server
|
|
||||||
# script and it will easily spin up a CTF competition for everyone in the local
|
|
||||||
# network.
|
|
||||||
#
|
|
||||||
|
|
||||||
# Optional variables: this should be modified by the commandline arguments
|
|
||||||
DATABASE=""
|
|
||||||
CONFIGURATION=""
|
|
||||||
|
|
||||||
# Internal variables; do not edit.
|
|
||||||
DEPENDENCIES="python-pip sqlite3 python-flask python-passlib"
|
|
||||||
SERVER_FILE="server_base.py"
|
|
||||||
NEW_SERVER_FILE="server.py"
|
|
||||||
SCHEMA_FILE="schema.sql"
|
|
||||||
PRIVATEKEY_FILE='privateKey.key'
|
|
||||||
CERTIFICATE_FILE='certificate.crt'
|
|
||||||
|
|
||||||
CURRENT_USER=`logname`
|
|
||||||
RED=`tput setaf 1` # code for red console text
|
|
||||||
GREEN=`tput setaf 2` # code for green text
|
|
||||||
NC=`tput sgr0` # Reset the text color
|
|
||||||
|
|
||||||
function display_help() {
|
|
||||||
cat <<EOF
|
|
||||||
usage:
|
|
||||||
$0 -d DATABASE -c CONFIGURATION
|
|
||||||
parameters:
|
|
||||||
-d
|
|
||||||
Specify the database file that will be created and used for this server.
|
|
||||||
Example: '/tmp/ctf-practice.db'
|
|
||||||
-c
|
|
||||||
Specify the configuration file that will be used for this server.
|
|
||||||
Example: 'ctf_practice.json'
|
|
||||||
-h
|
|
||||||
Display help message
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function install_dependencies(){
|
|
||||||
|
|
||||||
echo "$0: ${GREEN}installing dependenices...${NC}"
|
|
||||||
apt-get update || panic
|
|
||||||
apt-get -y install $DEPENDENCIES || panic
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_certificate(){
|
|
||||||
|
|
||||||
echo "$0: ${GREEN}creating HTTPS certificates...${NC}"
|
|
||||||
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout $PRIVATEKEY_FILE -out $CERTIFICATE_FILE || panic
|
|
||||||
|
|
||||||
sed "0,/\$CERTIFICATE_FILE/{s/\$CERTIFICATE_FILE/$CERTIFICATE_FILE/}" $SERVER_FILE > $NEW_SERVER_FILE || panic
|
|
||||||
sed -i "0,/\$PRIVATEKEY_FILE/{s/\$PRIVATEKEY_FILE/$PRIVATEKEY_FILE/}" $NEW_SERVER_FILE || panic
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_database(){
|
|
||||||
|
|
||||||
echo "$0: ${GREEN}creating sqlite3 database...${NC}"
|
|
||||||
|
|
||||||
rm -f $DATABASE
|
|
||||||
sqlite3 $DATABASE < $SCHEMA_FILE || panic
|
|
||||||
chown $CURRENT_USER $DATABASE || panic
|
|
||||||
sed -i '0,/\$DATABASE/{s/\$DATABASE/'${DATABASE//\//\\/}'/}' $NEW_SERVER_FILE || panic
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function configure_ctf(){
|
|
||||||
|
|
||||||
echo "$0: ${GREEN}configuring CTF...${NC}"
|
|
||||||
|
|
||||||
sed -i "0,/\$CONFIGURATION/{s/\$CONFIGURATION/$CONFIGURATION/}" $NEW_SERVER_FILE || panic
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_new_server(){
|
|
||||||
|
|
||||||
cp $SERVER_FILE $NEW_SERVER_FILE
|
|
||||||
chown $CURRENT_USER $NEW_SERVER_FILE
|
|
||||||
chmod 744 $NEW_SERVER_FILE
|
|
||||||
}
|
|
||||||
|
|
||||||
function configure_firewall(){
|
|
||||||
|
|
||||||
# Allow incoming connections...
|
|
||||||
echo "$0: ${GREEN} Configuring firewall for HTTPS connections...${NC}"
|
|
||||||
ufw allow https
|
|
||||||
}
|
|
||||||
|
|
||||||
function main()
|
|
||||||
{
|
|
||||||
|
|
||||||
install_dependencies
|
|
||||||
|
|
||||||
create_new_server
|
|
||||||
|
|
||||||
create_certificate
|
|
||||||
|
|
||||||
create_database
|
|
||||||
|
|
||||||
configure_ctf
|
|
||||||
|
|
||||||
configure_firewall
|
|
||||||
|
|
||||||
echo "$0: ${GREEN} CTF server successfully setup!${NC}"
|
|
||||||
echo "$0: ${GREEN} You should now be able to run the server with the command: ${NC}"
|
|
||||||
echo '`sudo python server.py`'
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print a fatal error message and exit
|
|
||||||
# Usage:
|
|
||||||
# some_command parameter || panic
|
|
||||||
#
|
|
||||||
# This will print the panic message and exit if `some_command` fails.
|
|
||||||
function panic
|
|
||||||
{
|
|
||||||
echo "$0: ${RED}fatal error${NC}"
|
|
||||||
exit -1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Make sure the user is root (e.g. running as sudo)
|
|
||||||
if [ "$(id -u)" != "0" ]; then
|
|
||||||
echo "$0: ${RED}you must be root to configure this box.${NC}"
|
|
||||||
exit -1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse script options
|
|
||||||
while getopts d:c:h opt; do
|
|
||||||
|
|
||||||
case $opt in
|
|
||||||
d)
|
|
||||||
echo "$0: ${GREEN}using database file ${OPTARG}${NC}"
|
|
||||||
DATABASE=$OPTARG
|
|
||||||
;;
|
|
||||||
c)
|
|
||||||
echo "$0: ${GREEN}using configuration file ${OPTARG}${NC}"
|
|
||||||
CONFIGURATION=$OPTARG
|
|
||||||
;;
|
|
||||||
h)
|
|
||||||
display_help
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
\?)
|
|
||||||
exit -1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
# Make sure we entered a database name
|
|
||||||
if [ "$DATABASE" == "" ]; then
|
|
||||||
echo "$0: ${RED}you must specify a database file!${NC}"
|
|
||||||
display_help
|
|
||||||
exit -1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure we entered a configuration file
|
|
||||||
if [ "$CONFIGURATION" == "" ]; then
|
|
||||||
echo "$0: ${RED}you must specify a configuration file!${NC}"
|
|
||||||
display_help
|
|
||||||
exit -1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# This makes it so every function has a "pre-declaration" of all the functions
|
|
||||||
main "$@"
|
|
|
@ -1,115 +0,0 @@
|
||||||
$(document).ready(function(){
|
|
||||||
|
|
||||||
$('input').first().focus();
|
|
||||||
|
|
||||||
show_messages('.error');
|
|
||||||
show_messages('.message');
|
|
||||||
show_messages('.success');
|
|
||||||
|
|
||||||
$('.challenge_title').click(function(){
|
|
||||||
|
|
||||||
$(this).next().slideToggle();
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function check_answer( challenge_id ){
|
|
||||||
|
|
||||||
var given_answer = $('#'+challenge_id+' input[name="answer"]').val();
|
|
||||||
|
|
||||||
$.ajax(
|
|
||||||
{ url:"/check_answer",
|
|
||||||
method: "POST",
|
|
||||||
data: {
|
|
||||||
"challenge_id": challenge_id,
|
|
||||||
"answer": given_answer
|
|
||||||
},
|
|
||||||
dataType: "json",
|
|
||||||
|
|
||||||
success:(function(response){
|
|
||||||
|
|
||||||
if ( response['correct'] == 1){
|
|
||||||
var new_score = response['new_score'];
|
|
||||||
|
|
||||||
say_correct( new_score );
|
|
||||||
correct_challenge( challenge_id );
|
|
||||||
//$('#'+ challenge_id + ' #challenge_body').slideUp();
|
|
||||||
|
|
||||||
}
|
|
||||||
if ( response['correct'] == 0){
|
|
||||||
$.notify('Incorrect!', 'error');
|
|
||||||
// say_wrong();
|
|
||||||
}
|
|
||||||
if ( response['correct'] == -1){
|
|
||||||
$.notify('You have already submitted this flag!', 'warn');
|
|
||||||
//say_already();
|
|
||||||
}
|
|
||||||
})});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
function say_correct( new_score ){
|
|
||||||
|
|
||||||
// $('.success').text("You are correct! Nice work!");
|
|
||||||
// show_message('success');
|
|
||||||
|
|
||||||
$.notify('You are correct! Nice work!', 'success');
|
|
||||||
|
|
||||||
$('#score').text( String(new_score) );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function correct_challenge(challenge_id){
|
|
||||||
|
|
||||||
// Flash green
|
|
||||||
|
|
||||||
|
|
||||||
$("#" + challenge_id + " h3").animate({
|
|
||||||
'background-color': '#eeFFee',
|
|
||||||
'color': '#348017',
|
|
||||||
'border': '1px solid #254117;'
|
|
||||||
}, 500, function(){
|
|
||||||
|
|
||||||
$("#" + challenge_id + " h3").animate({
|
|
||||||
'background-color': '#fbfbfb',
|
|
||||||
'color': '#585858',
|
|
||||||
'border': '1px solid #eaeaea;'
|
|
||||||
}, 3000, function(){}
|
|
||||||
)});
|
|
||||||
}
|
|
||||||
|
|
||||||
function say_wrong(){
|
|
||||||
|
|
||||||
$('.error').text("Incorrect!");
|
|
||||||
show_message('error');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function say_already(){
|
|
||||||
|
|
||||||
$('.message').text("You have already submitted this flag!");
|
|
||||||
show_message('message');
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_message(name){
|
|
||||||
|
|
||||||
$('.' + name).slideDown();
|
|
||||||
|
|
||||||
window.setTimeout( hide_messages, 2000 );
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_messages(name){
|
|
||||||
|
|
||||||
if ( $(name).text() != '' ){
|
|
||||||
show_message(name.slice(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function hide_messages( ){
|
|
||||||
|
|
||||||
$('.message').slideUp();
|
|
||||||
$('.error').slideUp();
|
|
||||||
$('.success').slideUp();
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
Put any downloadable files in this directory!
|
|
||||||
|
|
||||||
<server_root>/static/downloads
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
Put any downloadable files in this directory!
|
|
||||||
|
|
||||||
<server_root>/static/downloads
|
|
|
@ -1,46 +0,0 @@
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
char secret_code[] = "b!Lr}C%R}qSQFG";
|
|
||||||
|
|
||||||
void alter_digit(char *s)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < strlen(s); ++i)
|
|
||||||
{
|
|
||||||
if (isdigit(s[i]))
|
|
||||||
{
|
|
||||||
int x = 10;
|
|
||||||
x += 4 * 3;
|
|
||||||
x -= 7;
|
|
||||||
s[i] = s[i] ^ x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rotate(char *s)
|
|
||||||
{
|
|
||||||
char aux;
|
|
||||||
int n = strlen(s);
|
|
||||||
for (int i = 0; i < n / 2; ++i)
|
|
||||||
{
|
|
||||||
aux = s[i];
|
|
||||||
s[i] = s[n - i - 1];
|
|
||||||
s[n - i - 1] = aux;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int main(int argc, char const *argv[])
|
|
||||||
{
|
|
||||||
rotate(secret_code);
|
|
||||||
for (int i = 0; i < strlen(secret_code); ++i)
|
|
||||||
{
|
|
||||||
if (i % 2 == 0)
|
|
||||||
secret_code[i] -= 2;
|
|
||||||
else
|
|
||||||
secret_code[i] += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
alter_digit(secret_code);
|
|
||||||
puts(secret_code);
|
|
||||||
return 0;
|
|
||||||
}
|
|
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 356 KiB |
Before Width: | Height: | Size: 1.1 MiB |
|
@ -1,291 +0,0 @@
|
||||||
html, body{
|
|
||||||
font-family: "Helvetica";
|
|
||||||
height: 99%;
|
|
||||||
|
|
||||||
background-color: #ededef;
|
|
||||||
color: #585858;
|
|
||||||
padding-bottom: 60px;
|
|
||||||
}
|
|
||||||
#page{
|
|
||||||
|
|
||||||
max-width: 900px;
|
|
||||||
min-height: 80%;
|
|
||||||
background-color: white;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0px 0px 20px silver;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#content{
|
|
||||||
margin-top: 80px;
|
|
||||||
padding: 0px 80px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#title{
|
|
||||||
padding-top: 20px;
|
|
||||||
padding-left: 20px;
|
|
||||||
|
|
||||||
margin: 30px;
|
|
||||||
font-size: 240%;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation{
|
|
||||||
|
|
||||||
width: 95.7%;
|
|
||||||
list-style: none;
|
|
||||||
|
|
||||||
margin: -25px 20px;
|
|
||||||
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
height: 35px;
|
|
||||||
border-bottom: 1px solid silver;
|
|
||||||
vertical-align: middle;
|
|
||||||
/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#feccb1+0,ea5507+79,f17432+92,fb955e+100 */
|
|
||||||
background: #feccb1; /* Old browsers */
|
|
||||||
background: -moz-linear-gradient(top, #feccb1 0%, #ea5507 79%, #f17432 92%, #fb955e 100%); /* FF3.6-15 */
|
|
||||||
background: -webkit-linear-gradient(top, #feccb1 0%,#ea5507 79%,#f17432 92%,#fb955e 100%); /* Chrome10-25,Safari5.1-6 */
|
|
||||||
background: linear-gradient(to bottom, #feccb1 0%,#ea5507 79%,#f17432 92%,#fb955e 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#feccb1', endColorstr='#fb955e',GradientType=0 ); /* IE6-9 */
|
|
||||||
border-bottom: 2px solid #eaeaea;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation li{
|
|
||||||
min-width: 100px;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 6px;
|
|
||||||
|
|
||||||
}
|
|
||||||
.navigation li:hover{
|
|
||||||
text-shadow: 0px 0px 10px black;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre{
|
|
||||||
|
|
||||||
border: 1px solid #bebebe;
|
|
||||||
font-size: 83%;
|
|
||||||
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
text-indent: 0px;
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre-line;
|
|
||||||
padding: 10px;
|
|
||||||
vertical-align: middle !important;
|
|
||||||
background-color: #fafafa;
|
|
||||||
/*overflow-x: scroll;*/
|
|
||||||
color: darkblue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation a{
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
text-shadow: 0px 0px 5px black;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 20px;
|
|
||||||
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
#challenges{
|
|
||||||
|
|
||||||
border: 1px solid #eaeafa;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 20px;
|
|
||||||
|
|
||||||
width: 700px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
box-shadow: 0px 0px 30px #eaeaea;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#challenges input{
|
|
||||||
|
|
||||||
border: 1px solid #eaeafa;
|
|
||||||
border-radius: 5px;
|
|
||||||
|
|
||||||
|
|
||||||
box-shadow: 0px 0px 30px #eaeaea;
|
|
||||||
}
|
|
||||||
|
|
||||||
#scoreboard{
|
|
||||||
|
|
||||||
border: 1px solid #eaeafa;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 20px;
|
|
||||||
|
|
||||||
width: 700px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
box-shadow: 0px 0px 30px #eaeaea;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
input{
|
|
||||||
border: 1px solid silver;
|
|
||||||
border-radius: 3px;
|
|
||||||
/*font-size: 20px;*/
|
|
||||||
|
|
||||||
width: 95%;
|
|
||||||
|
|
||||||
padding: 3px;
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#login_form{
|
|
||||||
|
|
||||||
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
border: 1px solid #eaeafa;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 30px 150px;
|
|
||||||
|
|
||||||
width: 300px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
box-shadow: 0px 0px 30px #eaeaea;
|
|
||||||
}
|
|
||||||
|
|
||||||
#register_form{
|
|
||||||
|
|
||||||
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
border: 1px solid #eaeafa;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 30px 150px;
|
|
||||||
|
|
||||||
width: 300px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
box-shadow: 0px 0px 30px #eaeaea;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.challenge{
|
|
||||||
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom:10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message{
|
|
||||||
padding: 8px;
|
|
||||||
position: absolute;
|
|
||||||
top:154px;
|
|
||||||
background-color: #FFF8DC;
|
|
||||||
border: 1px solid #EAC117;
|
|
||||||
color: #966F33;
|
|
||||||
width: 883px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.success{
|
|
||||||
padding: 8px;
|
|
||||||
position: absolute;
|
|
||||||
top:154px;
|
|
||||||
background-color: #eeFFee;
|
|
||||||
border: 1px solid #254117;
|
|
||||||
color: #348017;
|
|
||||||
width: 883px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error{
|
|
||||||
|
|
||||||
padding: 8px;
|
|
||||||
position: absolute;
|
|
||||||
top:154px;
|
|
||||||
width: 883px;
|
|
||||||
background-color: #FFeeee;
|
|
||||||
border: 1px solid #9F000F;
|
|
||||||
|
|
||||||
color: #C11B17;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.challenge_title{
|
|
||||||
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
padding: 5px;
|
|
||||||
margin:-11px;
|
|
||||||
|
|
||||||
background-color: #fbfbfb;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.challenge form{
|
|
||||||
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.challenge li{
|
|
||||||
list-style: none;
|
|
||||||
float: left;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
padding-left: 20px;
|
|
||||||
margin-top: -5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.challenge_title span{
|
|
||||||
|
|
||||||
|
|
||||||
float: right;
|
|
||||||
vertical-align: middle;
|
|
||||||
opacity:.5;
|
|
||||||
margin-right: 5px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.status{
|
|
||||||
|
|
||||||
padding: 8px;
|
|
||||||
position: absolute;
|
|
||||||
top:154px;
|
|
||||||
width: 883px;
|
|
||||||
text-align: right;
|
|
||||||
opacity: .5;
|
|
||||||
z-index: 5;
|
|
||||||
font-size: smaller;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
text-indent: 20px;
|
|
||||||
line-height: 140%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content a{
|
|
||||||
color: #56A5EC;
|
|
||||||
}
|
|
||||||
#content a:visited{
|
|
||||||
color: #56A5EC;
|
|
||||||
}
|
|
||||||
|
|
||||||
th{
|
|
||||||
|
|
||||||
text-align: left;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
ps aux|grep "server.py"|cut -d" " -f6| while read line; do sudo kill -9 $line; done
|
|
||||||
ps aux|grep "server.py"|cut -d" " -f7| while read line; do sudo kill -9 $line; done
|
|
|
@ -1,10 +0,0 @@
|
||||||
{% extends "base_page.html" %}
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<h2> About </h2>
|
|
||||||
|
|
||||||
{% if app_about %}
|
|
||||||
{{ app_about | safe }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
|
@ -1,53 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title> {{ app_title }} </title>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='stylesheet.css')}}">
|
|
||||||
<script src="{{ url_for('static', filename='jquery.js' ) }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='notify.js' ) }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='jquery-ui.min.js' ) }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='control.js' ) }}"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="page">
|
|
||||||
<h1 id="title"> {{ app_title }} </h1>
|
|
||||||
|
|
||||||
<ul class="navigation">
|
|
||||||
{% if session.logged_in %}
|
|
||||||
{% for name, url in app_navigation_logged_in.iteritems() %}
|
|
||||||
<a href="{{ url }}"> <li> {{ name }} </li> </a>
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
{% for name, url in app_navigation_logged_out.iteritems() %}
|
|
||||||
<a href="{{ url }}"> <li> {{ name }} </li> </a>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{% if session.logged_in %}
|
|
||||||
<div class="status">
|
|
||||||
{{ session.username }} <strong>|</strong> <span id="score">{{ session.score }} pts </span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="success">{% if success %}{{ success }}{% endif %}</div>
|
|
||||||
<div class="error">{% if error %}{{ error }}{% endif %}</div>
|
|
||||||
<div class="message">{% if message %}{{ message }}{% endif %}</div>
|
|
||||||
|
|
||||||
|
|
||||||
{% for message in get_flashed_messages() %}
|
|
||||||
<div class="success"> {{ message }} </div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<div id="content">
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,39 +0,0 @@
|
||||||
{% extends "base_page.html" %}
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<h2> Services </h2>
|
|
||||||
|
|
||||||
<div id="challenges">
|
|
||||||
<div class="challenge" id="0">
|
|
||||||
<h3 class="challenge_title"> Submit a Flag</h3>
|
|
||||||
|
|
||||||
<form action="{{ url_for('challenges_page') }}" id="challenge_body" method="post">
|
|
||||||
{% if challenges %}
|
|
||||||
|
|
||||||
<h4> The running services are... </h4>
|
|
||||||
|
|
||||||
{% for challenge in challenges %}
|
|
||||||
|
|
||||||
<p style=' text-indent:0px; margin-left:30px;padding-bottom:10px;'>
|
|
||||||
<span style='font-weight: bold;'> {{ challenge.title }}</span> ( {{ challenge.points }} pts ):
|
|
||||||
|
|
||||||
{{ challenge.description | safe }}
|
|
||||||
<b>Connect on port {{ challenge.port }}. </b>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h4> Submit by the command-line via... </h4>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
curl -k "{{ url }}submit" --data "uuid={{session_value}}&flag=<FLAG>"
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<input type="hidden" name="challenge_id" value="0">
|
|
||||||
<input type="text" name="answer">
|
|
||||||
<input type="submit" value="Submit" onclick="return check_answer(0)">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
|
@ -1,20 +0,0 @@
|
||||||
{% extends "base_page.html" %}
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<h2> Login </h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Please log in with a registered username.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong> Note that the username field is case-sensitive.</strong>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<form id="login_form" action="{{ url_for('login') }}" method="post">
|
|
||||||
<strong>Username:</strong> <input type="text" name="username">
|
|
||||||
<strong>Password:</strong> <input type="password" name="password">
|
|
||||||
<input type="submit" value="Login">
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
|
@ -1,21 +0,0 @@
|
||||||
{% extends "base_page.html" %}
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<h2> Register </h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Please register the username and password you would like to log in with.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong> Do not use a password you use for other webites.</strong> Your password is stored in the database as a <a href="https://en.wikipedia.org/wiki/SHA-2">SHA256 hash</a>, and it is still passed to the server over a secure <a href="https://en.wikipedia.org/wiki/HTTPS">HTTPS</a> connection, but the next line of defense is for you, the user, to never use synchronized passwords.
|
|
||||||
</p>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<form id="register_form" action="{{ url_for('register') }}" method="post">
|
|
||||||
<strong>Username:</strong> <input type="text" name="username">
|
|
||||||
<strong>Password:</strong> <input type="password" name="password">
|
|
||||||
<strong>Confirm Password:</strong> <input type="password" name="confirm">
|
|
||||||
<input type="submit" value="Register">
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
|
@ -1,37 +0,0 @@
|
||||||
{% extends "base_page.html" %}
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<h2> The Scoreboard </h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
How do you stack up against the other players?
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<table id="scoreboard">
|
|
||||||
<tr>
|
|
||||||
<th> Place </th>
|
|
||||||
<th> Name </th>
|
|
||||||
<th> Score </th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<!-- {% for username in usernames %}
|
|
||||||
<tr>
|
|
||||||
<td> {{ loop.index }} </td>
|
|
||||||
<td> {{ username }} </td>
|
|
||||||
<td> {{ scores[ loop.index0 ] }} </td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %} -->
|
|
||||||
|
|
||||||
{% for user in users %}
|
|
||||||
<tr>
|
|
||||||
<td> {{ loop.index }} </td>
|
|
||||||
<td> {{ user["username"] }} </td>
|
|
||||||
<td> {{ user[ "score" ] }} </td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
{% endblock %}
|
|
|
@ -1,107 +0,0 @@
|
||||||
html, body{
|
|
||||||
font-family: "Helvetica";
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
background-color: #ededef;
|
|
||||||
color: #585858;
|
|
||||||
}
|
|
||||||
#page{
|
|
||||||
|
|
||||||
max-width: 900px;
|
|
||||||
min-height: 80%;
|
|
||||||
background-color: white;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0px 0px 20px silver;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
h1{
|
|
||||||
padding: 20px;
|
|
||||||
|
|
||||||
margin: 30px;
|
|
||||||
font-size: 240%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation{
|
|
||||||
|
|
||||||
width: 95.7%;
|
|
||||||
list-style: none;
|
|
||||||
|
|
||||||
margin: -25px 20px;
|
|
||||||
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
height: 35px;
|
|
||||||
border-bottom: 1px solid silver;
|
|
||||||
vertical-align: middle;
|
|
||||||
background: #1e5799;
|
|
||||||
background: -moz-linear-gradient(top, #1e5799 0%, #207cca 47%, #2989d8 84%, #7db9e8 100%);
|
|
||||||
background: -webkit-linear-gradient(top, #1e5799 0%,#207cca 47%,#2989d8 84%,#7db9e8 100%);
|
|
||||||
background: linear-gradient(to bottom, #1e5799 0%,#207cca 47%,#2989d8 84%,#7db9e8 100%);
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#7db9e8',GradientType=0 );
|
|
||||||
border-bottom: 2px solid #eaeaea;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation li{
|
|
||||||
min-width: 100px;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 6px;
|
|
||||||
|
|
||||||
}
|
|
||||||
.navigation li:hover{
|
|
||||||
text-shadow: 0px 0px 10px black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation a{
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
text-shadow: 0px 0px 5px black;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 20px;
|
|
||||||
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
#challenges{
|
|
||||||
|
|
||||||
border: 1px solid #eaeafa;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 20px;
|
|
||||||
margin-top: 50px;
|
|
||||||
width: 700px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
box-shadow: 0px 0px 30px #eaeaea;
|
|
||||||
}
|
|
||||||
input{
|
|
||||||
border: 1px solid silver;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 20px;
|
|
||||||
width: 95%;
|
|
||||||
padding: 0px 0px;
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.challenge{
|
|
||||||
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom:10px;
|
|
||||||
}
|
|
||||||
.challenge h2{
|
|
||||||
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
padding: 5px;
|
|
||||||
margin:-11px;
|
|
||||||
|
|
||||||
background-color: #fbfbfb;
|
|
||||||
margin-bottom: 30px
|
|
||||||
|
|
||||||
}
|
|
BIN
database.db
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
apt-get -y update && apt-get -y install pip sqlite3
|
||||||
|
pip install passlib flask colorama image python-resize-image
|
|
@ -1,28 +1,28 @@
|
||||||
-----BEGIN PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDmlaxfGoZDNn3y
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC4FWxCUkvF10cS
|
||||||
7Et02k5hYMRaT92p4knBO7WhTOSFSRkNuBN/E7Osuc5J548EzMYg9AoT+XiN6xfn
|
g5QnT2NNFTHYRfJT/KU4rQYQKIOAkXhODqVjpOtHNHkY+2N8GuqECkqUVUXtu2hy
|
||||||
wkrr3rntiGrO+J73/iLkD6/JDdXsFCcIj3ZhhM8eW08cu8on0WRHS96zyji8tFQU
|
H4CN1qmhmF4+qCGfs4UvNDF1rmbTlT1CNlOs5wh8i02acy8A4SVLquybiEWKIbKn
|
||||||
3ADPzNLimJQSEwIxttkRhHHf5xIffG7xFBhzDN3DRO+AdS7yVT+cus5H6n6i9+H9
|
BCPileFTRG0ZvesVVTOOPBpI2D1xh4kdriBBwx0+J/NM0L0we1MGgqDzjEc9AZ/e
|
||||||
mWuIwZC1JTUXUIGT/DIwRKPQQsnHrUDeibMivusxeJB8Oy9+X4ZwH6q37N+5hI8l
|
wZrhUlKkFWfk3ezU3z1brqDfi1YgzQfboZaXFN7yOzG2tdO4EysGs97DuVno84Ll
|
||||||
cBehjVHqiMAmNcLYsFHXPQLrLvFLujfscIVQE1Zq8ep3UTNmo1/ozBrVdhaYn9qm
|
ZCF/7ZwYgIORP4jVWOkUhtv6yj0uoqrkwQSw7LvoCf6mU2n9zR+xIwPs68xuuTXb
|
||||||
mq3VusrfAgMBAAECggEBALMroiDUD3eyo/NawNcvuq/X7TrvzCHxf7Xym5OWmAsp
|
fLdmSfn5AgMBAAECggEASK9EyMcf3iVLjdbgZ8kj52rH/KJZtanbPw6qhzTH/7rw
|
||||||
XZpXam7X9ElGp5CtqWflZh69Age7VX2RK6YeRvE4w+halAP3FC9G/f2QYtsrMQqc
|
qrmDul2C/OGOMzwHoxgpoytBGWK2MtE9w1oG83pgDktQYyMV664Bl4rfQJ01QrP5
|
||||||
LihssWPdOsMv2C1Pjimafv0XaxjxDV00EhGTUd4mHceNH6Fbu9y9Y7ZE3+dHOcHU
|
tSwoS+wJYMvMP4DdfVZo2IDL3fmno4v8s4+h77TIfI1XGsPvj8PNkIrQwhSH5kw2
|
||||||
CO0QRIUkcJfzndM+X/EeXSRuP6G0+pXdQ+tSKDeH1rNFgTFs17RTmt/36d2JW/O/
|
x03/s1X0tYgy7LxMgFH2IkDRIGIhxpfEiSKHssGfGp732Wl6HxiBQ0mvni27OgJg
|
||||||
GFLpOfoOtVJ7V8ouaE8B/3wbFbEolv85AoMDBh1Q+v3PSKhUGvbHBDf6SRwyxVQv
|
du7QHQIH1I9mRKBS0pvzR2BYqdvDYiacJifewxe2/WnYGvfCQmam6MXvtupncCLg
|
||||||
aOExMY2Mgdw4R1tAUckKgKktYrUVKjlh4OJ7+Yyy/0ECgYEA+rD2UXoWnqxFEWPr
|
7jM6P5QgX3cQ0g4STpO752ZHHGTHenRFzu+7B0lBAQKBgQDttTpqed5nv3IR8cNm
|
||||||
J7btiyS6QBIsW9pO3bPkX+lZ6XhCMHlI2lD6dkVwCRUTxP8yPsgiyNkCE9936sCX
|
7Xyk9+8XP4nReFaDUFOBJxR89e2X+hh4TKFa8MZUMOJjabs06xLRXs76MnRCDHWA
|
||||||
kK3CFBURvJQryoOrdOtCz+fFbtgifmNKQbKLxVLEm/FVJpqRReN6CV4UEdxZnnpV
|
ZXlvicWBQQxl6eCsDiVvRH+I7oioLo8MAyXwUt8dvBHJQA8cWAaLlql3WfAS4GzT
|
||||||
Tkg1h1xw2IB2YedKYXOw3jPDlGkCgYEA63e1xMYK6L4PGdGsswAiUdKxsKflH+Tf
|
S+C7tAs1n5qAppKNsy1ySDeBGQKBgQDGP9BeEQuZBKl4UqQQTW/uEnb5IqtuHSK+
|
||||||
gGTc+6Xrc92IIDD4yZ8Bk8NS1fFwpR82endlqfwn8QhxUsxbuGfg/5Yj3AVRmeLw
|
66aXRrLUhTpHFXdQu9ti+oYh90BBwKPZZY8WJV28t2U+taHYhaaBWpETBjzfmRPJ
|
||||||
7BQQUYRMCa+iuwRZTMWxZKXHACEQDoC3EPVtWeh5uxzKbd+MAbTHMvUM9STCaz55
|
NeuYoSoW86C5fn1tg94Y00GfjHLDbSdTxl+DRkNOzufZlCZvKAZskIQZV+Trgtz7
|
||||||
ZU9SeaAsXAcCgYAC5z/DC83tQoN+QxD7IcQ4g1Fg4pT+71VQff/cGIDBEnJ5yz3L
|
Pw7giR774QKBgFtKO2oC7bAobRWJJMMVt8XfVho2k6Y3sfnyUm+KY6ruA9ZW/SjO
|
||||||
wXpVGlLE2CildGspjPnSJ6k9f64M2vQmaczAnMnazECBlOrMbNkWPVHtCbXEjvPS
|
PTWgvHo+3+LQC05ybSKtZ43c7JslD8dEsVNttMVEBw/otxk8wZGu28/p09/LKbKy
|
||||||
NPYnb+D1CWN6EfoyvAKyzxMebdXf3vzT7kQocCqiZ0J3uc0DuepHeIQAWQKBgQC2
|
TtKx8PAJd0cz69m10KWxMdodVz7Yo9KuFFvh9GAesIZx8lyrEGwQYgiZAoGAee23
|
||||||
fJ1DthRoUjvTz7sfMwBmF3scpNIfCLrqf8D/ypQSxOKlyC5X28JWKS9+nVKmtez7
|
hpMvMd5nKISTOR+XTrH2kEWdb+zleMzQOcwWopSKAjwWlQXk6VwxcORzlb0YSNWo
|
||||||
tqL0vXabB+cDu1tuLBulGVALSZf3QnljDR2kf3qKmzLr66/lnuUfUpdKk1UlWD4I
|
ijNTEoUs9MObFeMlQ/tirHOyrsakH6VVEBtXGqSeXleIZvmqeFQ90RX9Y2pXvLON
|
||||||
h5zK7C/Dgsmjo3eXLuqepGn5ZxbCFLXyfSo3FpqqawKBgBg7W25kn/bd/aJp3yAY
|
/NwS+35PpEb02HqicNT1Ge0v8xUaOkBPMxPChaECgYBouXMmAGjSY91JYtNOtFnl
|
||||||
gcRgpQksIKg/3l/PrWY0hCAn+a49JgRQWNIFUcWViW93lvrSjdchsZovkGIfMQp4
|
V1sRLNnCzYfqMmI8Pve1M2waTpCiVi+FLUvd4x4CrmcblMjBJcigM63Ve0ONsbPH
|
||||||
uuynpeQWWVGREI887XdXACI+AkQQProQme2Xh+h4CGy+4o0Q85SxYsFFUeM2oDfg
|
MEIIK8SRmTVOVUA9hqgUySnQaBjCggPBrXldgndNWMHnYKldXqxSQj0pNsVrc6tC
|
||||||
c9e+nPQ/tMMD85mSV69KEhEQ
|
ROgtL6cYIaFSYsPgVIP60w==
|
||||||
-----END PRIVATE KEY-----
|
-----END PRIVATE KEY-----
|
||||||
|
|
673
server.py
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask import render_template, request, session, g, url_for, flash, get_flashed_messages, redirect
|
from flask import render_template, request, session, g, url_for, flash, get_flashed_messages, redirect, send_from_directory
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import json
|
import json
|
||||||
import sys, os
|
import sys, os
|
||||||
|
@ -9,17 +9,50 @@ from colorama import *
|
||||||
import sys
|
import sys
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
from werkzeug.utils import secure_filename
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
from textwrap import dedent
|
||||||
|
from PIL import Image # needed to resize the image they upload
|
||||||
|
import re # Used to verify phone numbers
|
||||||
|
from resizeimage import resizeimage
|
||||||
|
|
||||||
|
# Import smtplib for the actual sending function
|
||||||
|
import smtplib
|
||||||
|
|
||||||
|
# Import the email modules we'll need
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
|
||||||
from passlib.hash import sha256_crypt
|
from passlib.hash import sha256_crypt
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
|
|
||||||
|
|
||||||
|
CERTIFICATE = 'certificate.crt'
|
||||||
|
PRIVATE_KEY = 'privateKey.key'
|
||||||
|
|
||||||
|
|
||||||
|
bad_word_found = ""
|
||||||
|
|
||||||
|
f = open("badwords.txt")
|
||||||
|
bad_words = f.read().split('\n')
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
def contains_bad_word( string ):
|
||||||
|
global bad_word_found
|
||||||
|
|
||||||
|
words = string.split(" ")
|
||||||
|
for word in words:
|
||||||
|
if word in bad_words:
|
||||||
|
bad_word_found = word
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
price_cap = 10000
|
||||||
|
|
||||||
debug = True
|
debug = True
|
||||||
|
|
||||||
init( autoreset = True )
|
init( autoreset = True )
|
||||||
|
email_from = 'ObjeeTrade'
|
||||||
|
|
||||||
if (debug):
|
if (debug):
|
||||||
|
|
||||||
|
@ -37,19 +70,36 @@ else:
|
||||||
def error( string ): pass
|
def error( string ): pass
|
||||||
def warning( string ): pass
|
def warning( string ): pass
|
||||||
|
|
||||||
|
def allowed_file(filename):
|
||||||
|
return '.' in filename and \
|
||||||
|
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
|
||||||
|
|
||||||
|
def send_email( to_address, subject, message ):
|
||||||
|
|
||||||
|
msg = MIMEText(message, 'html')
|
||||||
|
msg["Subject"] = subject
|
||||||
|
msg['From'] = email_from
|
||||||
|
msg['To'] = to_address
|
||||||
|
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
|
||||||
|
server.ehlo()
|
||||||
|
server.login('objeetrade@gmail.com', 'Go Coast Guard')
|
||||||
|
server.sendmail(email_from, [to_address], msg.as_string())
|
||||||
|
server.quit()
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
|
||||||
DATABASE = '/tmp/bears.db'
|
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
|
||||||
CERTIFICATE = 'certificate.crt'
|
DATABASE = 'database.db'
|
||||||
|
UPLOAD_FOLDER = 'uploads'
|
||||||
PRIVATE_KEY = 'privateKey.key'
|
PRIVATE_KEY = 'privateKey.key'
|
||||||
|
|
||||||
SECRET_KEY = 'this_key_needs_to_be_used_for_session_variables'
|
SECRET_KEY = 'this_key_needs_to_be_used_for_session_variables'
|
||||||
|
|
||||||
if DATABASE == '$DATABASE':
|
# if DATABASE == '/tmp/bearshop_database.db':
|
||||||
error("This server has not yet been configured with a database file!")
|
# error("This server has not yet been configured with a database file!")
|
||||||
exit(-1)
|
# exit(-1)
|
||||||
|
|
||||||
if CERTIFICATE == '$CERTIFICATE_FILE':
|
if CERTIFICATE == '$CERTIFICATE':
|
||||||
error("This server has not yet been configured with a certificate!")
|
error("This server has not yet been configured with a certificate!")
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
|
@ -61,6 +111,10 @@ app = Flask( __name__ )
|
||||||
|
|
||||||
app.config.from_object(__name__)
|
app.config.from_object(__name__)
|
||||||
|
|
||||||
|
@app.route('/uploads/<filename>')
|
||||||
|
def uploaded_file(filename):
|
||||||
|
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
|
||||||
|
|
||||||
def init_db():
|
def init_db():
|
||||||
with closing(connect_db()) as db:
|
with closing(connect_db()) as db:
|
||||||
with app.open_resource('schema.sql', mode='r') as f:
|
with app.open_resource('schema.sql', mode='r') as f:
|
||||||
|
@ -70,6 +124,7 @@ def init_db():
|
||||||
def connect_db():
|
def connect_db():
|
||||||
return sqlite3.connect( app.config['DATABASE'] )
|
return sqlite3.connect( app.config['DATABASE'] )
|
||||||
|
|
||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def before_request():
|
def before_request():
|
||||||
g.db = connect_db()
|
g.db = connect_db()
|
||||||
|
@ -85,200 +140,550 @@ def teardown_request(exception):
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
|
|
||||||
if not ( session['logged_in'] ):
|
if not 'logged_in' in session: return redirect('login')
|
||||||
return redirect('login')
|
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified = cur.fetchone()[0]
|
||||||
|
if not verified:
|
||||||
|
return redirect('verify')
|
||||||
|
return redirect('products')
|
||||||
|
|
||||||
@app.route("/login", methods=["GET", "POST"])
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
def login():
|
def login():
|
||||||
|
|
||||||
error = ""
|
email = password = ""
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
|
||||||
cur = g.db.execute('select email, password from users')
|
cur = g.db.execute('select email, password, uuid from users')
|
||||||
# username, password_hash
|
users = dict(( row[0].lower(), row[1] ) for row in cur.fetchall())
|
||||||
users = dict(( row[0], row[1] ) for row in cur.fetchall())
|
|
||||||
|
|
||||||
print "You POSTed", users
|
email = request.form['email'].lower()
|
||||||
|
password = request.form['password']
|
||||||
|
|
||||||
if not request.form['email'] in users.iterkeys():
|
if ( email == "" ):
|
||||||
|
flash("You need to enter an e-mail address!")
|
||||||
|
elif not email.endswith("uscga.edu"):
|
||||||
|
flash("This does not look like a valid USCGA EDU e-mail address!")
|
||||||
|
elif not email in users.iterkeys():
|
||||||
flash('This e-mail is not in the database!')
|
flash('This e-mail is not in the database!')
|
||||||
else:
|
else:
|
||||||
|
if ( password == "" ):
|
||||||
if not ( sha256_crypt.verify( request.form['password'], users[request.form['username']] ) ):
|
flash("You need to enter a password!")
|
||||||
|
elif not ( sha256_crypt.verify( request.form['password'], users[email] ) ):
|
||||||
flash("Incorrect password!")
|
flash("Incorrect password!")
|
||||||
else:
|
else:
|
||||||
|
|
||||||
session_login( request.form['email'] )
|
session_login( request.form['email'] )
|
||||||
|
return redirect( "verify" )
|
||||||
|
|
||||||
return redirect( "about" )
|
return render_template( 'login.html', email=email, password = password )
|
||||||
|
|
||||||
return render_template( 'login.html' )
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/register", methods=["GET", "POST"])
|
@app.route("/register", methods=["GET", "POST"])
|
||||||
def register():
|
def register():
|
||||||
|
|
||||||
cur = g.db.execute('select email from users')
|
cur = g.db.execute('select email from users')
|
||||||
|
usernames = [row[0].lower() for row in cur.fetchall() ]
|
||||||
|
|
||||||
usernames = [row[0] for row in cur.fetchall() ]
|
email = password = confirm = ""
|
||||||
|
|
||||||
error = ""
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
email = request.form['email'].lower()
|
||||||
|
password = request.form['password']
|
||||||
|
confirm = request.form['confirm']
|
||||||
if unicode(request.form['email']) in usernames:
|
if unicode(request.form['email']) in usernames:
|
||||||
flash('This e-mail is already registered!')
|
flash('This e-mail is already registered!')
|
||||||
|
elif (not request.form['email'].endswith('@uscga.edu')):
|
||||||
|
flash('You must use an "@uscga.edu" domain e-mail!')
|
||||||
elif (request.form['password'] == ""):
|
elif (request.form['password'] == ""):
|
||||||
flash("You must supply a password!")
|
flash("You must supply a password!")
|
||||||
elif request.form['password'] != request.form['confirm']:
|
elif request.form['password'] != request.form['confirm']:
|
||||||
flash('Your passwords do not match!')
|
flash('Your passwords do not match!')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# I use this for command-line submission...
|
# I use this for command-line submission...
|
||||||
identifier = str(uuid4())
|
identifier = str(uuid4())
|
||||||
|
|
||||||
cur = g.db.execute('insert into users (email, password, uuid) values ( ?, ?, ? )', [
|
cur = g.db.execute('insert into users (email, name, password, uuid, your_products, room, phone, verified) values ( ?, ?, ?, ?, ?, ?, ?, ? )', [
|
||||||
request.form['email'],
|
email,
|
||||||
|
" ".join( [email.split(".")[0].title(), email.split(".")[2].split("@")[0].title() ]),
|
||||||
sha256_crypt.encrypt( request.form['password']),
|
sha256_crypt.encrypt( request.form['password']),
|
||||||
identifier # and a completely unique idenitifier
|
identifier, # a completely unique idenitifier
|
||||||
|
"", # They currently have no products being sold
|
||||||
|
"", # They can enter their room number later
|
||||||
|
"", # They can enter their phone number later
|
||||||
|
0 # verified? ...since they just registered, no!
|
||||||
] )
|
] )
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
|
||||||
flash("Hello " + request.form['username'] + ", you have successfully registered!")
|
|
||||||
session_login( request.form['email'] )
|
session_login( request.form['email'] )
|
||||||
return redirect( "challenges" )
|
send_verification_link()
|
||||||
|
return redirect( "verify" )
|
||||||
|
|
||||||
return render_template( 'register.html', error = error )
|
return render_template( 'register.html', email = email, password = password, confirm = confirm )
|
||||||
|
|
||||||
|
|
||||||
# @app.route("/scoreboard")
|
@app.route("/send_verification_link")
|
||||||
# def scoreboard():
|
def send_verification_link():
|
||||||
|
|
||||||
# cur = g.db.execute('select username, score from users order by score desc, last_submission asc')
|
if not 'logged_in' in session: return redirect('login')
|
||||||
# response = cur.fetchall()
|
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified = cur.fetchone()[0]
|
||||||
|
|
||||||
# users = [ { "username": row[0], "score": row[1] } for row in response]
|
if ( session['logged_in'] ):
|
||||||
|
|
||||||
# return render("scoreboard.html", users = users )
|
email = session['email']
|
||||||
|
name = session['name']
|
||||||
|
cur = g.db.execute('select uuid, verified from users where email = (?)', [email])
|
||||||
|
|
||||||
# @app.route("/logout")
|
identifier, verified = cur.fetchone()
|
||||||
# def logout():
|
if ( verified == 1 ):
|
||||||
|
flash("Your e-mail address has already been verified.")
|
||||||
|
return redirect('products')
|
||||||
|
else:
|
||||||
|
|
||||||
# session_logout()
|
send_email( email,
|
||||||
# return redirect("about")
|
'Your Registration Verification Code',
|
||||||
|
render_template("verification_email.html", identifier = identifier, name = name
|
||||||
|
))
|
||||||
|
|
||||||
# @app.route("/")
|
# THIS IS ONLY FOR TESTING....
|
||||||
# @app.route("/about")
|
send_email( 'johnhammond010@gmail.com',
|
||||||
# def about(): return render("about.html", app_about=configuration['app_about'])
|
'Your Registration Verification Code',
|
||||||
|
render_template("verification_email.html", identifier = identifier, name = name
|
||||||
|
))
|
||||||
|
|
||||||
# @app.route("/challenges")
|
flash("An e-mail has been sent!")
|
||||||
# def challenges_page():
|
return redirect("verify")
|
||||||
|
|
||||||
# if not ( session['logged_in'] ):
|
|
||||||
# return render("login.html", error = "You must log in to be able to see the challenges!")
|
|
||||||
# try:
|
|
||||||
# cur = g.db.execute('select uuid from users where username =?',
|
|
||||||
# [ session['username'],] )
|
|
||||||
|
|
||||||
# uuid = cur.fetchone()[0]
|
|
||||||
# except Exception as e:
|
|
||||||
# print error(e.message)
|
|
||||||
# uuid = ''
|
|
||||||
|
|
||||||
# return render("challenges.html", challenges = configuration['services'], url=request.url_root, session_value = uuid )
|
|
||||||
|
|
||||||
# @app.route("/check_answer", methods=["GET", "POST"])
|
|
||||||
# def check_answer():
|
|
||||||
|
|
||||||
# global correct_answers
|
|
||||||
|
|
||||||
# if request.method == "POST":
|
|
||||||
# if request.form['answer'] in session['solved_challenges']:
|
|
||||||
|
|
||||||
# return json.dumps({'correct': -1});
|
|
||||||
|
|
||||||
# if ( request.form['answer'] in correct_answers.keys() ):
|
|
||||||
|
|
||||||
# flag = request.form['answer']
|
|
||||||
|
|
||||||
# new_score = int(session['score']) + correct_answers[flag]
|
|
||||||
# cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')) where username = (?)", [
|
|
||||||
# new_score,
|
|
||||||
# session['username']
|
|
||||||
# ] );
|
|
||||||
|
|
||||||
# session['solved_challenges'].append( request.form['answer'] )
|
|
||||||
# session['score'] = new_score
|
|
||||||
# g.db.commit();
|
|
||||||
|
|
||||||
# return json.dumps({'correct': 1, 'new_score': new_score});
|
|
||||||
# else:
|
|
||||||
# return json.dumps({'correct': 0});
|
|
||||||
|
|
||||||
# @app.route("/submit", methods=[ "POST" ])
|
|
||||||
# def submit():
|
|
||||||
|
|
||||||
# global correct_answers
|
|
||||||
|
|
||||||
# if request.method == "POST":
|
|
||||||
|
|
||||||
# if ( request.form['flag'] in correct_answers.keys() ):
|
|
||||||
|
|
||||||
# flag = request.form['flag']
|
|
||||||
|
|
||||||
# cur = g.db.execute('select score, solved_challenges from users where uuid = (?)',
|
|
||||||
# [ request.form['uuid'], ])
|
|
||||||
|
|
||||||
|
|
||||||
# current_score, solved_challenges = cur.fetchone()
|
@app.route("/products")
|
||||||
|
def products():
|
||||||
|
|
||||||
# solved_challenges = solved_challenges.split()
|
if not 'logged_in' in session: return redirect('login')
|
||||||
|
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified = cur.fetchone()[0]
|
||||||
|
if not verified:
|
||||||
|
return redirect('verify')
|
||||||
|
cur = g.db.execute('select name, picture, price, uuid from products')
|
||||||
|
products = [ [ row[0], row[1], row[2], row[3] ] for row in cur.fetchall()[::-1]]
|
||||||
|
|
||||||
# if ( flag in solved_challenges ):
|
return render_template("products.html", products = products)
|
||||||
# return 'You already submitted this flag!\n'
|
|
||||||
|
|
||||||
# print solved_challenges
|
@app.route("/products/<uuid>")
|
||||||
|
def product(uuid):
|
||||||
|
|
||||||
# new_score = current_score + correct_answers[flag]
|
if not 'logged_in' in session: return redirect('login')
|
||||||
# solved_challenges.append( flag + " " )
|
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
|
||||||
# cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')), solved_challenges = (?) where uuid = (?)", [
|
verified = cur.fetchone()[0]
|
||||||
# new_score,
|
if not verified:
|
||||||
# ' '.join(solved_challenges),
|
return redirect('verify')
|
||||||
# request.form['uuid']
|
|
||||||
# ] );
|
|
||||||
|
|
||||||
# # session['solved_challenges'].append( request.form['flag'] )
|
cur = g.db.execute('select name, price, picture, description, seller, interested_people from products where uuid = (?)', [uuid] )
|
||||||
# session['score'] = new_score
|
name, price, picture, description, seller, interested_people = cur.fetchone()
|
||||||
# g.db.commit();
|
|
||||||
|
|
||||||
# # return json.dumps({'correct': 1, 'new_score': new_score});
|
cur = g.db.execute('select uuid from users where name = (?)', [seller] )
|
||||||
# return 'Correct!\n';
|
seller_uuid = cur.fetchone()[0]
|
||||||
# else:
|
|
||||||
# # return json.dumps({'correct': 0});
|
|
||||||
# return 'Incorrect!\n';
|
|
||||||
|
|
||||||
def session_login( username ):
|
|
||||||
|
|
||||||
flash("You were successfully logged in!")
|
interested_people = [ person for person in interested_people.split('\n') if person ]
|
||||||
|
|
||||||
# cur = g.db.execute('select solved_challenges, score from users where username = (?)',
|
return render_template('item.html', name=name, picture=picture, description=description, seller=seller, price=price, uuid=uuid, interested_people =interested_people, seller_uuid = seller_uuid)
|
||||||
# [username])
|
|
||||||
|
|
||||||
# solved_challenges, score = cur.fetchone()
|
@app.route("/remove_product/<uuid>")
|
||||||
|
def remove_product(uuid):
|
||||||
|
|
||||||
|
if not 'logged_in' in session: return redirect('login')
|
||||||
|
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified = cur.fetchone()[0]
|
||||||
|
if not verified:
|
||||||
|
return redirect('verify')
|
||||||
|
|
||||||
|
cur = g.db.execute('select seller from products where uuid = (?)', [uuid])
|
||||||
|
product_seller = cur.fetchone()[0]
|
||||||
|
|
||||||
|
if ( product_seller == session['name'] ):
|
||||||
|
|
||||||
|
cur = g.db.execute('delete from products where uuid = (?)', [uuid])
|
||||||
|
g.db.commit()
|
||||||
|
cur = g.db.execute('select your_products from users where email = (?)', [session['email']])
|
||||||
|
your_products = cur.fetchone()[0];
|
||||||
|
your_products = your_products.replace(uuid,'')
|
||||||
|
your_products = your_products.strip()
|
||||||
|
print your_products
|
||||||
|
cur = g.db.execute('update users set your_products = (?) where email = (?)', [
|
||||||
|
your_products,
|
||||||
|
session['email']
|
||||||
|
])
|
||||||
|
g.db.commit()
|
||||||
|
|
||||||
|
flash("The product has been successfully removed.")
|
||||||
|
return redirect("products")
|
||||||
|
else:
|
||||||
|
return "This product does not belong to you. Nice try, but no."
|
||||||
|
|
||||||
|
@app.route("/verify", methods=["GET", "POST"])
|
||||||
|
def verify():
|
||||||
|
|
||||||
|
identifier = ""
|
||||||
|
|
||||||
|
if not 'logged_in' in session: return redirect('login')
|
||||||
|
else:
|
||||||
|
cur = g.db.execute('select uuid, verified from users where email = (?)', [session['email']])
|
||||||
|
uuid, verified = cur.fetchone()
|
||||||
|
|
||||||
|
if ( verified ):
|
||||||
|
# flash("Your e-mail address has already been verified.")
|
||||||
|
return redirect('products')
|
||||||
|
else:
|
||||||
|
if ( request.method == "GET" ):
|
||||||
|
identifier = request.args.get('identifier')
|
||||||
|
if ( request.method == "POST" ):
|
||||||
|
identifier = request.form['identifier']
|
||||||
|
|
||||||
|
if ( identifier ):
|
||||||
|
if ( identifier == uuid ):
|
||||||
|
cur = g.db.execute("update users set verified = (?) where email = (?)", [
|
||||||
|
1,
|
||||||
|
session['email']
|
||||||
|
] );
|
||||||
|
|
||||||
|
g.db.commit();
|
||||||
|
return redirect('products')
|
||||||
|
|
||||||
|
else:
|
||||||
|
flash("Incorrect verification code.")
|
||||||
|
|
||||||
|
return render_template( 'verify.html', identifier = identifier)
|
||||||
|
|
||||||
|
@app.route("/search")
|
||||||
|
def search():
|
||||||
|
if not 'logged_in' in session: return redirect('login')
|
||||||
|
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified = cur.fetchone()[0]
|
||||||
|
if not verified:
|
||||||
|
return redirect('verify')
|
||||||
|
return render_template("search.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/edit/<uuid>", methods=["GET", "POST"])
|
||||||
|
def edit(uuid):
|
||||||
|
if not 'logged_in' in session: return redirect('login')
|
||||||
|
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified = cur.fetchone()[0]
|
||||||
|
if not verified:
|
||||||
|
return redirect('verify')
|
||||||
|
|
||||||
|
if ( request.method == "GET" ):
|
||||||
|
|
||||||
|
|
||||||
|
cur = g.db.execute('select name, price, picture, description, seller from products where uuid = (?)', [uuid] )
|
||||||
|
name, price, picture, description, seller = cur.fetchone()
|
||||||
|
|
||||||
|
return render_template('edit.html', name=name, picture=picture, description=description, seller=seller, price=price[1:], uuid=uuid)
|
||||||
|
|
||||||
|
if ( request.method == "POST" ):
|
||||||
|
|
||||||
|
name = request.form['name']
|
||||||
|
# uuid = request.form['uuid']
|
||||||
|
picture = request.form['picture']
|
||||||
|
cur = g.db.execute('select seller from products where uuid = (?)', [uuid])
|
||||||
|
product_seller = cur.fetchone()[0]
|
||||||
|
|
||||||
|
if ( product_seller == session['name'] ):
|
||||||
|
# picture = request.form['picture']
|
||||||
|
price = request.form['price']
|
||||||
|
name = request.form['name']
|
||||||
|
description = request.form['description']
|
||||||
|
|
||||||
|
if (contains_bad_word(price.lower()) or \
|
||||||
|
contains_bad_word(description.lower()) or \
|
||||||
|
contains_bad_word(name.lower())
|
||||||
|
):
|
||||||
|
flash("Detected a bad word: '" + bad_word_found + "'. Not accepting that.")
|
||||||
|
return redirect(url_for('edit', uuid=uuid))
|
||||||
|
|
||||||
|
if ( name == "" ):
|
||||||
|
flash("Please enter a name of the product!")
|
||||||
|
return redirect(url_for('edit', uuid=uuid))
|
||||||
|
|
||||||
|
elif ( price == "" ):
|
||||||
|
flash("Please enter the price of the product in dollars!")
|
||||||
|
return redirect(url_for('edit', uuid=uuid))
|
||||||
|
elif ( description == "" ):
|
||||||
|
flash("Please enter a description of your product!")
|
||||||
|
return redirect(url_for('edit', uuid=uuid))
|
||||||
|
elif ( '.' in price ):
|
||||||
|
if ( price[-3] != '.' ):
|
||||||
|
flash("That does not look like a valid price!")
|
||||||
|
return redirect(url_for('edit', uuid=uuid))
|
||||||
|
try:
|
||||||
|
price_number = round(float(price),2)
|
||||||
|
warning(str(price_number))
|
||||||
|
if (price_number != abs(price_number)):
|
||||||
|
flash("That does not look like a valid price!")
|
||||||
|
return redirect(url_for('edit', uuid=uuid))
|
||||||
|
elif ( price_number >= price_cap ):
|
||||||
|
flash("Please enter a cost less than $" + str(price_cap))
|
||||||
|
return redirect(url_for('edit', uuid=uuid))
|
||||||
|
else:
|
||||||
|
# We should be good to process the form
|
||||||
|
price_number = '$' + format(price_number, '.2f')
|
||||||
|
|
||||||
|
if 'picture' not in request.files:
|
||||||
|
pass # They don't have to update the picture
|
||||||
|
else:
|
||||||
|
file = request.files['picture']
|
||||||
|
|
||||||
|
if file and allowed_file(file.filename):
|
||||||
|
filename = secure_filename(str(uuid4()) + "." + file.filename.split('.')[-1])
|
||||||
|
save_location = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||||
|
file.save(save_location)
|
||||||
|
p = Image.open(save_location)
|
||||||
|
try:
|
||||||
|
p = resizeimage.resize_cover(p, (350, 350))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
p.save(save_location)
|
||||||
|
# return redirect(url_for('uploaded_file', filename=filename))
|
||||||
|
picture = (url_for('uploaded_file', filename=filename))
|
||||||
|
|
||||||
|
cur = g.db.execute("update products set name = (?), picture = (?), description = (?), price = (?) where uuid = (?)", [
|
||||||
|
name,
|
||||||
|
str(picture),
|
||||||
|
description,
|
||||||
|
price_number,
|
||||||
|
uuid
|
||||||
|
] );
|
||||||
|
g.db.commit()
|
||||||
|
except:
|
||||||
|
# print price
|
||||||
|
flash("That does not look like a valid price!")
|
||||||
|
return redirect(url_for('edit', uuid=uuid))
|
||||||
|
|
||||||
|
else:
|
||||||
|
flash("This is not your own product!")
|
||||||
|
return redirect(request.referrer)
|
||||||
|
|
||||||
|
return redirect(url_for('product', uuid=uuid))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/profile/<uuid>", methods= ["GET", "POST"])
|
||||||
|
def profile(uuid):
|
||||||
|
if not 'logged_in' in session: return redirect('login')
|
||||||
|
cur = g.db.execute('select verified, room, phone from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified, room, phone = cur.fetchone()
|
||||||
|
if not verified:
|
||||||
|
return redirect('verify')
|
||||||
|
|
||||||
|
cur = g.db.execute('select email, your_products from users where uuid = (?)', [uuid])
|
||||||
|
email, your_products = cur.fetchone()
|
||||||
|
name = " ".join( [email.split(".")[0].title(), email.split(".")[2].split("@")[0].title() ])
|
||||||
|
your_products = your_products.split(" ")
|
||||||
|
products = []
|
||||||
|
for product in your_products:
|
||||||
|
cur = g.db.execute('select name from products where uuid = (?)', [product])
|
||||||
|
product_name = cur.fetchone()
|
||||||
|
if product_name != None:
|
||||||
|
product_name = product_name[0]
|
||||||
|
products.append( [product_name, product] )
|
||||||
|
|
||||||
|
if ( request.method == "POST" ):
|
||||||
|
|
||||||
|
if uuid == session['uuid']:
|
||||||
|
|
||||||
|
phone = room = ""
|
||||||
|
phone = request.form['phone']
|
||||||
|
room = request.form['room']
|
||||||
|
name = session['name']
|
||||||
|
|
||||||
|
if ( not re.search('\d\d\d-\d\d\d-\d\d\d\d', phone) ):
|
||||||
|
flash("Please enter the phone number in the form: ###-###-####")
|
||||||
|
return render_template("profile.html", name = name, products = products, phone = phone, room = room )
|
||||||
|
elif ( not ( re.search('E\d\d\d$', room) or re.search('\d\d\d\d$', room) ) ) :
|
||||||
|
flash("Please enter a proper room number, #### or E###.")
|
||||||
|
return render_template("profile.html", name = name, products = products, phone = phone, room = room )
|
||||||
|
else:
|
||||||
|
flash("Your profile has been saved successfully!")
|
||||||
|
cur = g.db.execute('update users set room = (?), phone = (?) where uuid = (?)', [
|
||||||
|
room,
|
||||||
|
phone,
|
||||||
|
session['uuid']
|
||||||
|
])
|
||||||
|
|
||||||
|
g.db.commit()
|
||||||
|
|
||||||
|
return render_template("profile.html", name = name, products = products, phone = phone, room = room )
|
||||||
|
|
||||||
|
return render_template("profile.html", name = name, products = products, room = room, phone = phone )
|
||||||
|
|
||||||
|
@app.route("/show_interest/<seller>/<uuid>")
|
||||||
|
def show_interest(seller, uuid):
|
||||||
|
if not 'logged_in' in session: return redirect('login')
|
||||||
|
cur = g.db.execute('select verified, room, phone from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified, room, phone = cur.fetchone()
|
||||||
|
if not verified:
|
||||||
|
return redirect('verify')
|
||||||
|
|
||||||
|
cur = g.db.execute('select interested_people, name from products where uuid = (?)', [uuid])
|
||||||
|
interested_people, product_name = cur.fetchone();
|
||||||
|
interested_people += '\n' + session['name']
|
||||||
|
interested_people = interested_people.strip()
|
||||||
|
cur = g.db.execute('update products set interested_people = (?) where uuid = (?)', [
|
||||||
|
interested_people,
|
||||||
|
uuid
|
||||||
|
])
|
||||||
|
g.db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
cur = g.db.execute('select email from users where name = (?)', [seller])
|
||||||
|
sellers_email = cur.fetchone()[0]
|
||||||
|
|
||||||
|
send_email( sellers_email,
|
||||||
|
'Someone is interested in your product!',
|
||||||
|
render_template("interest_email.html",
|
||||||
|
name = session['name'],
|
||||||
|
product_name = product_name,
|
||||||
|
room = room,
|
||||||
|
phone = phone,
|
||||||
|
email = session['email']
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
flash("You showed interest in this product! An e-mail has been sent to notify the seller.")
|
||||||
|
return redirect( request.referrer )
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/sell", methods=["GET", "POST"])
|
||||||
|
def sell():
|
||||||
|
|
||||||
|
if not 'logged_in' in session: return redirect('login')
|
||||||
|
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
|
||||||
|
verified = cur.fetchone()[0]
|
||||||
|
if not verified:
|
||||||
|
return redirect('verify')
|
||||||
|
|
||||||
|
name = picture = description = price = ""
|
||||||
|
|
||||||
|
if ( request.method == "POST" ):
|
||||||
|
|
||||||
|
name = request.form['name']
|
||||||
|
price = request.form['price']
|
||||||
|
description = request.form['description']
|
||||||
|
if ( contains_bad_word(price.lower()) or \
|
||||||
|
contains_bad_word(description.lower()) or \
|
||||||
|
contains_bad_word(name.lower())
|
||||||
|
):
|
||||||
|
flash("Detected a bad word: '" + bad_word_found + "'. Not accepting that.")
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
|
||||||
|
if ( name == "" ):
|
||||||
|
flash("Please enter a name of the product!")
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
elif ( price == "" ):
|
||||||
|
flash("Please enter the price of the product in dollars!")
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
elif ( description == "" ):
|
||||||
|
flash("Please enter a description of your product!")
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
elif ( '.' in price ):
|
||||||
|
if ( price[-3] != '.' ):
|
||||||
|
flash("That does not look like a valid price!")
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
try:
|
||||||
|
price_number = round(float(price),2)
|
||||||
|
warning(str(price_number))
|
||||||
|
except:
|
||||||
|
print price
|
||||||
|
flash("That does not look like a valid price!")
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
|
||||||
|
if (price_number != abs(price_number)):
|
||||||
|
flash("That does not look like a valid price!")
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
elif ( price_number >= price_cap ):
|
||||||
|
flash("Please enter a cost less than $" + str(price_cap))
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# We should be good to process the form
|
||||||
|
price_number = '$' + format(price_number, '.2f')
|
||||||
|
|
||||||
|
if 'picture' not in request.files:
|
||||||
|
pass # We make it optional for them to upload files, remember?
|
||||||
|
else:
|
||||||
|
file = request.files['picture']
|
||||||
|
|
||||||
|
if file and allowed_file(file.filename):
|
||||||
|
filename = secure_filename(str(uuid4()) + "." + file.filename.split('.')[-1])
|
||||||
|
save_location = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||||
|
file.save(save_location)
|
||||||
|
p = Image.open(save_location)
|
||||||
|
try:
|
||||||
|
p = resizeimage.resize_cover(p, (350, 350))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
p.save(save_location)
|
||||||
|
# return redirect(url_for('uploaded_file', filename=filename))
|
||||||
|
picture = (url_for('uploaded_file', filename=filename))
|
||||||
|
|
||||||
|
uuid = str(uuid4())
|
||||||
|
cur = g.db.execute('insert into products (name, picture, description, price, seller, interested_people, uuid) values ( ?, ?, ?, ?, ?, ?, ? )', [
|
||||||
|
name,
|
||||||
|
str(picture),
|
||||||
|
description,
|
||||||
|
price_number, # Since you are just selling this product, no one is interested yet!
|
||||||
|
session['name'],
|
||||||
|
"",
|
||||||
|
uuid
|
||||||
|
] );
|
||||||
|
|
||||||
|
g.db.commit()
|
||||||
|
cur = g.db.execute('select your_products from users where email = (?)', [session['email']])
|
||||||
|
your_products = cur.fetchone()[0];
|
||||||
|
your_products += ' ' + uuid
|
||||||
|
your_products = your_products.strip()
|
||||||
|
print your_products
|
||||||
|
cur = g.db.execute('update users set your_products = (?) where email = (?)', [
|
||||||
|
your_products,
|
||||||
|
session['email']
|
||||||
|
])
|
||||||
|
g.db.commit()
|
||||||
|
|
||||||
|
return redirect('products')
|
||||||
|
|
||||||
|
return render_template("sell.html", name=name, price = price, description = description)
|
||||||
|
|
||||||
|
@app.route("/log_out", methods=["GET", "POST"])
|
||||||
|
def log_out():
|
||||||
|
session_logout()
|
||||||
|
return redirect('login')
|
||||||
|
|
||||||
|
def session_login( email ):
|
||||||
|
|
||||||
|
flash("You have been successfully logged in!")
|
||||||
|
|
||||||
session['logged_in'] = True
|
session['logged_in'] = True
|
||||||
# session['username'] = username
|
session['email'] = email.lower()
|
||||||
# session['score'] = score
|
cur = g.db.execute('select uuid from users where email = (?)', [session['email']])
|
||||||
# session['solved_challenges'] = []
|
uuid = cur.fetchone()
|
||||||
|
if uuid != None: uuid = uuid[0];
|
||||||
|
session['uuid'] = uuid
|
||||||
|
session['name'] = " ".join( [email.split(".")[0].title(), email.split(".")[-2].split("@")[0].title() ])
|
||||||
|
|
||||||
def session_logout():
|
def session_logout():
|
||||||
|
|
||||||
flash("You have been successfully logged out.")
|
flash("You have been successfully logged out.")
|
||||||
|
|
||||||
session['logged_in'] = False
|
session.pop('logged_in')
|
||||||
# session.pop('username')
|
session.pop('email')
|
||||||
# session.pop('score')
|
session.pop('uuid')
|
||||||
|
session.pop('name')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( __name__ == "__main__" ):
|
if ( __name__ == "__main__" ):
|
||||||
|
|
||||||
context = (CERTIFICATE, PRIVATE_KEY)
|
context = (CERTIFICATE, PRIVATE_KEY)
|
||||||
app.run( host="0.0.0.0", debug=True, ssl_context=context, threaded=True)
|
app.run( host="0.0.0.0", debug=True, ssl_context=context, port = 444, threaded = True )
|
||||||
|
|
||||||
|
|
|
@ -428,7 +428,10 @@ def edit(uuid):
|
||||||
save_location = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
save_location = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||||
file.save(save_location)
|
file.save(save_location)
|
||||||
p = Image.open(save_location)
|
p = Image.open(save_location)
|
||||||
p = resizeimage.resize_cover(p, (350, 350))
|
try:
|
||||||
|
p = resizeimage.resize_cover(p, (350, 350))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
p.save(save_location)
|
p.save(save_location)
|
||||||
# return redirect(url_for('uploaded_file', filename=filename))
|
# return redirect(url_for('uploaded_file', filename=filename))
|
||||||
picture = (url_for('uploaded_file', filename=filename))
|
picture = (url_for('uploaded_file', filename=filename))
|
||||||
|
@ -604,7 +607,10 @@ def sell():
|
||||||
save_location = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
save_location = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||||
file.save(save_location)
|
file.save(save_location)
|
||||||
p = Image.open(save_location)
|
p = Image.open(save_location)
|
||||||
p = resizeimage.resize_cover(p, (350, 350))
|
try:
|
||||||
|
p = resizeimage.resize_cover(p, (350, 350))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
p.save(save_location)
|
p.save(save_location)
|
||||||
# return redirect(url_for('uploaded_file', filename=filename))
|
# return redirect(url_for('uploaded_file', filename=filename))
|
||||||
picture = (url_for('uploaded_file', filename=filename))
|
picture = (url_for('uploaded_file', filename=filename))
|
||||||
|
|
13
setup.sh
|
@ -44,10 +44,19 @@ function install_dependencies(){
|
||||||
apt-get -y install $DEPENDENCIES || panic
|
apt-get -y install $DEPENDENCIES || panic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function create_certificate(){
|
function create_certificate(){
|
||||||
|
|
||||||
echo "$0: ${GREEN}creating HTTPS certificates...${NC}"
|
echo "$0: ${GREEN}creating HTTPS certificates...${NC}"
|
||||||
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout $PRIVATEKEY_FILE -out $CERTIFICATE_FILE || panic
|
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout $PRIVATEKEY_FILE -out $CERTIFICATE_FILE <<EOF || panic
|
||||||
|
US
|
||||||
|
CT
|
||||||
|
New London
|
||||||
|
United States Coast Guard Academy
|
||||||
|
Cyber Team
|
||||||
|
github.com/JohnHammond
|
||||||
|
johnhammond010@gmail.com
|
||||||
|
EOF
|
||||||
|
|
||||||
sed "0,/\$CERTIFICATE_FILE/{s/\$CERTIFICATE_FILE/$CERTIFICATE_FILE/}" $SERVER_FILE > $NEW_SERVER_FILE || panic
|
sed "0,/\$CERTIFICATE_FILE/{s/\$CERTIFICATE_FILE/$CERTIFICATE_FILE/}" $SERVER_FILE > $NEW_SERVER_FILE || panic
|
||||||
sed -i "0,/\$PRIVATEKEY_FILE/{s/\$PRIVATEKEY_FILE/$PRIVATEKEY_FILE/}" $NEW_SERVER_FILE || panic
|
sed -i "0,/\$PRIVATEKEY_FILE/{s/\$PRIVATEKEY_FILE/$PRIVATEKEY_FILE/}" $NEW_SERVER_FILE || panic
|
||||||
|
@ -61,7 +70,7 @@ function create_database(){
|
||||||
|
|
||||||
rm -f $DATABASE
|
rm -f $DATABASE
|
||||||
sqlite3 $DATABASE < $SCHEMA_FILE || panic
|
sqlite3 $DATABASE < $SCHEMA_FILE || panic
|
||||||
chown $CURRENT_USER $DATABASE || panic
|
chown $CURRENT_USER $DATABASE
|
||||||
sed -i '0,/\$DATABASE/{s/\$DATABASE/'${DATABASE//\//\\/}'/}' $NEW_SERVER_FILE || panic
|
sed -i '0,/\$DATABASE/{s/\$DATABASE/'${DATABASE//\//\\/}'/}' $NEW_SERVER_FILE || panic
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,6 @@ a:visited{
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#vertical{
|
#vertical{
|
||||||
|
|
After Width: | Height: | Size: 3.9 KiB |
|
@ -3,8 +3,9 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>USCGA BearShop</title>
|
<title>ObjeeTrade</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/master.css' ) }}">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/master.css' ) }}">
|
||||||
|
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico' ) }}" type="image/x-icon">
|
||||||
<script src="{{ url_for('static', filename='js/jquery.js' ) }}"></script>
|
<script src="{{ url_for('static', filename='js/jquery.js' ) }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/notify.js' ) }}"></script>
|
<script src="{{ url_for('static', filename='js/notify.js' ) }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/jquery-ui.min.js' ) }}"></script>
|
<script src="{{ url_for('static', filename='js/jquery-ui.min.js' ) }}"></script>
|
||||||
|
@ -34,5 +35,9 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
<div style="position:fixed;bottom:10px;width:100%;text-align:center;color:rgba(0,0,0,.3);z-index: -5">
|
||||||
|
<small> This web application was developed solely by John Hammond</small>
|
||||||
|
<div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -2,8 +2,8 @@
|
||||||
<head></head>
|
<head></head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<h2>You got someone's interest on <a href="http://uscgabearshop">
|
<h2>You got someone's interest on <a href="https://www.objeetrade.com">
|
||||||
BearShop!</a></h2>
|
ObjeeTrade!</a></h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{{name}} showed an interest in your product, "{{product_name}}".
|
{{name}} showed an interest in your product, "{{product_name}}".
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Thanks for using <a href="http://uscgabearshop">BearShop!</a> I hope you are enjoying its services. If you have any questions, concerns, or comments, be sure to let me know!
|
Thanks for using <a href="https://www.objeetrade.com/">ObjeeTrade!</a> I hope you are enjoying its services. If you have any questions, concerns, or comments, be sure to let me know!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
<div id="login_box_background"></div>
|
<div id="login_box_background"></div>
|
||||||
<div id="login_box">
|
<div id="login_box">
|
||||||
|
|
||||||
<h1>Welcome the USCGA BearShop!</h1>
|
<h1>Welcome to ObjeeTrade!</h1>
|
||||||
<p>
|
<p>
|
||||||
Please login below with your EDU e-mail and your BearShop password.
|
Please login below with your EDU e-mail and your ObjeeTrade password.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title> Login -- USCGA BearShop</title>
|
<title> Login -- ObjeeTrade</title>
|
||||||
<link rel="stylesheet" type="text/css" href="../static/css/master.css">
|
<link rel="stylesheet" type="text/css" href="../static/css/master.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -12,9 +12,9 @@
|
||||||
<div id="login_box_background"></div>
|
<div id="login_box_background"></div>
|
||||||
<div id="login_box">
|
<div id="login_box">
|
||||||
|
|
||||||
<h1>Welcome the USCGA BearShop!</h1>
|
<h1>Welcome to ObjeeTrade!</h1>
|
||||||
<p>
|
<p>
|
||||||
Please login below with your EDU e-mail and your BearShop password.
|
Please login below with your EDU e-mail and your ObjeeTrade password.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<h1>Register an Account</h1>
|
<h1>Register an Account</h1>
|
||||||
<p>
|
<p>
|
||||||
To register an account with BearShop, we'll need you to supply your EDU e-mail account and decide on a secure password.
|
To register an account with ObjeeTrade, we'll need you to supply your EDU e-mail account and decide on a secure password.
|
||||||
</p>
|
</p>
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<input type="text" name="email" placeholder="E-mail" value="{{email}}">
|
<input type="text" name="email" placeholder="E-mail" value="{{email}}">
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
{% extends "base_page.html" %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div id="vertical">
|
||||||
|
|
||||||
|
<div style="text-align:center">
|
||||||
|
{% if products|length == 0 %}
|
||||||
|
<h2 style="color:silver; text-align:center">
|
||||||
|
There are currently no rides available. :(
|
||||||
|
</h2>
|
||||||
|
{% else %}
|
||||||
|
{% for ride in rides %}
|
||||||
|
<a href="{{ url_for('ride', uuid=ride[5] )}}">
|
||||||
|
<div class="ride">
|
||||||
|
<h2> {{ ride[0] }} <span>to {{ ride[1] }} </span>.</h2>
|
||||||
|
{{ ride[2] }} passengers on {{ ride[3] }}
|
||||||
|
</div></a>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
<head></head>
|
<head></head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<h2>Thank you for registering with <a href="http://uscgabearshop">
|
<h1>Thank you for registering with <a href="https://www.objeetrade.com">
|
||||||
BearShop!</a></h2>
|
ObjeeTrade!</a></h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b> Hi {{name}}! </b>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To complete your registraton, you must submit this verification code:
|
To complete your registraton, you must submit this verification code:
|
||||||
|
@ -15,12 +19,12 @@
|
||||||
You can do this more quickly by simply clicking this link:
|
You can do this more quickly by simply clicking this link:
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a href="http://uscgabearshop.com/verify?identifier={{identifier}}"> http://uscgabearshop.com/verify?identifier={{identifier}}</a>
|
<a href="https://www.objeetrade.com/verify?identifier={{identifier}}"> https://www.objeetrade.com/verify?identifier={{identifier}}</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Thanks for registering, and I hope you enjoy <a href="http://uscgabearshop">
|
Thanks for registering, and I hope you enjoy <a href="https://www.objeetrade.com">
|
||||||
BearShop!</a>
|
ObjeeTrade!</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 133 KiB |
After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 200 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 33 KiB |