Import
This commit is contained in:
		
						commit
						61f5bc4d17
					
				
							
								
								
									
										123
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,123 @@ | |||||||
|  | # Byte-compiled / optimized / DLL files | ||||||
|  | __pycache__/ | ||||||
|  | *.py[cod] | ||||||
|  | *$py.class | ||||||
|  | 
 | ||||||
|  | # C extensions | ||||||
|  | *.so | ||||||
|  | 
 | ||||||
|  | # Distribution / packaging | ||||||
|  | .Python | ||||||
|  | build/ | ||||||
|  | develop-eggs/ | ||||||
|  | dist/ | ||||||
|  | downloads/ | ||||||
|  | eggs/ | ||||||
|  | .eggs/ | ||||||
|  | lib/ | ||||||
|  | lib64/ | ||||||
|  | parts/ | ||||||
|  | sdist/ | ||||||
|  | var/ | ||||||
|  | wheels/ | ||||||
|  | pip-wheel-metadata/ | ||||||
|  | share/python-wheels/ | ||||||
|  | *.egg-info/ | ||||||
|  | .installed.cfg | ||||||
|  | *.egg | ||||||
|  | MANIFEST | ||||||
|  | 
 | ||||||
|  | # PyInstaller | ||||||
|  | #  Usually these files are written by a python script from a template | ||||||
|  | #  before PyInstaller builds the exe, so as to inject date/other infos into it. | ||||||
|  | *.manifest | ||||||
|  | *.spec | ||||||
|  | 
 | ||||||
|  | # Installer logs | ||||||
|  | pip-log.txt | ||||||
|  | pip-delete-this-directory.txt | ||||||
|  | 
 | ||||||
|  | # Unit test / coverage reports | ||||||
|  | htmlcov/ | ||||||
|  | .tox/ | ||||||
|  | .nox/ | ||||||
|  | .coverage | ||||||
|  | .coverage.* | ||||||
|  | .cache | ||||||
|  | nosetests.xml | ||||||
|  | coverage.xml | ||||||
|  | *.cover | ||||||
|  | .hypothesis/ | ||||||
|  | .pytest_cache/ | ||||||
|  | 
 | ||||||
|  | # Translations | ||||||
|  | *.mo | ||||||
|  | *.pot | ||||||
|  | 
 | ||||||
|  | # Django stuff: | ||||||
|  | *.log | ||||||
|  | local_settings.py | ||||||
|  | db.sqlite3 | ||||||
|  | 
 | ||||||
|  | # Flask stuff: | ||||||
|  | instance/ | ||||||
|  | .webassets-cache | ||||||
|  | 
 | ||||||
|  | # Scrapy stuff: | ||||||
|  | .scrapy | ||||||
|  | 
 | ||||||
|  | # Sphinx documentation | ||||||
|  | docs/_build/ | ||||||
|  | 
 | ||||||
|  | # PyBuilder | ||||||
|  | target/ | ||||||
|  | 
 | ||||||
|  | # Jupyter Notebook | ||||||
|  | .ipynb_checkpoints | ||||||
|  | 
 | ||||||
|  | # IPython | ||||||
|  | profile_default/ | ||||||
|  | ipython_config.py | ||||||
|  | 
 | ||||||
|  | # pyenv | ||||||
|  | .python-version | ||||||
|  | 
 | ||||||
|  | # pipenv | ||||||
|  | #   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||||||
|  | #   However, in case of collaboration, if having platform-specific dependencies or dependencies | ||||||
|  | #   having no cross-platform support, pipenv may install dependencies that don't work, or not | ||||||
|  | #   install all needed dependencies. | ||||||
|  | #Pipfile.lock | ||||||
|  | 
 | ||||||
|  | # celery beat schedule file | ||||||
|  | celerybeat-schedule | ||||||
|  | 
 | ||||||
|  | # SageMath parsed files | ||||||
|  | *.sage.py | ||||||
|  | 
 | ||||||
|  | # Environments | ||||||
|  | .env | ||||||
|  | .venv | ||||||
|  | env/ | ||||||
|  | venv/ | ||||||
|  | ENV/ | ||||||
|  | env.bak/ | ||||||
|  | venv.bak/ | ||||||
|  | 
 | ||||||
|  | # Spyder project settings | ||||||
|  | .spyderproject | ||||||
|  | .spyproject | ||||||
|  | 
 | ||||||
|  | # Rope project settings | ||||||
|  | .ropeproject | ||||||
|  | 
 | ||||||
|  | # mkdocs documentation | ||||||
|  | /site | ||||||
|  | 
 | ||||||
|  | # mypy | ||||||
|  | .mypy_cache/ | ||||||
|  | .dmypy.json | ||||||
|  | dmypy.json | ||||||
|  | 
 | ||||||
|  | # Pyre type checker | ||||||
|  | .pyre/ | ||||||
							
								
								
									
										2
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | Basic challenges developed for Hackmeeting 0x14. | ||||||
|  | https://hm.capturetheflag.it | ||||||
							
								
								
									
										9
									
								
								circus.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								circus.ini
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | [watcher:crypto2] | ||||||
|  | cmd = /usr/local/bin/gunicorn -w 3 --bin 192.168.0.12:5000 crypto2:app | ||||||
|  | working_dir = /home/ctf/rc4 | ||||||
|  | send_hup = true | ||||||
|  | 
 | ||||||
|  | [watcher:web] | ||||||
|  | cmd = /usr/local/bin/gunicorn -w 3 --bin 192.168.0.12:7000 web:app | ||||||
|  | working_dir = /home/ctf/evilcorp | ||||||
|  | send_hup = true | ||||||
							
								
								
									
										43
									
								
								ecb/crypto1/app.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								ecb/crypto1/app.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | import socket | ||||||
|  | import base64 | ||||||
|  | import threading | ||||||
|  | from Crypto.Cipher import AES | ||||||
|  | 
 | ||||||
|  | flag = 'HM{3cb_0r4cl3}' | ||||||
|  | key = '12345678abcdefgh' | ||||||
|  | 
 | ||||||
|  | BIND_IP = '192.168.0.12' | ||||||
|  | BIND_PORT = 8000 | ||||||
|  | 
 | ||||||
|  | def pad(raw): | ||||||
|  | 
 | ||||||
|  |     if (len(raw) % 16 == 0): | ||||||
|  |         return raw | ||||||
|  |     padding_required = 16 - (len(raw) % 16) | ||||||
|  |     padChar = b'\x00' | ||||||
|  |     data = raw.encode('ascii') + padding_required * padChar | ||||||
|  |     return data | ||||||
|  | 
 | ||||||
|  | def handle_client(client_socket): | ||||||
|  |     client_socket.send(bytes('I will send you AES(<input>+flag):\n'.encode('ascii'))) | ||||||
|  |     request = client_socket.recv(1024) | ||||||
|  |     string = request.decode('ascii').rstrip() | ||||||
|  |     cipher = AES.AESCipher(key, AES.MODE_ECB) | ||||||
|  |     ciphertext = base64.b64encode(cipher.encrypt(pad(string+flag))) | ||||||
|  |     client_socket.send(ciphertext) | ||||||
|  |     client_socket.close() | ||||||
|  | 
 | ||||||
|  | def tcp_server(): | ||||||
|  |     server = socket.socket( socket.AF_INET, socket.SOCK_STREAM) | ||||||
|  |     server.bind(( BIND_IP, BIND_PORT)) | ||||||
|  |     server.listen(5) | ||||||
|  |     print("[*] Listening on %s:%d" % (BIND_IP, BIND_PORT)) | ||||||
|  | 
 | ||||||
|  |     while 1: | ||||||
|  |         client, addr = server.accept() | ||||||
|  |         print("[*] Accepted connection from: %s:%d" %(addr[0], addr[1])) | ||||||
|  |         client_handler = threading.Thread(target=handle_client, args=(client,)) | ||||||
|  |         client_handler.start() | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     tcp_server() | ||||||
							
								
								
									
										37
									
								
								ecb/crypto1/solution.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								ecb/crypto1/solution.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | from base64 import b64decode | ||||||
|  | import socket | ||||||
|  | from Crypto.Cipher import AES | ||||||
|  | 
 | ||||||
|  | server = '127.0.0.1' | ||||||
|  | port = 8000 | ||||||
|  | 
 | ||||||
|  | chars = 'abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ{}_' | ||||||
|  | flag_blocks = 2 | ||||||
|  | block_size = 16 | ||||||
|  | index = {} | ||||||
|  | 
 | ||||||
|  | flag = '' | ||||||
|  | 
 | ||||||
