__init__.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. from flask import Flask, g, request, render_template, redirect, current_app
  2. from uuid import uuid4
  3. from flask_argon2 import Argon2
  4. from Crypto.Cipher import ARC4
  5. from binascii import hexlify, unhexlify
  6. import sqlite3
  7. import json
  8. import secrets
  9. app = Flask(__name__)
  10. argon2 = Argon2(app)
  11. flag = 'HM{h3r35_y0ur_2time_p4d}'
  12. database = 'wep.sqlite3'
  13. def get_db():
  14. db = getattr(g, '_database', None)
  15. if db is None:
  16. db = g._database = sqlite3.connect(database)
  17. return db
  18. @app.teardown_appcontext
  19. def close_connection(exception):
  20. db = getattr(g, '_database', None)
  21. if db is not None:
  22. db.close()
  23. def check_session(cookies):
  24. if 'session' not in cookies and 'iv' not in cookies or 'uid' not in cookies:
  25. return False
  26. try:
  27. cur = get_db().execute('SELECT uid, username, iv, key FROM users WHERE uid = ? AND iv = ? LIMIT 1', (cookies['uid'], cookies['iv']))
  28. cur_user = cur.fetchone()
  29. except sqlite3.Error as e:
  30. print(e)
  31. return 'Something went wrong, ping the admins'
  32. if not cur_user:
  33. return False
  34. uid = cur_user[0]
  35. username = cur_user[1]
  36. iv = cur_user[2]
  37. key = cur_user[3]
  38. cipher = ARC4.new(bytes(iv) + key)
  39. try:
  40. plaintext = cipher.decrypt(unhexlify(cookies['session']))
  41. session = json.loads(plaintext)
  42. except:
  43. return False
  44. session['key'] = key
  45. session['iv'] = iv
  46. return session
  47. @app.route('/', methods=['GET'])
  48. def index():
  49. return render_template('index.html')
  50. @app.route('/register', methods=['GET'])
  51. def show_register():
  52. return render_template('register.html')
  53. @app.route('/register', methods=['POST'])
  54. def register():
  55. if 'username' not in request.form or 'password' not in request.form or 'password2' not in request.form:
  56. return 'All fields are required!'
  57. username = request.form['username']
  58. password = request.form['password']
  59. password2 = request.form['password2']
  60. if not username.isalnum():
  61. return 'Username must be alphanumeric'
  62. if password != password2:
  63. return 'Password confirmation does not match'
  64. if len(password) < 6:
  65. return 'Password must be at least 6 chars!'
  66. try:
  67. cur = get_db().execute('SELECT username FROM users WHERE username= ? LIMIT 1', (username,))
  68. cur_user = cur.fetchone()
  69. except:
  70. return 'Something went wrong, ping the admins'
  71. if cur_user:
  72. return 'Username already exist'
  73. try:
  74. cur.execute('INSERT INTO users (uid, username, password, iv, key) VALUES(?, ?, ?, 0, ?)', (str(uuid4()), username, argon2.generate_password_hash(password), secrets.token_bytes(16),))
  75. get_db().commit()
  76. except sqlite3.Error as e:
  77. print(e)
  78. return 'Something went wrong, ping the admins'
  79. return redirect('/login', 302)
  80. @app.route('/login', methods=['GET'])
  81. def show_login():
  82. return render_template('login.html')
  83. @app.route('/login', methods=['POST'])
  84. def login():
  85. if 'username' not in request.form or 'password' not in request.form:
  86. return 'All fields are required!'
  87. username = request.form['username']
  88. password = request.form['password']
  89. if not username.isalnum():
  90. return 'Login failed'
  91. if len(password) < 6:
  92. return 'Login failed'
  93. try:
  94. cur = get_db().execute('SELECT uid, username, password, iv, key FROM users WHERE username = ? LIMIT 1', (username,))
  95. cur_user = cur.fetchone()
  96. except sqlite3.Error as e:
  97. print(e)
  98. return 'Something went wrong, ping the admins'
  99. if not cur_user:
  100. return 'Login failed'
  101. if not argon2.check_password_hash(cur_user[2], password):
  102. return 'Login failed'
  103. uid = cur_user[0]
  104. username = cur_user[1]
  105. iv = cur_user[3]+1
  106. key = cur_user[4]
  107. if iv >= 255:
  108. iv = 0
  109. data = {
  110. 'username': username,
  111. 'description': 'No description yet',
  112. 'show_flag': False
  113. }
  114. cipher = ARC4.new(bytes(iv) + key)
  115. try:
  116. ciphertext = cipher.encrypt(json.dumps(data).encode('ascii')).hex()
  117. except:
  118. return 'Something went wrong, ping the admins'
  119. try:
  120. get_db().execute('UPDATE users SET iv = ? WHERE username = ?', (iv, username,))
  121. get_db().commit()
  122. except sqlite3.Error as e:
  123. print(e)
  124. return 'Something went wrong, ping the admins'
  125. response = current_app.make_response(redirect('/user', 302))
  126. response.set_cookie('session', value=str(ciphertext), path='/', httponly=True)
  127. response.set_cookie('uid', value=uid, path='/', httponly=True)
  128. response.set_cookie('iv', value=str(iv), path='/', httponly=True)
  129. return response
  130. @app.route('/user', methods=['GET'])
  131. def show_user():
  132. session = check_session(request.cookies)
  133. if not session:
  134. return redirect('/login', 302)
  135. if session['show_flag']:
  136. return flag
  137. return render_template('user.html', authenticated=True, username=session['username'], description=session['description'])
  138. @app.route('/user', methods=['POST'])
  139. def user():
  140. session = check_session(request.cookies)
  141. if not session:
  142. return redirect('/login', 302)
  143. if session['show_flag']:
  144. return flag
  145. if 'description' not in request.form:
  146. return 'Description field is mandatory!'
  147. description = request.form['description']
  148. if len(description) < 10 or len(description) > 200:
  149. return 'Description either too short (<10) or too long (>200)'
  150. username = session['username']
  151. key = session['key']
  152. iv = session['iv']+1
  153. if iv >= 255:
  154. iv = 0
  155. data = {
  156. 'username': username,
  157. 'description': description,
  158. 'show_flag': False
  159. }
  160. cipher = ARC4.new(bytes(iv) + key)
  161. try:
  162. ciphertext = cipher.encrypt(json.dumps(data).encode('ascii')).hex()
  163. except:
  164. return 'Something went wrong, ping the admins'
  165. try:
  166. get_db().execute('UPDATE users SET iv = ? WHERE username = ?', (iv, username,))
  167. get_db().commit()
  168. except sqlite3.Error as e:
  169. print(e)
  170. return 'Something went wrong, ping the admins'
  171. response = current_app.make_response(redirect('/user', 302))
  172. response.set_cookie('session', value=str(ciphertext), path='/', httponly=True)
  173. response.set_cookie('iv', value=str(iv), path='/', httponly=True)
  174. return response
  175. return render_template('user.html', authenticated=True, username=session['username'], description=session['description'])
  176. @app.route('/logout', methods=['GET'])
  177. def logout():
  178. response = current_app.make_response(redirect('/', 302))
  179. for cookie in request.cookies:
  180. response.set_cookie(cookie, value='', expires=0)
  181. return response
  182. if __name__ == "__main__":
  183. app.run(host='0.0.0.0')