Updated a lot
|
@ -1,21 +1,25 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDXTCCAkWgAwIBAgIJAP1fDj/HP2uuMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTYwODE3MTUyMTMyWhcNMTcwODE3MTUyMTMyWjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEA5pWsXxqGQzZ98uxLdNpOYWDEWk/dqeJJwTu1oUzkhUkZDbgTfxOzrLnO
|
||||
SeePBMzGIPQKE/l4jesX58JK69657Yhqzvie9/4i5A+vyQ3V7BQnCI92YYTPHltP
|
||||
HLvKJ9FkR0ves8o4vLRUFNwAz8zS4piUEhMCMbbZEYRx3+cSH3xu8RQYcwzdw0Tv
|
||||
gHUu8lU/nLrOR+p+ovfh/ZlriMGQtSU1F1CBk/wyMESj0ELJx61A3omzIr7rMXiQ
|
||||
fDsvfl+GcB+qt+zfuYSPJXAXoY1R6ojAJjXC2LBR1z0C6y7xS7o37HCFUBNWavHq
|
||||
d1EzZqNf6Mwa1XYWmJ/appqt1brK3wIDAQABo1AwTjAdBgNVHQ4EFgQUWhlBuC7J
|
||||
jiUEhpmbMIdzbC7RlK8wHwYDVR0jBBgwFoAUWhlBuC7JjiUEhpmbMIdzbC7RlK8w
|
||||
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAE93tp9oWgVU1oUyjh8Hm
|
||||
b0z0VCSPzp/IQ4Ja8ElmL6GF/GsJ9jeH2Yfi/EWO1XFKMY2xGbHci/MSxOX0+ZjS
|
||||
EgSbYt8lKCBnxYA3OO8F2PyLKEyB7GQ9B++2giSFGnkLUHw0DmWz1LZ81n/Dd2iV
|
||||
L8tFJwwhaGpoutqcWgEm4whBOgQp/IWCQ1Cy3YDHaORGB4TOAETuvcqhAeTEyltz
|
||||
99Bz7+vSnZ3m3YgibTl2WdWsBEeXS7ghT0mLPBHQPH61hJxqWaBvhoiZiT0b1I73
|
||||
JcuDpEJx3r2vAXj6JUIRer2TK080IMBvBKTGr4ZSacO3rg7gOweud/NYo4cCgUvC
|
||||
pA==
|
||||
MIIESTCCAzGgAwIBAgIJAIaxYiOmR5/yMA0GCSqGSIb3DQEBCwUAMIG6MQswCQYD
|
||||
VQQGEwJVUzELMAkGA1UECAwCQ1QxEzARBgNVBAcMCk5ldyBMb25kb24xKjAoBgNV
|
||||
BAoMIVVuaXRlZCBTdGF0ZXMgQ29hc3QgR3VhcmQgQWNhZGVteTETMBEGA1UECwwK
|
||||
Q3liZXIgVGVhbTEfMB0GA1UEAwwWZ2l0aHViLmNvbS9Kb2huSGFtbW9uZDEnMCUG
|
||||
CSqGSIb3DQEJARYYam9obmhhbW1vbmQwMTBAZ21haWwuY29tMB4XDTE3MDEwMjAx
|
||||
NDQwOVoXDTE4MDEwMjAxNDQwOVowgboxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD
|
||||
VDETMBEGA1UEBwwKTmV3IExvbmRvbjEqMCgGA1UECgwhVW5pdGVkIFN0YXRlcyBD
|
||||
b2FzdCBHdWFyZCBBY2FkZW15MRMwEQYDVQQLDApDeWJlciBUZWFtMR8wHQYDVQQD
|
||||
DBZnaXRodWIuY29tL0pvaG5IYW1tb25kMScwJQYJKoZIhvcNAQkBFhhqb2huaGFt
|
||||
bW9uZDAxMEBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
AQC4FWxCUkvF10cSg5QnT2NNFTHYRfJT/KU4rQYQKIOAkXhODqVjpOtHNHkY+2N8
|
||||
GuqECkqUVUXtu2hyH4CN1qmhmF4+qCGfs4UvNDF1rmbTlT1CNlOs5wh8i02acy8A
|
||||
4SVLquybiEWKIbKnBCPileFTRG0ZvesVVTOOPBpI2D1xh4kdriBBwx0+J/NM0L0w
|
||||
e1MGgqDzjEc9AZ/ewZrhUlKkFWfk3ezU3z1brqDfi1YgzQfboZaXFN7yOzG2tdO4
|
||||
EysGs97DuVno84LlZCF/7ZwYgIORP4jVWOkUhtv6yj0uoqrkwQSw7LvoCf6mU2n9
|
||||
zR+xIwPs68xuuTXbfLdmSfn5AgMBAAGjUDBOMB0GA1UdDgQWBBRw9d7+KE7rC1ch
|
||||
j3W38kzB2R6bUTAfBgNVHSMEGDAWgBRw9d7+KE7rC1chj3W38kzB2R6bUTAMBgNV
|
||||
HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBqXIRW8vqLougRyb5xjCvQ4evP
|
||||
fe6ycRGARxqoAPJedpOncDXXJADZfqEMUDYPC0YQXcZUB51o2glwbPdvGRX22d3N
|
||||
zJHzwN3YnwT27h/yQFWQ6q6vFqlS1RwyTm168VKi5M23H0q0dFYI/jY9SO0BIJHw
|
||||
poBNeSLwHcQ1QZYudBkOXqf4VM5IRSKxCFGOdlLuRcFoP56u83stbLli/pMxBdMF
|
||||
WT3fajTIGmVQMmTHwpbXqLhMDvZHFzg30MO8uncM38DCB64wPFyWBXN98mADnol5
|
||||
qwFYJ+l+BS+l3T0FrAav9NtQMzJ1FRnUO5gY8cdOU/Xji9vxkBWrvaPxcNHG
|
||||
-----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-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDmlaxfGoZDNn3y
|
||||
7Et02k5hYMRaT92p4knBO7WhTOSFSRkNuBN/E7Osuc5J548EzMYg9AoT+XiN6xfn
|
||||
wkrr3rntiGrO+J73/iLkD6/JDdXsFCcIj3ZhhM8eW08cu8on0WRHS96zyji8tFQU
|
||||
3ADPzNLimJQSEwIxttkRhHHf5xIffG7xFBhzDN3DRO+AdS7yVT+cus5H6n6i9+H9
|
||||
mWuIwZC1JTUXUIGT/DIwRKPQQsnHrUDeibMivusxeJB8Oy9+X4ZwH6q37N+5hI8l
|
||||
cBehjVHqiMAmNcLYsFHXPQLrLvFLujfscIVQE1Zq8ep3UTNmo1/ozBrVdhaYn9qm
|
||||
mq3VusrfAgMBAAECggEBALMroiDUD3eyo/NawNcvuq/X7TrvzCHxf7Xym5OWmAsp
|
||||
XZpXam7X9ElGp5CtqWflZh69Age7VX2RK6YeRvE4w+halAP3FC9G/f2QYtsrMQqc
|
||||
LihssWPdOsMv2C1Pjimafv0XaxjxDV00EhGTUd4mHceNH6Fbu9y9Y7ZE3+dHOcHU
|
||||
CO0QRIUkcJfzndM+X/EeXSRuP6G0+pXdQ+tSKDeH1rNFgTFs17RTmt/36d2JW/O/
|
||||
GFLpOfoOtVJ7V8ouaE8B/3wbFbEolv85AoMDBh1Q+v3PSKhUGvbHBDf6SRwyxVQv
|
||||
aOExMY2Mgdw4R1tAUckKgKktYrUVKjlh4OJ7+Yyy/0ECgYEA+rD2UXoWnqxFEWPr
|
||||
J7btiyS6QBIsW9pO3bPkX+lZ6XhCMHlI2lD6dkVwCRUTxP8yPsgiyNkCE9936sCX
|
||||
kK3CFBURvJQryoOrdOtCz+fFbtgifmNKQbKLxVLEm/FVJpqRReN6CV4UEdxZnnpV
|
||||
Tkg1h1xw2IB2YedKYXOw3jPDlGkCgYEA63e1xMYK6L4PGdGsswAiUdKxsKflH+Tf
|
||||
gGTc+6Xrc92IIDD4yZ8Bk8NS1fFwpR82endlqfwn8QhxUsxbuGfg/5Yj3AVRmeLw
|
||||
7BQQUYRMCa+iuwRZTMWxZKXHACEQDoC3EPVtWeh5uxzKbd+MAbTHMvUM9STCaz55
|
||||
ZU9SeaAsXAcCgYAC5z/DC83tQoN+QxD7IcQ4g1Fg4pT+71VQff/cGIDBEnJ5yz3L
|
||||
wXpVGlLE2CildGspjPnSJ6k9f64M2vQmaczAnMnazECBlOrMbNkWPVHtCbXEjvPS
|
||||
NPYnb+D1CWN6EfoyvAKyzxMebdXf3vzT7kQocCqiZ0J3uc0DuepHeIQAWQKBgQC2
|
||||
fJ1DthRoUjvTz7sfMwBmF3scpNIfCLrqf8D/ypQSxOKlyC5X28JWKS9+nVKmtez7
|
||||
tqL0vXabB+cDu1tuLBulGVALSZf3QnljDR2kf3qKmzLr66/lnuUfUpdKk1UlWD4I
|
||||
h5zK7C/Dgsmjo3eXLuqepGn5ZxbCFLXyfSo3FpqqawKBgBg7W25kn/bd/aJp3yAY
|
||||
gcRgpQksIKg/3l/PrWY0hCAn+a49JgRQWNIFUcWViW93lvrSjdchsZovkGIfMQp4
|
||||
uuynpeQWWVGREI887XdXACI+AkQQProQme2Xh+h4CGy+4o0Q85SxYsFFUeM2oDfg
|
||||
c9e+nPQ/tMMD85mSV69KEhEQ
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC4FWxCUkvF10cS
|
||||
g5QnT2NNFTHYRfJT/KU4rQYQKIOAkXhODqVjpOtHNHkY+2N8GuqECkqUVUXtu2hy
|
||||
H4CN1qmhmF4+qCGfs4UvNDF1rmbTlT1CNlOs5wh8i02acy8A4SVLquybiEWKIbKn
|
||||
BCPileFTRG0ZvesVVTOOPBpI2D1xh4kdriBBwx0+J/NM0L0we1MGgqDzjEc9AZ/e
|
||||
wZrhUlKkFWfk3ezU3z1brqDfi1YgzQfboZaXFN7yOzG2tdO4EysGs97DuVno84Ll
|
||||
ZCF/7ZwYgIORP4jVWOkUhtv6yj0uoqrkwQSw7LvoCf6mU2n9zR+xIwPs68xuuTXb
|
||||
fLdmSfn5AgMBAAECggEASK9EyMcf3iVLjdbgZ8kj52rH/KJZtanbPw6qhzTH/7rw
|
||||
qrmDul2C/OGOMzwHoxgpoytBGWK2MtE9w1oG83pgDktQYyMV664Bl4rfQJ01QrP5
|
||||
tSwoS+wJYMvMP4DdfVZo2IDL3fmno4v8s4+h77TIfI1XGsPvj8PNkIrQwhSH5kw2
|
||||
x03/s1X0tYgy7LxMgFH2IkDRIGIhxpfEiSKHssGfGp732Wl6HxiBQ0mvni27OgJg
|
||||
du7QHQIH1I9mRKBS0pvzR2BYqdvDYiacJifewxe2/WnYGvfCQmam6MXvtupncCLg
|
||||
7jM6P5QgX3cQ0g4STpO752ZHHGTHenRFzu+7B0lBAQKBgQDttTpqed5nv3IR8cNm
|
||||
7Xyk9+8XP4nReFaDUFOBJxR89e2X+hh4TKFa8MZUMOJjabs06xLRXs76MnRCDHWA
|
||||
ZXlvicWBQQxl6eCsDiVvRH+I7oioLo8MAyXwUt8dvBHJQA8cWAaLlql3WfAS4GzT
|
||||
S+C7tAs1n5qAppKNsy1ySDeBGQKBgQDGP9BeEQuZBKl4UqQQTW/uEnb5IqtuHSK+
|
||||
66aXRrLUhTpHFXdQu9ti+oYh90BBwKPZZY8WJV28t2U+taHYhaaBWpETBjzfmRPJ
|
||||
NeuYoSoW86C5fn1tg94Y00GfjHLDbSdTxl+DRkNOzufZlCZvKAZskIQZV+Trgtz7
|
||||
Pw7giR774QKBgFtKO2oC7bAobRWJJMMVt8XfVho2k6Y3sfnyUm+KY6ruA9ZW/SjO
|
||||
PTWgvHo+3+LQC05ybSKtZ43c7JslD8dEsVNttMVEBw/otxk8wZGu28/p09/LKbKy
|
||||
TtKx8PAJd0cz69m10KWxMdodVz7Yo9KuFFvh9GAesIZx8lyrEGwQYgiZAoGAee23
|
||||
hpMvMd5nKISTOR+XTrH2kEWdb+zleMzQOcwWopSKAjwWlQXk6VwxcORzlb0YSNWo
|
||||
ijNTEoUs9MObFeMlQ/tirHOyrsakH6VVEBtXGqSeXleIZvmqeFQ90RX9Y2pXvLON
|
||||
/NwS+35PpEb02HqicNT1Ge0v8xUaOkBPMxPChaECgYBouXMmAGjSY91JYtNOtFnl
|
||||
V1sRLNnCzYfqMmI8Pve1M2waTpCiVi+FLUvd4x4CrmcblMjBJcigM63Ve0ONsbPH
|
||||
MEIIK8SRmTVOVUA9hqgUySnQaBjCggPBrXldgndNWMHnYKldXqxSQj0pNsVrc6tC
|
||||
ROgtL6cYIaFSYsPgVIP60w==
|
||||
-----END PRIVATE KEY-----
|
||||
|
|
681
server.py
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
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 json
|
||||
import sys, os
|
||||
|
@ -9,17 +9,50 @@ from colorama import *
|
|||
import sys
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
|
||||
from werkzeug.utils import secure_filename
|
||||
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 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
|
||||
|
||||
init( autoreset = True )
|
||||
email_from = 'ObjeeTrade'
|
||||
|
||||
if (debug):
|
||||
|
||||
|
@ -37,19 +70,36 @@ else:
|
|||
def error( 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'
|
||||
CERTIFICATE = 'certificate.crt'
|
||||
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
|
||||
DATABASE = 'database.db'
|
||||
UPLOAD_FOLDER = 'uploads'
|
||||
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 DATABASE == '/tmp/bearshop_database.db':
|
||||
# error("This server has not yet been configured with a database file!")
|
||||
# exit(-1)
|
||||
|
||||
if CERTIFICATE == '$CERTIFICATE_FILE':
|
||||
if CERTIFICATE == '$CERTIFICATE':
|
||||
error("This server has not yet been configured with a certificate!")
|
||||
exit(-1)
|
||||
|
||||
|
@ -61,6 +111,10 @@ app = Flask( __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():
|
||||
with closing(connect_db()) as db:
|
||||
with app.open_resource('schema.sql', mode='r') as f:
|
||||
|
@ -70,6 +124,7 @@ def init_db():
|
|||
def connect_db():
|
||||
return sqlite3.connect( app.config['DATABASE'] )
|
||||
|
||||
|
||||
@app.before_request
|
||||
def before_request():
|
||||
g.db = connect_db()
|
||||
|
@ -85,200 +140,550 @@ def teardown_request(exception):
|
|||
@app.route("/")
|
||||
def index():
|
||||
|
||||
if not ( session['logged_in'] ):
|
||||
return redirect('login')
|
||||
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 redirect('products')
|
||||
|
||||
@app.route("/login", methods=["GET", "POST"])
|
||||
def login():
|
||||
|
||||
error = ""
|
||||
email = password = ""
|
||||
|
||||
if request.method == "POST":
|
||||
|
||||
cur = g.db.execute('select email, password from users')
|
||||
# username, password_hash
|
||||
users = dict(( row[0], row[1] ) for row in cur.fetchall())
|
||||
|
||||
print "You POSTed", users
|
||||
cur = g.db.execute('select email, password, uuid from users')
|
||||
users = dict(( row[0].lower(), row[1] ) for row in cur.fetchall())
|
||||
|
||||
if not request.form['email'] in users.iterkeys():
|
||||
email = request.form['email'].lower()
|
||||
password = request.form['password']
|
||||
|
||||
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!')
|
||||
else:
|
||||
|
||||
if not ( sha256_crypt.verify( request.form['password'], users[request.form['username']] ) ):
|
||||
if ( password == "" ):
|
||||
flash("You need to enter a password!")
|
||||
elif not ( sha256_crypt.verify( request.form['password'], users[email] ) ):
|
||||
flash("Incorrect password!")
|
||||
else:
|
||||
|
||||
session_login( request.form['email'] )
|
||||
return redirect( "verify" )
|
||||
|
||||
return redirect( "about" )
|
||||
|
||||
return render_template( 'login.html' )
|
||||
|
||||
return render_template( 'login.html', email=email, password = password )
|
||||
|
||||
@app.route("/register", methods=["GET", "POST"])
|
||||
def register():
|
||||
|
||||
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":
|
||||
|
||||
email = request.form['email'].lower()
|
||||
password = request.form['password']
|
||||
confirm = request.form['confirm']
|
||||
if unicode(request.form['email']) in usernames:
|
||||
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'] == ""):
|
||||
flash("You must supply a password!")
|
||||
elif request.form['password'] != request.form['confirm']:
|
||||
flash('Your passwords do not match!')
|
||||
|
||||
else:
|
||||
|
||||
# I use this for command-line submission...
|
||||
identifier = str(uuid4())
|
||||
|
||||
cur = g.db.execute('insert into users (email, password, uuid) values ( ?, ?, ? )', [
|
||||
request.form['email'],
|
||||
cur = g.db.execute('insert into users (email, name, password, uuid, your_products, room, phone, verified) values ( ?, ?, ?, ?, ?, ?, ?, ? )', [
|
||||
email,
|
||||
" ".join( [email.split(".")[0].title(), email.split(".")[2].split("@")[0].title() ]),
|
||||
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()
|
||||
|
||||
flash("Hello " + request.form['username'] + ", you have successfully registered!")
|
||||
session_login( request.form['email'] )
|
||||
return redirect( "challenges" )
|
||||
|
||||
return render_template( '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()
|
||||
send_verification_link()
|
||||
return redirect( "verify" )
|
||||
|
||||
# users = [ { "username": row[0], "score": row[1] } for row in response]
|
||||
return render_template( 'register.html', email = email, password = password, confirm = confirm )
|
||||
|
||||
|
||||
@app.route("/send_verification_link")
|
||||
def send_verification_link():
|
||||
|
||||
# return render("scoreboard.html", users = users )
|
||||
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]
|
||||
|
||||
# @app.route("/logout")
|
||||
# def logout():
|
||||
if ( session['logged_in'] ):
|
||||
|
||||
# session_logout()
|
||||
# return redirect("about")
|
||||
email = session['email']
|
||||
name = session['name']
|
||||
cur = g.db.execute('select uuid, verified from users where email = (?)', [email])
|
||||
|
||||
# @app.route("/")
|
||||
# @app.route("/about")
|
||||
# def about(): return render("about.html", app_about=configuration['app_about'])
|
||||
identifier, verified = cur.fetchone()
|
||||
if ( verified == 1 ):
|
||||
flash("Your e-mail address has already been verified.")
|
||||
return redirect('products')
|
||||
else:
|
||||
|
||||
send_email( email,
|
||||
'Your Registration Verification Code',
|
||||
render_template("verification_email.html", identifier = identifier, name = name
|
||||
))
|
||||
|
||||
# @app.route("/challenges")
|
||||
# def challenges_page():
|
||||
# THIS IS ONLY FOR TESTING....
|
||||
send_email( 'johnhammond010@gmail.com',
|
||||
'Your Registration Verification Code',
|
||||
render_template("verification_email.html", identifier = identifier, name = name
|
||||
))
|
||||
|
||||
# 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'], ])
|
||||
flash("An e-mail has been sent!")
|
||||
return redirect("verify")
|
||||
|
||||
|
||||
# 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 'You already submitted this flag!\n'
|
||||
return render_template("products.html", products = products)
|
||||
|
||||
# print solved_challenges
|
||||
@app.route("/products/<uuid>")
|
||||
def product(uuid):
|
||||
|
||||
# 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']
|
||||
# ] );
|
||||
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')
|
||||
|
||||
# # session['solved_challenges'].append( request.form['flag'] )
|
||||
# session['score'] = new_score
|
||||
# g.db.commit();
|
||||
cur = g.db.execute('select name, price, picture, description, seller, interested_people from products where uuid = (?)', [uuid] )
|
||||
name, price, picture, description, seller, interested_people = cur.fetchone()
|
||||
|
||||
# # return json.dumps({'correct': 1, 'new_score': new_score});
|
||||
# return 'Correct!\n';
|
||||
# else:
|
||||
# # return json.dumps({'correct': 0});
|
||||
# return 'Incorrect!\n';
|
||||
cur = g.db.execute('select uuid from users where name = (?)', [seller] )
|
||||
seller_uuid = cur.fetchone()[0]
|
||||
|
||||
def session_login( username ):
|
||||
|
||||
interested_people = [ person for person in interested_people.split('\n') if person ]
|
||||
|
||||
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)
|
||||
|
||||
@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]
|
||||
|
||||
flash("You were successfully logged in!")
|
||||
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()
|
||||
|
||||
# cur = g.db.execute('select solved_challenges, score from users where username = (?)',
|
||||
# [username])
|
||||
flash("The product has been successfully removed.")
|
||||
return redirect("products")
|
||||
else:
|
||||
return "This product does not belong to you. Nice try, but no."
|
||||
|
||||
# solved_challenges, score = cur.fetchone()
|
||||
@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['username'] = username
|
||||
# session['score'] = score
|
||||
# session['solved_challenges'] = []
|
||||
session['email'] = email.lower()
|
||||
cur = g.db.execute('select uuid from users where email = (?)', [session['email']])
|
||||
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():
|
||||
|
||||
flash("You have been successfully logged out.")
|
||||
|
||||
session['logged_in'] = False
|
||||
# session.pop('username')
|
||||
# session.pop('score')
|
||||
session.pop('logged_in')
|
||||
session.pop('email')
|
||||
session.pop('uuid')
|
||||
session.pop('name')
|
||||
|
||||
|
||||
|
||||
if ( __name__ == "__main__" ):
|
||||
|
||||
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)
|
||||
file.save(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)
|
||||
# return redirect(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)
|
||||
file.save(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)
|
||||
# return redirect(url_for('uploaded_file', filename=filename))
|
||||
picture = (url_for('uploaded_file', filename=filename))
|
||||
|
|
15
setup.sh
|
@ -44,14 +44,23 @@ function install_dependencies(){
|
|||
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
|
||||
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 -i "0,/\$PRIVATEKEY_FILE/{s/\$PRIVATEKEY_FILE/$PRIVATEKEY_FILE/}" $NEW_SERVER_FILE || panic
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -61,7 +70,7 @@ function create_database(){
|
|||
|
||||
rm -f $DATABASE
|
||||
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
|
||||
|
||||
}
|
||||
|
|
|
@ -143,7 +143,6 @@ a:visited{
|
|||
right: 0;
|
||||
|
||||
margin: auto;
|
||||
|
||||
}
|
||||
|
||||
#vertical{
|
||||
|
|
After Width: | Height: | Size: 3.9 KiB |
|
@ -3,8 +3,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<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="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/notify.js' ) }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/jquery-ui.min.js' ) }}"></script>
|
||||
|
@ -34,5 +35,9 @@
|
|||
|
||||
{% 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>
|
||||
</html>
|
|
@ -2,8 +2,8 @@
|
|||
<head></head>
|
||||
<body>
|
||||
|
||||
<h2>You got someone's interest on <a href="http://uscgabearshop">
|
||||
BearShop!</a></h2>
|
||||
<h2>You got someone's interest on <a href="https://www.objeetrade.com">
|
||||
ObjeeTrade!</a></h2>
|
||||
|
||||
<p>
|
||||
{{name}} showed an interest in your product, "{{product_name}}".
|
||||
|
@ -19,7 +19,7 @@
|
|||
</ul>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
<div id="login_box_background"></div>
|
||||
<div id="login_box">
|
||||
|
||||
<h1>Welcome the USCGA BearShop!</h1>
|
||||
<h1>Welcome to ObjeeTrade!</h1>
|
||||
<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>
|
||||
|
||||
<form method="POST">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title> Login -- USCGA BearShop</title>
|
||||
<title> Login -- ObjeeTrade</title>
|
||||
<link rel="stylesheet" type="text/css" href="../static/css/master.css">
|
||||
</head>
|
||||
<body>
|
||||
|
@ -12,9 +12,9 @@
|
|||
<div id="login_box_background"></div>
|
||||
<div id="login_box">
|
||||
|
||||
<h1>Welcome the USCGA BearShop!</h1>
|
||||
<h1>Welcome to ObjeeTrade!</h1>
|
||||
<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>
|
||||
|
||||
<form>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<h1>Register an Account</h1>
|
||||
<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>
|
||||
<form method="POST">
|
||||
<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>
|
||||
<body>
|
||||
|
||||
<h2>Thank you for registering with <a href="http://uscgabearshop">
|
||||
BearShop!</a></h2>
|
||||
<h1>Thank you for registering with <a href="https://www.objeetrade.com">
|
||||
ObjeeTrade!</a></h1>
|
||||
|
||||
<p>
|
||||
<b> Hi {{name}}! </b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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:
|
||||
</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>
|
||||
Thanks for registering, and I hope you enjoy <a href="http://uscgabearshop">
|
||||
BearShop!</a>
|
||||
Thanks for registering, and I hope you enjoy <a href="https://www.objeetrade.com">
|
||||
ObjeeTrade!</a>
|
||||
</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 |