|  | for i in range(block_size-1, 1, -1): | ||||||
|  | 	for j in chars: | ||||||
|  | 		 | ||||||
|  | 		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||||
|  | 		s.connect((server, port)) | ||||||
|  | 		data = s.recv(4096)  | ||||||
|  | 		s.send(('a'*i).encode('ascii')) | ||||||
|  | 		value = b64decode(s.recv(4096)).hex()[0:32] | ||||||
|  | 		s.close() | ||||||
|  | 
 | ||||||
|  | 		s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||||
|  | 		s.connect((server, port)) | ||||||
|  | 		data = s.recv(4096)  | ||||||
|  | 		s.send(('a'*i+flag+j).encode('ascii')) | ||||||
|  | 		test = b64decode(s.recv(4096)).hex()[0:32] | ||||||
|  | 		s.close() | ||||||
|  | 
 | ||||||
|  | 		if value == test: | ||||||
|  | 			flag += j | ||||||
|  | 			break | ||||||
|  | 	print(flag) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										
											BIN
										
									
								
								evilcorp/evilcorp.sqlite3
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								evilcorp/evilcorp.sqlite3
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										248
									
								
								evilcorp/web/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								evilcorp/web/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,248 @@ | |||||||
|  | from flask import Flask, g, request, render_template, redirect, current_app, send_file | ||||||
|  | from flask_argon2 import Argon2 | ||||||
|  | from io import BytesIO | ||||||
|  | import jwt | ||||||
|  | import time | ||||||
|  | import sqlite3 | ||||||
|  | import secrets | ||||||
|  | 
 | ||||||
|  | app = Flask(__name__) | ||||||
|  | app.config['PRIVATE_KEY'] = ''' | ||||||
|  | -----BEGIN RSA PRIVATE KEY----- | ||||||
|  | MIICXAIBAAKBgQCo0oR5UXusQs7tvgcT5EOLB+2JaKXmmip3ViGijLHku2Y+gyas | ||||||
|  | 0KFYHEQjTgz2AH1N9sUu8tzLAxn+wun28qyF3Paswmx27J/pAmbX8v6g+oGur4Jz | ||||||
|  | V6ZoM5PA5iD5UvWYcLBczB84GcqhQkLHh8n/sZXP9jXMnxjTPD4nuPuQ3wIDAQAB | ||||||
|  | AoGAd0s6/RdNEu6qlmifS7kS2V2ixmRCRu9NbsJYRiqxUfXyS94VKCzMthxTMbdn | ||||||
|  | hTXXVY44y/IlfvcUGWfWOABHU7JK5NfWbwJfH0dU2kNEf8LzPmf1DzGy6vj01i/u | ||||||
|  | 6KrSJMqJOW62NxQ1GjkvWVGgoy8RrHKzrkM7bnQ+i6JDVLECQQDX24V58LQwMmo2 | ||||||
|  | JDZHjEZLZlx4xQz3lzhrLOfn7B3zgspRrgufOp2SaL+nFaphUl4w8P9mo/FcDmqc | ||||||
|  | R402Z4yTAkEAyDfCiZiGBgPm7mDOLiJ1Wpyc21fsF6zwoc56xSbeK+a3t9LxT00M | ||||||
|  | 1W+qZv6e89erUmGNl85CwFmoyMEPdIgmBQJAOOUZp2x0cge3yxF8ZRtqI9GVKhf2 | ||||||
|  | NQRc0JMDhTPNKTQeE61mTs/qXH7TlTy2rfRB83ByQSGRKox6OTr6044zlQJAKuCe | ||||||
|  | Hb93PESLqRM8NG8WuL//a43ptqxHoC9K5XvMapRvVcOr//KdQ/w0/veabNgMDYls | ||||||
|  | vEzkyLKqzctilu8tTQJBAMXgHKX62GhH54pB4GrLLS25JpxqUNChDuPGaMPilfCW | ||||||
|  | WOsFVC93MPtLA/YaAJHKZNoaXulkb5q3jhlWxCpDAKM= | ||||||
|  | -----END RSA PRIVATE KEY----- | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | app.config['PUBLIC_KEY'] = '''-----BEGIN PUBLIC KEY----- | ||||||
|  | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo0oR5UXusQs7tvgcT5EOLB+2J | ||||||
|  | aKXmmip3ViGijLHku2Y+gyas0KFYHEQjTgz2AH1N9sUu8tzLAxn+wun28qyF3Pas | ||||||
|  | wmx27J/pAmbX8v6g+oGur4JzV6ZoM5PA5iD5UvWYcLBczB84GcqhQkLHh8n/sZXP | ||||||
|  | 9jXMnxjTPD4nuPuQ3wIDAQAB | ||||||
|  | -----END PUBLIC KEY-----''' | ||||||
|  | 
 | ||||||
|  | argon2 = Argon2(app) | ||||||
|  | 
 | ||||||
|  | flag1 = 'HM{sql_inj3ctions_4re_still_r3l3vant}' | ||||||
|  | flag2 = 'HM{y0u_th0ught_p4ssword_ha5h1ng_is_enough?}' | ||||||
|  | flag3 = 'HM{s3ssion_manag3ment_is_super_h4rd}' | ||||||
|  | 
 | ||||||
|  | database = 'evilcorp.sqlite3' | ||||||
|  | 
 | ||||||
|  | def check_session(cookies): | ||||||
|  | 
 | ||||||
|  |     if 'session' not in cookies: | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     session = cookies['session'] | ||||||
|  |     try: | ||||||
|  |         session_decoded = jwt.decode(session, app.config['PUBLIC_KEY']) | ||||||
|  |     except jwt.InvalidTokenError: | ||||||
|  |         return False | ||||||
|  |     return session_decoded | ||||||
|  | 
 | ||||||
|  | def get_db(): | ||||||
|  |     db = getattr(g, '_database', None) | ||||||
|  |     if db is None: | ||||||
|  |         db = g._database = sqlite3.connect(database) | ||||||
|  |     return db | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.teardown_appcontext | ||||||
|  | def close_connection(exception): | ||||||
|  |     db = getattr(g, '_database', None) | ||||||
|  |     if db is not None: | ||||||
|  |         db.close() | ||||||
|  | 
 | ||||||
|  | @app.route('/', methods=['GET']) | ||||||
|  | def show_index(): | ||||||
|  |     session = check_session(request.cookies) | ||||||
|  |     if session: | ||||||
|  |         authenticated = True | ||||||
|  |         username = session['user'] | ||||||
|  |     else: | ||||||
|  |         authenticated = False | ||||||
|  |         username = None | ||||||
|  |     return render_template('index.html', authenticated=authenticated, username=username) | ||||||
|  | 
 | ||||||
|  | @app.route('/news', methods=['GET']) | ||||||
|  | def show_news(): | ||||||
|  |     session = check_session(request.cookies) | ||||||
|  |     if session: | ||||||
|  |         authenticated = True | ||||||
|  |         username = session['user'] | ||||||
|  |     else: | ||||||
|  |         authenticated = False | ||||||
|  |         username = None | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         cur = get_db().execute('SELECT uid, title, body, images FROM news ORDER BY uid DESC') | ||||||
|  |         news = cur.fetchall() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |         print(e) | ||||||
|  |         return 'Something went wrong, ping the admins' | ||||||
|  |      | ||||||
|  |     return render_template('news.html', news=news, authenticated=authenticated, username=username) | ||||||
|  | 
 | ||||||
|  | @app.route('/images/<uid>', methods=['GET']) | ||||||
|  | def show_image(uid): | ||||||
|  |     try: | ||||||
|  |         cur = get_db().execute('SELECT uid, name, body FROM images WHERE uid = ' + uid) | ||||||
|  |         image = cur.fetchone() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |         print(e) | ||||||
|  |         return 'Something went wrong, ping the admins' | ||||||
|  |     if not image: | ||||||
|  |     	return 'No image found' | ||||||
|  |     return send_file(BytesIO(image[2]), attachment_filename=image[1]+'.jpg', mimetype='image/jpg') | ||||||
|  | 
 | ||||||
|  | @app.route('/login', methods=['GET']) | ||||||
|  | def show_login(): | ||||||
|  |     return render_template('login.html') | ||||||
|  | 
 | ||||||
|  | @app.route('/login', methods=['POST']) | ||||||
|  | def login(): | ||||||
|  | 
 | ||||||
|  |     if 'username' not in request.form or 'password' not in request.form: | ||||||
|  |         return 'All fields are required!' | ||||||
|  |     username = request.form['username'] | ||||||
|  |     password = request.form['password'] | ||||||
|  | 
 | ||||||
|  |     #if not username.isalnum(): | ||||||
|  |     #    return 'Login failed' | ||||||
|  | 
 | ||||||
|  |     if len(password) < 6: | ||||||
|  |         return 'Login failed' | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         cur = get_db().execute('SELECT uid, username, password FROM users WHERE username = ? LIMIT 1', (username,)) | ||||||
|  |         cur_user = cur.fetchone() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |         print(e) | ||||||
|  |         return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     if not cur_user: | ||||||
|  |         return 'Login failed' | ||||||
|  | 
 | ||||||
|  |     if not argon2.check_password_hash(cur_user[2], password): | ||||||
|  |         return 'Login failed' | ||||||
|  | 
 | ||||||
|  |     session = jwt.encode({'user': cur_user[1], 'admin': False, 'iat': int(time.time())}, key=app.config['PRIVATE_KEY'] , algorithm='RS256') | ||||||
|  | 
 | ||||||
|  |     response = current_app.make_response(redirect('/user', 302)) | ||||||
|  |     response.set_cookie('session', value=session, path='/', httponly=True) | ||||||
|  |     return response | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route('/reset', methods=['GET']) | ||||||
|  | def show_reset(): | ||||||
|  |     return render_template('reset.html') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route('/reset', methods=['POST']) | ||||||
|  | def reset(): | ||||||
|  |     if 'email' not in request.form: | ||||||
|  |         return 'Email is required required!' | ||||||
|  |     email = request.form['email'] | ||||||
|  | 
 | ||||||
|  |     if len(email) < 6: | ||||||
|  |         return 'Email too short' | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         cur = get_db().execute('SELECT uid, email, username, recovered, admin FROM users WHERE email = ? LIMIT 1', (email,)) | ||||||
|  |         cur_user = cur.fetchone() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |         print(e) | ||||||
|  |         return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     if not cur_user: | ||||||
|  |         return 'No user found' | ||||||
|  | 
 | ||||||
|  |     if cur_user[4]: | ||||||
|  |         return 'Nope' | ||||||
|  | 
 | ||||||
|  |     if cur_user[3]: | ||||||
|  |         return 'Password for this user has already been reset' | ||||||
|  | 
 | ||||||
|  |     uid = cur_user[0] | ||||||
|  |     token = secrets.token_hex() | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         #cur = get_db().execute('UPDATE user SET recovery = ?, recovered = 1 WHERE email = ?', (token, email,)) | ||||||
|  |         cur = get_db().execute('UPDATE users SET recovery = ? WHERE uid = ?', (token, uid,)) | ||||||
|  |         get_db().commit() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |         print(e) | ||||||
|  |         return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     return 'Reset token sent to user email' | ||||||
|  | 
 | ||||||
|  | @app.route('/reset2', methods=['POST']) | ||||||
|  | def reset2(): | ||||||
|  |     if 'email' not in request.form or 'token' not in request.form: | ||||||
|  |         return 'Both fields are required!' | ||||||
|  | 
 | ||||||
|  |     email = request.form['email'] | ||||||
|  |     token = request.form['token'] | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         cur = get_db().execute('SELECT * FROM users WHERE recovery = ? AND email = ? AND recovered != 1', (token, email,)) | ||||||
|  |         cur_user = cur.fetchone() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |         print(e) | ||||||
|  |         return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     if not cur_user: | ||||||
|  |         return 'Wrong email or token or password already reset one time' | ||||||
|  | 
 | ||||||
|  |     else: | ||||||
|  |         newpassword = secrets.token_urlsafe(16) | ||||||
|  |         try: | ||||||
|  |             cur = get_db().execute('UPDATE users SET password = ?, recovered = 1 WHERE recovery = ? AND email = ?', (argon2.generate_password_hash(newpassword), token, email,)) | ||||||
|  |             get_db().commit() | ||||||
|  |         except sqlite3.Error as e: | ||||||
|  |             print(e) | ||||||
|  |             return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     return 'Your new password is ' + newpassword | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route('/user', methods=['GET']) | ||||||
|  | def show_user(): | ||||||
|  |     session = check_session(request.cookies) | ||||||
|  |     if not session: | ||||||
|  |         return redirect('/login', 302) | ||||||
|  |     else: | ||||||
|  |         if not session['admin']: | ||||||
|  |             return render_template('user.html', authenticated=True, username=session['user'], flag2=flag2) | ||||||
|  |         return 'Good job! Here\'s the last flag: ' + flag3 | ||||||
|  | 
 | ||||||
|  | @app.route('/logout', methods=['GET']) | ||||||
|  | def logout(): | ||||||
|  |     response = current_app.make_response(redirect('/', 302)) | ||||||
|  |     for cookie in request.cookies: | ||||||
|  |         response.set_cookie(cookie, value='', expires=0) | ||||||
|  |     return response | ||||||
|  | 
 | ||||||
|  | @app.route('/robots.txt', methods=['GET']) | ||||||
|  | def show_robots(): | ||||||
|  |     return 'Disallow: /pub.asc' | ||||||
|  | 
 | ||||||
|  | @app.route('/pub.asc', methods=['GET']) | ||||||
|  | def show_pubkey(): | ||||||
|  |     return app.config['PUBLIC_KEY'] | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     app.run(host='0.0.0.0', port=7000) | ||||||
|  | 
 | ||||||
							
								
								
									
										
											BIN
										
									
								
								evilcorp/web/evilcorp.sqlite3
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								evilcorp/web/evilcorp.sqlite3
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										7
									
								
								evilcorp/web/pub.asc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								evilcorp/web/pub.asc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | -----BEGIN PUBLIC KEY----- | ||||||
|  | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo0oR5UXusQs7tvgcT5EOLB+2J | ||||||
|  | aKXmmip3ViGijLHku2Y+gyas0KFYHEQjTgz2AH1N9sUu8tzLAxn+wun28qyF3Pas | ||||||
|  | wmx27J/pAmbX8v6g+oGur4JzV6ZoM5PA5iD5UvWYcLBczB84GcqhQkLHh8n/sZXP | ||||||
|  | 9jXMnxjTPD4nuPuQ3wIDAQAB | ||||||
|  | -----END PUBLIC KEY----- | ||||||
|  | 
 | ||||||
							
								
								
									
										248
									
								
								evilcorp/web/static/menu.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								evilcorp/web/static/menu.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,248 @@ | |||||||
|  | body { | ||||||
|  |     color: #777; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .pure-img-responsive { | ||||||
|  |     max-width: 100%; | ||||||
|  |     height: auto; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Add transition to containers so they can push in and out. | ||||||
|  | */ | ||||||
|  | #layout, | ||||||
|  | #menu, | ||||||
|  | .menu-link { | ||||||
|  |     -webkit-transition: all 0.2s ease-out; | ||||||
|  |     -moz-transition: all 0.2s ease-out; | ||||||
|  |     -ms-transition: all 0.2s ease-out; | ||||||
|  |     -o-transition: all 0.2s ease-out; | ||||||
|  |     transition: all 0.2s ease-out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | This is the parent `<div>` that contains the menu and the content area. | ||||||
|  | */ | ||||||
|  | #layout { | ||||||
|  |     position: relative; | ||||||
|  |     left: 0; | ||||||
|  |     padding-left: 0; | ||||||
|  | } | ||||||
|  |     #layout.active #menu { | ||||||
|  |         left: 150px; | ||||||
|  |         width: 150px; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #layout.active .menu-link { | ||||||
|  |         left: 150px; | ||||||
|  |     } | ||||||
|  | /* | ||||||
|  | The content `<div>` is where all your content goes. | ||||||
|  | */ | ||||||
|  | .content { | ||||||
|  |     margin: 0 auto; | ||||||
|  |     padding: 0 2em; | ||||||
|  |     max-width: 800px; | ||||||
|  |     margin-bottom: 50px; | ||||||
|  |     line-height: 1.6em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .header { | ||||||
|  |      margin: 0; | ||||||
|  |      color: #333; | ||||||
|  |      text-align: center; | ||||||
|  |      padding: 2.5em 2em 0; | ||||||
|  |      border-bottom: 1px solid #eee; | ||||||
|  |  } | ||||||
|  |     .header h1 { | ||||||
|  |         margin: 0.2em 0; | ||||||
|  |         font-size: 3em; | ||||||
|  |         font-weight: 300; | ||||||
|  |     } | ||||||
|  |      .header h2 { | ||||||
|  |         font-weight: 300; | ||||||
|  |         color: #ccc; | ||||||
|  |         padding: 0; | ||||||
|  |         margin-top: 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | .content-subhead { | ||||||
|  |     margin: 50px 0 20px 0; | ||||||
|  |     font-weight: 300; | ||||||
|  |     color: #888; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | The `#menu` `<div>` is the parent `<div>` that contains the `.pure-menu` that | ||||||
|  | appears on the left side of the page. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #menu { | ||||||
|  |     margin-left: -150px; /* "#menu" width */ | ||||||
|  |     width: 150px; | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; | ||||||
|  |     bottom: 0; | ||||||
|  |     z-index: 1000; /* so the menu or its navicon stays above all content */ | ||||||
|  |     background: #191818; | ||||||
|  |     overflow-y: auto; | ||||||
|  |     -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  |     /* | ||||||
|  |     All anchors inside the menu should be styled like this. | ||||||
|  |     */ | ||||||
|  |     #menu a { | ||||||
|  |         color: #999; | ||||||
|  |         border: none; | ||||||
|  |         padding: 0.6em 0 0.6em 0.6em; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |     Remove all background/borders, since we are applying them to #menu. | ||||||
|  |     */ | ||||||
|  |      #menu .pure-menu, | ||||||
|  |      #menu .pure-menu ul { | ||||||
|  |         border: none; | ||||||
|  |         background: transparent; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |     Add that light border to separate items into groups. | ||||||
|  |     */ | ||||||
|  |     #menu .pure-menu ul, | ||||||
|  |     #menu .pure-menu .menu-item-divided { | ||||||
|  |         border-top: 1px solid #333; | ||||||
|  |     } | ||||||
|  |         /* | ||||||
|  |         Change color of the anchor links on hover/focus. | ||||||
|  |         */ | ||||||
|  |         #menu .pure-menu li a:hover, | ||||||
|  |         #menu .pure-menu li a:focus { | ||||||
|  |             background: #333; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |     This styles the selected menu item `<li>`. | ||||||
|  |     */ | ||||||
|  |     #menu .pure-menu-selected, | ||||||
|  |     #menu .pure-menu-heading { | ||||||
|  |         background: #1f8dd6; | ||||||
|  |     } | ||||||
|  |         /* | ||||||
|  |         This styles a link within a selected menu item `<li>`. | ||||||
|  |         */ | ||||||
|  |         #menu .pure-menu-selected a { | ||||||
|  |             color: #fff; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |     This styles the menu heading. | ||||||
|  |     */ | ||||||
|  |     #menu .pure-menu-heading { | ||||||
|  |         font-size: 110%; | ||||||
|  |         color: #fff; | ||||||
|  |         margin: 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | /* -- Dynamic Button For Responsive Menu -------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | The button to open/close the Menu is custom-made and not part of Pure. Here's | ||||||
|  | how it works: | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | `.menu-link` represents the responsive menu toggle that shows/hides on | ||||||
|  | small screens. | ||||||
|  | */ | ||||||
|  | .menu-link { | ||||||
|  |     position: fixed; | ||||||
|  |     display: block; /* show this only on small screens */ | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; /* "#menu width" */ | ||||||
|  |     background: #000; | ||||||
|  |     background: rgba(0,0,0,0.7); | ||||||
|  |     font-size: 10px; /* change this value to increase/decrease button size */ | ||||||
|  |     z-index: 10; | ||||||
|  |     width: 2em; | ||||||
|  |     height: auto; | ||||||
|  |     padding: 2.1em 1.6em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |     .menu-link:hover, | ||||||
|  |     .menu-link:focus { | ||||||
|  |         background: #000; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .menu-link span { | ||||||
|  |         position: relative; | ||||||
|  |         display: block; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .menu-link span, | ||||||
|  |     .menu-link span:before, | ||||||
|  |     .menu-link span:after { | ||||||
|  |         background-color: #fff; | ||||||
|  |         width: 100%; | ||||||
|  |         height: 0.2em; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |         .menu-link span:before, | ||||||
|  |         .menu-link span:after { | ||||||
|  |             position: absolute; | ||||||
|  |             margin-top: -0.6em; | ||||||
|  |             content: " "; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .menu-link span:after { | ||||||
|  |             margin-top: 0.6em; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* -- Responsive Styles (Media Queries) ------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | Hides the menu at `48em`, but modify this based on your app's needs. | ||||||
|  | */ | ||||||
|  | @media (min-width: 48em) { | ||||||
|  | 
 | ||||||
|  |     .header, | ||||||
|  |     .content { | ||||||
|  |         padding-left: 2em; | ||||||
|  |         padding-right: 2em; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #layout { | ||||||
|  |         padding-left: 150px; /* left col width "#menu" */ | ||||||
|  |         left: 0; | ||||||
|  |     } | ||||||
|  |     #menu { | ||||||
|  |         left: 150px; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .menu-link { | ||||||
|  |         position: fixed; | ||||||
|  |         left: 150px; | ||||||
|  |         display: none; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #layout.active .menu-link { | ||||||
|  |         left: 150px; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (max-width: 48em) { | ||||||
|  |     /* Only apply this when the window is small. Otherwise, the following | ||||||
|  |     case results in extra padding on the left: | ||||||
|  |         * Make the window small. | ||||||
|  |         * Tap the menu to trigger the active state. | ||||||
|  |         * Make the window large again. | ||||||
|  |     */ | ||||||
|  |     #layout.active { | ||||||
|  |         position: relative; | ||||||
|  |         left: 150px; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								evilcorp/web/static/pure.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								evilcorp/web/static/pure.css
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								evilcorp/web/static/robots.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								evilcorp/web/static/robots.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | Disallow: /pub.asc | ||||||
							
								
								
									
										46
									
								
								evilcorp/web/static/ui.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								evilcorp/web/static/ui.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | (function (window, document) { | ||||||
|  | 
 | ||||||
|  |     var layout   = document.getElementById('layout'), | ||||||
|  |         menu     = document.getElementById('menu'), | ||||||
|  |         menuLink = document.getElementById('menuLink'), | ||||||
|  |         content  = document.getElementById('main'); | ||||||
|  | 
 | ||||||
|  |     function toggleClass(element, className) { | ||||||
|  |         var classes = element.className.split(/\s+/), | ||||||
|  |             length = classes.length, | ||||||
|  |             i = 0; | ||||||
|  | 
 | ||||||
|  |         for(; i < length; i++) { | ||||||
|  |           if (classes[i] === className) { | ||||||
|  |             classes.splice(i, 1); | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         // The className is not found
 | ||||||
|  |         if (length === classes.length) { | ||||||
|  |             classes.push(className); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         element.className = classes.join(' '); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     function toggleAll(e) { | ||||||
|  |         var active = 'active'; | ||||||
|  | 
 | ||||||
|  |         e.preventDefault(); | ||||||
|  |         toggleClass(layout, active); | ||||||
|  |         toggleClass(menu, active); | ||||||
|  |         toggleClass(menuLink, active); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     menuLink.onclick = function (e) { | ||||||
|  |         toggleAll(e); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     content.onclick = function(e) { | ||||||
|  |         if (menu.className.indexOf('active') !== -1) { | ||||||
|  |             toggleAll(e); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | }(this, this.document)); | ||||||
							
								
								
									
										41
									
								
								evilcorp/web/templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								evilcorp/web/templates/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | <!doctype html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |     <meta charset="utf-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <meta name="description" content="A layout example with a side menu that hides on mobile, just like the Pure website."> | ||||||
|  |     <title>Evil Corp | Home</title> | ||||||
|  |      | ||||||
|  |     <link rel="stylesheet" href="/static/pure.css">     | ||||||
|  |     <link rel="stylesheet" href="/static/menu.css"> | ||||||
|  | 
 | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <div id="layout"> | ||||||
|  | 
 | ||||||
|  |     {% include 'nav.html' %} | ||||||
|  | 
 | ||||||
|  |     <div id="main"> | ||||||
|  |         <div class="header"> | ||||||
|  |             <h1>Welcome to Evil Corp</h1> | ||||||
|  |             <h2>We are a totally-legit, zero-bullshit company</h2> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="content"> | ||||||
|  |             <h2 class="content-subhead">What's this site for?</h2> | ||||||
|  |             <p> | ||||||
|  |                 This is out completely secure company website. Valid credentials are required to access most resources, but you can still visit our <a href="/news">News</a> area freely. | ||||||
|  |                 As in any other CMS, admins have superpowers: they can, for example, read super secret flags! | ||||||
|  |             </p> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <script src="/static/ui.js"></script> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										54
									
								
								evilcorp/web/templates/login.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								evilcorp/web/templates/login.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | <!doctype html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |     <meta charset="utf-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <meta name="description" content="A layout example with a side menu that hides on mobile, just like the Pure website."> | ||||||
|  |     <title>Evil Corp | Login</title> | ||||||
|  |      | ||||||
|  |     <link rel="stylesheet" href="/static/pure.css">     | ||||||
|  |     <link rel="stylesheet" href="/static/menu.css"> | ||||||
|  | 
 | ||||||
|  |     <style> | ||||||
|  |         .login { | ||||||
|  |             margin-right: auto; | ||||||
|  |             margin-left: auto; | ||||||
|  |             width: 240px; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .pure-input { | ||||||
|  |             width: 240px; | ||||||
|  |         } | ||||||
|  |     </style> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <div id="layout"> | ||||||
|  | 
 | ||||||
|  |     {% include 'nav.html' %} | ||||||
|  | 
 | ||||||
|  |     <div id="main"> | ||||||
|  |         <div class="header"> | ||||||
|  |             <h1>Evil Corp</h1> | ||||||
|  |             <h2>Login to access our corporate resources</h2> | ||||||
|  |         </div> | ||||||
|  |         <div class="login"> | ||||||
|  |             <form class="pure-form" method="post" action=""> | ||||||
|  |                 <fieldset class="pure-group"> | ||||||
|  |                     <input type="text" class="pure-input" placeholder="Username" name="username"> | ||||||
|  |                     <input type="password" class="pure-input" placeholder="Password" name="password"> | ||||||
|  |                 </fieldset> | ||||||
|  |                 <button type="submit" class="pure-button pure-input pure-button-primary">Sign in</button> | ||||||
|  |                 <p><a href="/reset">Forgot password?</a></p> | ||||||
|  |             </form> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <script src="/static/ui.js"></script> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										22
									
								
								evilcorp/web/templates/nav.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								evilcorp/web/templates/nav.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  |     <!-- Menu toggle --> | ||||||
|  |     <a href="#menu" id="menuLink" class="menu-link"> | ||||||
|  |         <!-- Hamburger icon --> | ||||||
|  |         <span></span> | ||||||
|  |     </a> | ||||||
|  | 
 | ||||||
|  |     <div id="menu"> | ||||||
|  |         <div class="pure-menu"> | ||||||
|  |             <a class="pure-menu-heading" href="#">Evil Corp</a> | ||||||
|  | 
 | ||||||
|  |             <ul class="pure-menu-list"> | ||||||
|  |                 <li class="pure-menu-item"><a href="/" class="pure-menu-link">Home</a></li> | ||||||
|  |                 <li class="pure-menu-item"><a href="/news" class="pure-menu-link">News</a></li> | ||||||
|  |                 {% if authenticated %} | ||||||
|  |                 <li class="pure-menu-item"><a href="/user" class="pure-menu-link">{{ username }}</a></li>  | ||||||
|  |                 <li class="pure-menu-item"><a href="/logout" class="pure-menu-link">Logout</a></li> | ||||||
|  |                 {% else %} | ||||||
|  |                 <li class="pure-menu-item"><a href="/login" class="pure-menu-link">Login</a></li> | ||||||
|  |                 {% endif %} | ||||||
|  |             </ul> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
							
								
								
									
										41
									
								
								evilcorp/web/templates/news.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								evilcorp/web/templates/news.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | <!doctype html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |     <meta charset="utf-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <meta name="description" content="A layout example with a side menu that hides on mobile, just like the Pure website."> | ||||||
|  |     <title>Evil Corp | News</title> | ||||||
|  |      | ||||||
|  |     <link rel="stylesheet" href="/static/pure.css">     | ||||||
|  |     <link rel="stylesheet" href="/static/menu.css"> | ||||||
|  | 
 | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <div id="layout"> | ||||||
|  | 
 | ||||||
|  |     {% include 'nav.html' %} | ||||||
|  | 
 | ||||||
|  |     <div id="main"> | ||||||
|  |         <div class="header"> | ||||||
|  |             <h1>Evil Corp News</h1> | ||||||
|  |             <h2>Here we will keep you updated on how we improve the world!</h2> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         {% for post in news %} | ||||||
|  |         <div class="content"> | ||||||
|  |             <h2 class="content-subhead">{{ post[1] }}</h2> | ||||||
|  |             {{ post[2]|safe }} | ||||||
|  |             <img class="pure-img-responsive" src="/images/{{ post[3] }}"> | ||||||
|  |         </div> | ||||||
|  |         {% endfor %} | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <script src="/static/ui.js"></script> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										64
									
								
								evilcorp/web/templates/reset.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								evilcorp/web/templates/reset.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | <!doctype html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |     <meta charset="utf-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <meta name="description" content="A layout example with a side menu that hides on mobile, just like the Pure website."> | ||||||
|  |     <title>Evil Corp | Password reset</title> | ||||||
|  |      | ||||||
|  |     <link rel="stylesheet" href="/static/pure.css">     | ||||||
|  |     <link rel="stylesheet" href="/static/menu.css"> | ||||||
|  | 
 | ||||||
|  |     <style> | ||||||
|  |         .login { | ||||||
|  |             margin-right: auto; | ||||||
|  |             margin-left: auto; | ||||||
|  |             width: 240px; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         .pure-input { | ||||||
|  |             width: 240px; | ||||||
|  |         } | ||||||
|  |     </style> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <div id="layout"> | ||||||
|  | 
 | ||||||
|  |     {% include 'nav.html' %} | ||||||
|  | 
 | ||||||
|  |     <div id="main"> | ||||||
|  |         <div class="header"> | ||||||
|  |             <h1>Evil Corp</h1> | ||||||
|  |             <h2>Can't remember your password?</h2> | ||||||
|  |         </div> | ||||||
|  |         <div class="login"> | ||||||
|  |             <form class="pure-form" method="post" action=""> | ||||||
|  |                 <fieldset class="pure-group"> | ||||||
|  |                     <input type="email" class="pure-input" placeholder="Email" name="email"> | ||||||
|  |                 </fieldset> | ||||||
|  |                 <button type="submit" class="pure-button pure-input pure-button-primary">Send</button> | ||||||
|  |             </form> | ||||||
|  |         </div> | ||||||
|  |         <div class="header"> | ||||||
|  |             <h2>Already got a token?</h2> | ||||||
|  |         </div> | ||||||
|  |         <div class="login"> | ||||||
|  |             <form class="pure-form" method="post" action="/reset2"> | ||||||
|  |                 <fieldset class="pure-group"> | ||||||
|  |                     <input type="email" class="pure-input" placeholder="Email" name="email"> | ||||||
|  |                     <input type="text" class="pure-input" placeholder="Reset Token" name="token"> | ||||||
|  |                 </fieldset> | ||||||
|  |                 <button type="submit" class="pure-button pure-input pure-button-primary">Reset</button> | ||||||
|  |             </form> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <script src="/static/ui.js"></script> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										46
									
								
								evilcorp/web/templates/user.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								evilcorp/web/templates/user.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | <!doctype html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |     <meta charset="utf-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <meta name="description" content="A layout example with a side menu that hides on mobile, just like the Pure website."> | ||||||
|  |     <title>Evil Corp | Home</title> | ||||||
|  |      | ||||||
|  |     <link rel="stylesheet" href="/static/pure.css">     | ||||||
|  |     <link rel="stylesheet" href="/static/menu.css"> | ||||||
|  | 
 | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <div id="layout"> | ||||||
|  | 
 | ||||||
|  |     {% include 'nav.html' %} | ||||||
|  | 
 | ||||||
|  |     <div id="main"> | ||||||
|  |         <div class="header"> | ||||||
|  |             <h1>User Profile</h1> | ||||||
|  |             <h2>Welcome back <italic>{{ username }}</italic></h2> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         <div class="content"> | ||||||
|  |             <h2 class="content-subhead">Congratulations</h2> | ||||||
|  |             <p> | ||||||
|  |                 Here's your second flag: <strong>{{ flag2 }}</strong> | ||||||
|  |             </p> | ||||||
|  |         </div> | ||||||
|  |         <div class="content"> | ||||||
|  |             <h2 class="content-subhead">User options</h2> | ||||||
|  |             <p> | ||||||
|  |                 Unfortunately we have yet to implement user functionalities. If you are an admin, please login as such to change site configuration. | ||||||
|  |             </p> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <script src="/static/ui.js"></script> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										4
									
								
								evilcorp/wsgi.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								evilcorp/wsgi.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | from web import app | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     app.run(host='192.168.0.12', port=7000) | ||||||
							
								
								
									
										242
									
								
								rc4/crypto2/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								rc4/crypto2/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,242 @@ | |||||||
|  | from flask import Flask, g, request, render_template, redirect, current_app | ||||||
|  | from uuid import uuid4 | ||||||
|  | from flask_argon2 import Argon2 | ||||||
|  | from Crypto.Cipher import ARC4 | ||||||
|  | from binascii import hexlify, unhexlify | ||||||
|  | import sqlite3 | ||||||
|  | import json | ||||||
|  | import secrets | ||||||
|  | app = Flask(__name__) | ||||||
|  | argon2 = Argon2(app) | ||||||
|  | 
 | ||||||
|  | flag = 'HM{h3r35_y0ur_2time_p4d}' | ||||||
|  | 
 | ||||||
|  | database = 'wep.sqlite3' | ||||||
|  | 
 | ||||||
|  | def get_db(): | ||||||
|  |     db = getattr(g, '_database', None) | ||||||
|  |     if db is None: | ||||||
|  |         db = g._database = sqlite3.connect(database) | ||||||
|  |     return db | ||||||
|  | 
 | ||||||
|  | @app.teardown_appcontext | ||||||
|  | def close_connection(exception): | ||||||
|  |     db = getattr(g, '_database', None) | ||||||
|  |     if db is not None: | ||||||
|  |         db.close() | ||||||
|  | 
 | ||||||
|  | def check_session(cookies): | ||||||
|  | 
 | ||||||
|  |     if 'session' not in cookies and 'iv' not in cookies or 'uid' not in cookies: | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         cur = get_db().execute('SELECT uid, username, iv, key FROM users WHERE uid = ? AND iv = ? LIMIT 1', (cookies['uid'], cookies['iv'])) | ||||||
|  |         cur_user = cur.fetchone() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |     	print(e) | ||||||
|  |     	return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     if not cur_user: | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     uid = cur_user[0] | ||||||
|  |     username = cur_user[1] | ||||||
|  |     iv = cur_user[2] | ||||||
|  |     key = cur_user[3] | ||||||
|  |     cipher = ARC4.new(bytes(iv) + key) | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         plaintext = cipher.decrypt(unhexlify(cookies['session'])) | ||||||
|  |         session = json.loads(plaintext) | ||||||
|  |     except: | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     session['key'] = key | ||||||
|  |     session['iv'] = iv | ||||||
|  |     return session | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route('/', methods=['GET']) | ||||||
|  | def index(): | ||||||
|  |     return render_template('index.html') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route('/register', methods=['GET']) | ||||||
|  | def show_register(): | ||||||
|  |     return render_template('register.html') | ||||||
|  | 
 | ||||||
|  | @app.route('/register', methods=['POST']) | ||||||
|  | def register(): | ||||||
|  | 
 | ||||||
|  |     if 'username' not in request.form or 'password' not in request.form or 'password2' not in request.form: | ||||||
|  |        return 'All fields are required!' | ||||||
|  |     username = request.form['username'] | ||||||
|  |     password = request.form['password'] | ||||||
|  |     password2 = request.form['password2'] | ||||||
|  | 
 | ||||||
|  |     if not username.isalnum(): | ||||||
|  |     	return 'Username must be alphanumeric' | ||||||
|  | 
 | ||||||
|  |     if password != password2: | ||||||
|  |     	return 'Password confirmation does not match' | ||||||
|  | 
 | ||||||
|  |     if len(password) < 6: | ||||||
|  |     	return 'Password must be at least 6 chars!' | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |     	cur = get_db().execute('SELECT username FROM users WHERE username= ? LIMIT 1', (username,)) | ||||||
|  |     	cur_user = cur.fetchone() | ||||||
|  |     except: | ||||||
|  |     	return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     if cur_user: | ||||||
|  |         return 'Username already exist' | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         cur.execute('INSERT INTO users (uid, username, password, iv, key) VALUES(?, ?, ?, 0, ?)', (str(uuid4()), username, argon2.generate_password_hash(password), secrets.token_bytes(16),)) | ||||||
|  |         get_db().commit() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |     	print(e) | ||||||
|  |     	return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     return redirect('/login', 302) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route('/login', methods=['GET']) | ||||||
|  | def show_login(): | ||||||
|  |     return render_template('login.html') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route('/login', methods=['POST']) | ||||||
|  | def login(): | ||||||
|  | 
 | ||||||
|  |     if 'username' not in request.form or 'password' not in request.form: | ||||||
|  |     	return 'All fields are required!' | ||||||
|  |     username = request.form['username'] | ||||||
|  |     password = request.form['password'] | ||||||
|  | 
 | ||||||
|  |     if not username.isalnum(): | ||||||
|  |     	return 'Login failed' | ||||||
|  | 
 | ||||||
|  |     if len(password) < 6: | ||||||
|  |     	return 'Login failed' | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         cur = get_db().execute('SELECT uid, username, password, iv, key FROM users WHERE username = ? LIMIT 1', (username,)) | ||||||
|  |         cur_user = cur.fetchone() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |     	print(e) | ||||||
|  |     	return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     if not cur_user: | ||||||
|  |     	return 'Login failed' | ||||||
|  | 
 | ||||||
|  |     if not argon2.check_password_hash(cur_user[2], password): | ||||||
|  |     	return 'Login failed' | ||||||
|  | 
 | ||||||
|  |     uid = cur_user[0] | ||||||
|  |     username = cur_user[1] | ||||||
|  |     iv = cur_user[3]+1 | ||||||
|  |     key = cur_user[4] | ||||||
|  | 
 | ||||||
|  |     if iv >= 255: | ||||||
|  |     	iv = 0 | ||||||
|  | 
 | ||||||
|  |     data = { | ||||||
|  |         'username': username, | ||||||
|  |         'description': 'No description yet', | ||||||
|  |         'show_flag': False | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     cipher = ARC4.new(bytes(iv) + key) | ||||||
|  |      | ||||||
|  |     try: | ||||||
|  |         ciphertext = cipher.encrypt(json.dumps(data).encode('ascii')).hex() | ||||||
|  |     except: | ||||||
|  |     	return 'Something went wrong, ping the admins' | ||||||
|  |      | ||||||
|  |     try: | ||||||
|  |     	get_db().execute('UPDATE users SET iv = ? WHERE username = ?', (iv, username,)) | ||||||
|  |     	get_db().commit() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |     	print(e) | ||||||
|  |     	return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     response = current_app.make_response(redirect('/user', 302)) | ||||||
|  |     response.set_cookie('session', value=str(ciphertext), path='/', httponly=True) | ||||||
|  |     response.set_cookie('uid', value=uid, path='/', httponly=True) | ||||||
|  |     response.set_cookie('iv', value=str(iv), path='/', httponly=True) | ||||||
|  |     return response | ||||||
|  | 
 | ||||||
|  | @app.route('/user', methods=['GET']) | ||||||
|  | def show_user(): | ||||||
|  |     session = check_session(request.cookies) | ||||||
|  |     if not session: | ||||||
|  |         return redirect('/login', 302) | ||||||
|  |     if session['show_flag']: | ||||||
|  |         return flag | ||||||
|  | 
 | ||||||
|  |     return render_template('user.html', authenticated=True, username=session['username'], description=session['description']) | ||||||
|  | 
 | ||||||
|  | @app.route('/user', methods=['POST']) | ||||||
|  | def user(): | ||||||
|  |     session = check_session(request.cookies) | ||||||
|  |     if not session: | ||||||
|  |         return redirect('/login', 302) | ||||||
|  |     if session['show_flag']: | ||||||
|  |         return flag | ||||||
|  | 
 | ||||||
|  |     if 'description' not in request.form: | ||||||
|  |     	return 'Description field is mandatory!' | ||||||
|  | 
 | ||||||
|  |     description = request.form['description'] | ||||||
|  | 
 | ||||||
|  |     if len(description) < 10 or len(description) > 200: | ||||||
|  |     	return 'Description either too short (<10) or too long (>200)' | ||||||
|  | 
 | ||||||
|  |     username = session['username'] | ||||||
|  |     key = session['key'] | ||||||
|  |     iv = session['iv']+1 | ||||||
|  | 
 | ||||||
|  |     if iv >= 255: | ||||||
|  |     	iv = 0 | ||||||
|  | 
 | ||||||
|  |     data = { | ||||||
|  |         'username': username, | ||||||
|  |         'description': description, | ||||||
|  |         'show_flag': False | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     cipher = ARC4.new(bytes(iv) + key) | ||||||
|  |      | ||||||
|  |     try: | ||||||
|  |         ciphertext = cipher.encrypt(json.dumps(data).encode('ascii')).hex() | ||||||
|  |     except: | ||||||
|  |     	return 'Something went wrong, ping the admins' | ||||||
|  |      | ||||||
|  |     try: | ||||||
|  |     	get_db().execute('UPDATE users SET iv = ? WHERE username = ?', (iv, username,)) | ||||||
|  |     	get_db().commit() | ||||||
|  |     except sqlite3.Error as e: | ||||||
|  |     	print(e) | ||||||
|  |     	return 'Something went wrong, ping the admins' | ||||||
|  | 
 | ||||||
|  |     response = current_app.make_response(redirect('/user', 302)) | ||||||
|  |     response.set_cookie('session', value=str(ciphertext), path='/', httponly=True) | ||||||
|  |     response.set_cookie('iv', value=str(iv), path='/', httponly=True) | ||||||
|  |     return response | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     return render_template('user.html', authenticated=True, username=session['username'], description=session['description']) | ||||||
|  | 
 | ||||||
|  | @app.route('/logout', methods=['GET']) | ||||||
|  | def logout(): | ||||||
|  |     response = current_app.make_response(redirect('/', 302)) | ||||||
|  |     for cookie in request.cookies: | ||||||
|  |         response.set_cookie(cookie, value='', expires=0) | ||||||
|  |     return response | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     app.run(host='0.0.0.0') | ||||||
							
								
								
									
										61
									
								
								rc4/crypto2/solution.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								rc4/crypto2/solution.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | import requests | ||||||
|  | from binascii import hexlify, unhexlify | ||||||
|  | 
 | ||||||
|  | url = 'http://192.168.0.222:5000' | ||||||
|  | 
 | ||||||
|  | # Any registered username and password | ||||||
|  | username = 'myBLfLEDraYh3Dq' | ||||||
|  | password = '9GQLqu39EviKw' | ||||||
|  | 
 | ||||||
|  | # default comment and any much longer string | ||||||
|  | original = 'No description yet' | ||||||
|  | description = 'stringadiversamapiulungastringadiversamapiulungastringa'.encode('ascii') | ||||||
|  | 
 | ||||||
|  | # do login | ||||||
|  | s = requests.session() | ||||||
|  | r = s.post(url + '/login', data={'username': username, 'password': password}) | ||||||
|  | 
 | ||||||
|  | cur_iv = s.cookies['iv'] | ||||||
|  | 
 | ||||||
|  | ciphertext1 = s.cookies['session'] | ||||||
|  | 
 | ||||||
|  | # loop trough 256 requests to obtain a two time pad | ||||||
|  | for i in range(int(cur_iv), int(cur_iv)+256): | ||||||
|  | 	s.post(url + '/user', data={'description': description}) | ||||||
|  | 
 | ||||||
|  | 	if s.cookies['iv'] == cur_iv: | ||||||
|  | 		ciphertext2 = s.cookies['session'] | ||||||
|  | 
 | ||||||
|  | for i in range(0, len(ciphertext1), 2): | ||||||
|  | 	if ciphertext1[i:i+1] != ciphertext2[i:i+1]: | ||||||
|  | 		break | ||||||
|  | 
 | ||||||
|  | # obtain new cookis with the original comment to flip the fals in true | ||||||
|  | s.post(url + '/user', data={'description': original}) | ||||||
|  | 
 | ||||||
|  | cur_iv = s.cookies['iv'] | ||||||
|  | uid = s.cookies['uid'] | ||||||
|  | 
 | ||||||
|  | description = description.hex() | ||||||
|  | ciphertext1 = ciphertext1[i:] | ||||||
|  | ciphertext2 = ciphertext2[i:i+len(description)] | ||||||
|  | 
 | ||||||
|  | # xor our known plaintext with the given ciphertext to recover part of the rc4 stream | ||||||
|  | key = '{:x}'.format(int(ciphertext2, 16) ^ int(description, 16))[0:len(ciphertext1)] | ||||||
|  | # xor our known rc4 stream with the default comment on the same iteration to decrypt the final parte of the cookie | ||||||
|  | plaintext = unhexlify('{:x}'.format(int(key, 16) ^ int(ciphertext1, 16))) | ||||||
|  | 
 | ||||||
|  | # print the plaintext and notice it has a show_flag parameter | ||||||
|  | print('[*] Decrypted first cookie: ' + plaintext.decode('ascii')) | ||||||
|  | 
 | ||||||
|  | # xor 'true ' with 'false' to calculate the value to use to flip the ciphertext | ||||||
|  | flip = '{:x}'.format(int('true '.encode('ascii').hex(), 16) ^ int('false'.encode('ascii').hex(), 16)) | ||||||
|  | 
 | ||||||
|  | cur_session = s.cookies['session'] | ||||||
|  | # xor to obtain 'true ' from false' | ||||||
|  | flip = '{:x}'.format(int(flip, 16) ^ int(cur_session[-12:-2], 16)) | ||||||
|  | session = cur_session[0:-12] + flip + cur_session[-2:] | ||||||
|  | # get the flag! | ||||||
|  | flag = requests.get(url + '/user', cookies={'iv': cur_iv, 'uid': uid, 'session': session}) | ||||||
|  | 
 | ||||||
|  | print('[*] Got the flag: ' + flag.text) | ||||||
							
								
								
									
										1
									
								
								rc4/crypto2/static/min.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								rc4/crypto2/static/min.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | /* Copyright 2014 Owen Versteeg; MIT licensed */body,textarea,input,select{background:0;border-radius:0;font:16px sans-serif;margin:0}.smooth{transition:all .2s}.btn,.nav a{text-decoration:none}.container{margin:0 20px;width:auto}label>*{display:inline}form>*{display:block;margin-bottom:10px}.btn{background:#999;border-radius:6px;border:0;color:#fff;cursor:pointer;display:inline-block;margin:2px 0;padding:12px 30px 14px}.btn:hover{background:#888}.btn:active,.btn:focus{background:#777}.btn-a{background:#0ae}.btn-a:hover{background:#09d}.btn-a:active,.btn-a:focus{background:#08b}.btn-b{background:#3c5}.btn-b:hover{background:#2b4}.btn-b:active,.btn-b:focus{background:#2a4}.btn-c{background:#d33}.btn-c:hover{background:#c22}.btn-c:active,.btn-c:focus{background:#b22}.btn-sm{border-radius:4px;padding:10px 14px 11px}.row{margin:1% 0;overflow:auto}.col{float:left}.table,.c12{width:100%}.c11{width:91.66%}.c10{width:83.33%}.c9{width:75%}.c8{width:66.66%}.c7{width:58.33%}.c6{width:50%}.c5{width:41.66%}.c4{width:33.33%}.c3{width:25%}.c2{width:16.66%}.c1{width:8.33%}h1{font-size:3em}.btn,h2{font-size:2em}.ico{font:33px Arial Unicode MS,Lucida Sans Unicode}.addon,.btn-sm,.nav,textarea,input,select{outline:0;font-size:14px}textarea,input,select{padding:8px;border:1px solid #ccc}textarea:focus,input:focus,select:focus{border-color:#5ab}textarea,input[type=text]{-webkit-appearance:none;}.addon{padding:8px 12px;box-shadow:0 0 0 1px #ccc}.nav,.nav .current,.nav a:hover{background:#000;color:#fff}.nav{height:24px;padding:11px 0 15px}.nav a{color:#aaa;padding-right:1em;position:relative;top:-1px}.nav .pagename{font-size:22px;top:1px}.btn.btn-close{background:#000;float:right;font-size:25px;margin:-54px 7px;display:none}@media(min-width:1310px){.container{margin:auto;width:1270px}}@media(max-width:870px){.row .col{width:100%}}@media(max-width:500px){.btn.btn-close{display:block}.nav{overflow:hidden}.pagename{margin-top:-11px}.nav:active,.nav:focus{height:auto}.nav div:before{background:#000;border-bottom:10px double;border-top:3px solid;content:'';float:right;height:4px;position:relative;right:3px;top:14px;width:20px}.nav a{padding:.5em 0;display:block;width:50%}}.table th,.table td{padding:.5em;text-align:left}.table tbody>:nth-child(2n-1){background:#ddd}.msg{padding:1.5em;background:#def;border-left:5px solid #59d} | ||||||
							
								
								
									
										35
									
								
								rc4/crypto2/templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								rc4/crypto2/templates/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  | 	<head> | ||||||
|  | 		<meta charset="UTF-8"> | ||||||
|  | 		<meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|  | 
 | ||||||
|  | 		<title>HM0x14 - WE(P)B | Home</title> | ||||||
|  | 
 | ||||||
|  | 		<link href="static/min.css" rel="stylesheet" type="text/css"> | ||||||
|  | 
 | ||||||
|  | 		<style> | ||||||
|  | 			.hero { | ||||||
|  | 				background: #eee; | ||||||
|  | 				padding: 20px; | ||||||
|  | 				border-radius: 10px; | ||||||
|  | 				margin-top: 1em; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			.hero h1 { | ||||||
|  | 				margin-top: 0; | ||||||
|  | 				margin-bottom: 0.3em; | ||||||
|  | 			} | ||||||
|  | 		</style> | ||||||
|  | 	</head> | ||||||
|  | 	<body> | ||||||
|  | 		{% include 'navbar.html' %} | ||||||
|  | 		<div class="container"> | ||||||
|  | 			<div class="hero"> | ||||||
|  | 				<h1>Welcome</h1> | ||||||
|  | 				<p>I learnt WEP is so secure that i decided to use it for my session management, but why waste 24bit for the IV? 8 should be enough, no user is going to do that many requests anyway...</p> | ||||||
|  | 				<a class="btn btn-b" href="/register">Register</a> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
|  | 	</body> | ||||||
|  | </html> | ||||||
							
								
								
									
										43
									
								
								rc4/crypto2/templates/login.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								rc4/crypto2/templates/login.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  | 	<head> | ||||||
|  | 		<meta charset="UTF-8"> | ||||||
|  | 		<meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|  | 
 | ||||||
|  | 		<title>HM0x14 - WE(P)B | Login</title> | ||||||
|  | 
 | ||||||
|  | 		<link href="static/min.css" rel="stylesheet" type="text/css"> | ||||||
|  | 
 | ||||||
|  | 		<style> | ||||||
|  | 		input { | ||||||
|  | 			border: 1px solid #ccc; | ||||||
|  | 			box-shadow: inset 0 1px 3px #ddd; | ||||||
|  | 			border-radius: 2px; | ||||||
|  | 			vertical-align: middle; | ||||||
|  | 			-webkit-box-sizing: border-box; | ||||||
|  | 			-moz-box-sizing: border-box; | ||||||
|  | 			box-sizing: border-box; | ||||||
|  | 			width: 240px; | ||||||
|  | 			max-width: 100%; | ||||||
|  | 			padding: 0.5em 0.6em; | ||||||
|  | 			margin-bottom: 0.5em; | ||||||
|  | 		} | ||||||
|  | 		</style> | ||||||
|  | 	</head> | ||||||
|  | 	<body> | ||||||
|  | 	{% include 'navbar.html' %} | ||||||
|  | 		<div class="container"> | ||||||
|  | 			<div class="row"> | ||||||
|  |     			<div class="col c6"> | ||||||
|  |     			<h1>Login</h1> | ||||||
|  |     			<hr> | ||||||
|  |     				<form method="post" action=""> | ||||||
|  |     					<input type="text" name="username" id="username" placeholder="Username"> | ||||||
|  | 						<input type="password" name="password" id="password" placeholder="Password"> | ||||||
|  | 						<input type="submit" class="btn btn-a btn-sm smooth" value="Login"> | ||||||
|  |     				</form> | ||||||
|  |     			</div> | ||||||
|  |     		</div> | ||||||
|  | 		</div> | ||||||
|  | 	</body> | ||||||
|  | </html> | ||||||
							
								
								
									
										13
									
								
								rc4/crypto2/templates/navbar.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								rc4/crypto2/templates/navbar.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | 		<nav class="nav" tabindex="-1" onclick="this.focus()"> | ||||||
|  | 			<div class="container"> | ||||||
|  | 				<a class="pagename current" href="#">HM0x14 - WE(P)B</a> | ||||||
|  | 				{% if authenticated %} | ||||||
|  | 				<a href="/user">{{ username }}</a>  | ||||||
|  | 				<a href="/logout">Logout</a> | ||||||
|  | 				{% else %} | ||||||
|  | 				<a href="/">Home</a> | ||||||
|  | 				<a href="/login">Login</a>  | ||||||
|  | 				<a href="/register">Register</a> | ||||||
|  | 				{% endif %} | ||||||
|  | 			</div> | ||||||
|  | 		</nav> | ||||||
							
								
								
									
										44
									
								
								rc4/crypto2/templates/register.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								rc4/crypto2/templates/register.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  | 	<head> | ||||||
|  | 		<meta charset="UTF-8"> | ||||||
|  | 		<meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|  | 
 | ||||||
|  | 		<title>HM0x14 - WE(P)B | Register</title> | ||||||
|  | 
 | ||||||
|  | 		<link href="static/min.css" rel="stylesheet" type="text/css"> | ||||||
|  | 
 | ||||||
|  | 		<style> | ||||||
|  | 		input { | ||||||
|  | 			border: 1px solid #ccc; | ||||||
|  | 			box-shadow: inset 0 1px 3px #ddd; | ||||||
|  | 			border-radius: 2px; | ||||||
|  | 			vertical-align: middle; | ||||||
|  | 			-webkit-box-sizing: border-box; | ||||||
|  | 			-moz-box-sizing: border-box; | ||||||
|  | 			box-sizing: border-box; | ||||||
|  | 			width: 240px; | ||||||
|  | 			max-width: 100%; | ||||||
|  | 			padding: 0.5em 0.6em; | ||||||
|  | 			margin-bottom: 0.5em; | ||||||
|  | 		} | ||||||
|  | 		</style> | ||||||
|  | 	</head> | ||||||
|  | 	<body> | ||||||
|  | 	{% include 'navbar.html' %} | ||||||
|  | 		<div class="container"> | ||||||
|  | 			<div class="row"> | ||||||
|  |     			<div class="col c6"> | ||||||
|  |     			<h1>Register</h1> | ||||||
|  |     			<hr> | ||||||
|  |     				<form method="post" action=""> | ||||||
|  |     					<input type="text" name="username" id="username" placeholder="Username"> | ||||||
|  | 						<input type="password" name="password" id="password" placeholder="Password"> | ||||||
|  | 						<input type="password" name="password2" id="password2" placeholder="repeat Password"> | ||||||
|  | 						<input type="submit" class="btn btn-a btn-sm smooth" value="Register"> | ||||||
|  |     				</form> | ||||||
|  |     			</div> | ||||||
|  |     		</div> | ||||||
|  | 		</div> | ||||||
|  | 	</body> | ||||||
|  | </html> | ||||||
							
								
								
									
										56
									
								
								rc4/crypto2/templates/user.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								rc4/crypto2/templates/user.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  | 	<head> | ||||||
|  | 		<meta charset="UTF-8"> | ||||||
|  | 		<meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|  | 
 | ||||||
|  | 		<title>HM0x14 - WE(P)B | User</title> | ||||||
|  | 
 | ||||||
|  | 		<link href="static/min.css" rel="stylesheet" type="text/css"> | ||||||
|  | 
 | ||||||
|  | 		<style> | ||||||
|  | 		.hero { | ||||||
|  | 			background: #eee; | ||||||
|  | 			padding: 20px; | ||||||
|  | 			border-radius: 10px; | ||||||
|  | 			margin-top: 1em; | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		input,textarea { | ||||||
|  | 			border: 1px solid #ccc; | ||||||
|  | 			box-shadow: inset 0 1px 3px #ddd; | ||||||
|  | 			border-radius: 2px; | ||||||
|  | 			vertical-align: middle; | ||||||
|  | 			-webkit-box-sizing: border-box; | ||||||
|  | 			-moz-box-sizing: border-box; | ||||||
|  | 			box-sizing: border-box; | ||||||
|  | 			width: 320px; | ||||||
|  | 			max-width: 100%; | ||||||
|  | 			padding: 0.5em 0.6em; | ||||||
|  | 			margin-bottom: 0.5em; | ||||||
|  | 		} | ||||||
|  | 		</style> | ||||||
|  | 	</head> | ||||||
|  | 	<body> | ||||||
|  | 	{% include 'navbar.html' %} | ||||||
|  | 		<div class="container"> | ||||||
|  | 			<div class="row"> | ||||||
|  |     			<div class="col c6"> | ||||||
|  |     			<h1>Update description</h1> | ||||||
|  |     			<hr> | ||||||
|  |     				<form method="post" action=""> | ||||||
|  |     					<textarea name="description" id="description" rows="12">{{ description }}</textarea> | ||||||
|  | 						<input type="submit" class="btn btn-a btn-sm smooth" value="Update"> | ||||||
|  |     				</form> | ||||||
|  |     			</div> | ||||||
|  | 				<div class="col c6"> | ||||||
|  |     			<h1>Profile description</h1> | ||||||
|  |     			<hr> | ||||||
|  |     				<div class="hero"> | ||||||
|  |     					<p>{{ description }}</p> | ||||||
|  |     				</div> | ||||||
|  |     			</div> | ||||||
|  |     		</div> | ||||||
|  | 		</div> | ||||||
|  | 	</body> | ||||||
|  | </html> | ||||||
							
								
								
									
										
											BIN
										
									
								
								rc4/crypto2/wep.sqlite3
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								rc4/crypto2/wep.sqlite3
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								rc4/wep.sqlite3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								rc4/wep.sqlite3
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										4
									
								
								rc4/wsgi.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								rc4/wsgi.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | from crypto2 import app | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     app.run(host='192.168.0.12') | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user