__init__.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. from flask import Flask, g, request, render_template, redirect, current_app, send_file
  2. from flask_argon2 import Argon2
  3. from io import BytesIO
  4. import jwt
  5. import time
  6. import sqlite3
  7. import secrets
  8. app = Flask(__name__)
  9. app.config['PRIVATE_KEY'] = '''
  10. -----BEGIN RSA PRIVATE KEY-----
  11. MIICXAIBAAKBgQCo0oR5UXusQs7tvgcT5EOLB+2JaKXmmip3ViGijLHku2Y+gyas
  12. 0KFYHEQjTgz2AH1N9sUu8tzLAxn+wun28qyF3Paswmx27J/pAmbX8v6g+oGur4Jz
  13. V6ZoM5PA5iD5UvWYcLBczB84GcqhQkLHh8n/sZXP9jXMnxjTPD4nuPuQ3wIDAQAB
  14. AoGAd0s6/RdNEu6qlmifS7kS2V2ixmRCRu9NbsJYRiqxUfXyS94VKCzMthxTMbdn
  15. hTXXVY44y/IlfvcUGWfWOABHU7JK5NfWbwJfH0dU2kNEf8LzPmf1DzGy6vj01i/u
  16. 6KrSJMqJOW62NxQ1GjkvWVGgoy8RrHKzrkM7bnQ+i6JDVLECQQDX24V58LQwMmo2
  17. JDZHjEZLZlx4xQz3lzhrLOfn7B3zgspRrgufOp2SaL+nFaphUl4w8P9mo/FcDmqc
  18. R402Z4yTAkEAyDfCiZiGBgPm7mDOLiJ1Wpyc21fsF6zwoc56xSbeK+a3t9LxT00M
  19. 1W+qZv6e89erUmGNl85CwFmoyMEPdIgmBQJAOOUZp2x0cge3yxF8ZRtqI9GVKhf2
  20. NQRc0JMDhTPNKTQeE61mTs/qXH7TlTy2rfRB83ByQSGRKox6OTr6044zlQJAKuCe
  21. Hb93PESLqRM8NG8WuL//a43ptqxHoC9K5XvMapRvVcOr//KdQ/w0/veabNgMDYls
  22. vEzkyLKqzctilu8tTQJBAMXgHKX62GhH54pB4GrLLS25JpxqUNChDuPGaMPilfCW
  23. WOsFVC93MPtLA/YaAJHKZNoaXulkb5q3jhlWxCpDAKM=
  24. -----END RSA PRIVATE KEY-----
  25. '''
  26. app.config['PUBLIC_KEY'] = '''-----BEGIN PUBLIC KEY-----
  27. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo0oR5UXusQs7tvgcT5EOLB+2J
  28. aKXmmip3ViGijLHku2Y+gyas0KFYHEQjTgz2AH1N9sUu8tzLAxn+wun28qyF3Pas
  29. wmx27J/pAmbX8v6g+oGur4JzV6ZoM5PA5iD5UvWYcLBczB84GcqhQkLHh8n/sZXP
  30. 9jXMnxjTPD4nuPuQ3wIDAQAB
  31. -----END PUBLIC KEY-----'''
  32. argon2 = Argon2(app)
  33. flag1 = 'HM{sql_inj3ctions_4re_still_r3l3vant}'
  34. flag2 = 'HM{y0u_th0ught_p4ssword_ha5h1ng_is_enough?}'
  35. flag3 = 'HM{s3ssion_manag3ment_is_super_h4rd}'
  36. database = 'evilcorp.sqlite3'
  37. def check_session(cookies):
  38. if 'session' not in cookies:
  39. return False
  40. session = cookies['session']
  41. try:
  42. session_decoded = jwt.decode(session, app.config['PUBLIC_KEY'])
  43. except jwt.InvalidTokenError:
  44. return False
  45. return session_decoded
  46. def get_db():
  47. db = getattr(g, '_database', None)
  48. if db is None:
  49. db = g._database = sqlite3.connect(database)
  50. return db
  51. @app.teardown_appcontext
  52. def close_connection(exception):
  53. db = getattr(g, '_database', None)
  54. if db is not None:
  55. db.close()
  56. @app.route('/', methods=['GET'])
  57. def show_index():
  58. session = check_session(request.cookies)
  59. if session:
  60. authenticated = True
  61. username = session['user']
  62. else:
  63. authenticated = False
  64. username = None
  65. return render_template('index.html', authenticated=authenticated, username=username)
  66. @app.route('/news', methods=['GET'])
  67. def show_news():
  68. session = check_session(request.cookies)
  69. if session:
  70. authenticated = True
  71. username = session['user']
  72. else:
  73. authenticated = False
  74. username = None
  75. try:
  76. cur = get_db().execute('SELECT uid, title, body, images FROM news ORDER BY uid DESC')
  77. news = cur.fetchall()
  78. except sqlite3.Error as e:
  79. print(e)
  80. return 'Something went wrong, ping the admins'
  81. return render_template('news.html', news=news, authenticated=authenticated, username=username)
  82. @app.route('/images/<uid>', methods=['GET'])
  83. def show_image(uid):
  84. try:
  85. cur = get_db().execute('SELECT uid, name, body FROM images WHERE uid = ' + uid)
  86. image = cur.fetchone()
  87. except sqlite3.Error as e:
  88. print(e)
  89. return 'Something went wrong, ping the admins'
  90. if not image:
  91. return 'No image found'
  92. return send_file(BytesIO(image[2]), attachment_filename=image[1]+'.jpg', mimetype='image/jpg')
  93. @app.route('/login', methods=['GET'])
  94. def show_login():
  95. return render_template('login.html')
  96. @app.route('/login', methods=['POST'])
  97. def login():
  98. if 'username' not in request.form or 'password' not in request.form:
  99. return 'All fields are required!'
  100. username = request.form['username']
  101. password = request.form['password']
  102. #if not username.isalnum():
  103. # return 'Login failed'
  104. if len(password) < 6:
  105. return 'Login failed'
  106. try:
  107. cur = get_db().execute('SELECT uid, username, password FROM users WHERE username = ? LIMIT 1', (username,))
  108. cur_user = cur.fetchone()
  109. except sqlite3.Error as e:
  110. print(e)
  111. return 'Something went wrong, ping the admins'
  112. if not cur_user:
  113. return 'Login failed'
  114. if not argon2.check_password_hash(cur_user[2], password):
  115. return 'Login failed'
  116. session = jwt.encode({'user': cur_user[1], 'admin': False, 'iat': int(time.time())}, key=app.config['PRIVATE_KEY'] , algorithm='RS256')
  117. response = current_app.make_response(redirect('/user', 302))
  118. response.set_cookie('session', value=session, path='/', httponly=True)
  119. return response
  120. @app.route('/reset', methods=['GET'])
  121. def show_reset():
  122. return render_template('reset.html')
  123. @app.route('/reset', methods=['POST'])
  124. def reset():
  125. if 'email' not in request.form:
  126. return 'Email is required required!'
  127. email = request.form['email']
  128. if len(email) < 6:
  129. return 'Email too short'
  130. try:
  131. cur = get_db().execute('SELECT uid, email, username, recovered, admin FROM users WHERE email = ? LIMIT 1', (email,))
  132. cur_user = cur.fetchone()
  133. except sqlite3.Error as e:
  134. print(e)
  135. return 'Something went wrong, ping the admins'
  136. if not cur_user:
  137. return 'No user found'
  138. if cur_user[4]:
  139. return 'Nope'
  140. if cur_user[3]:
  141. return 'Password for this user has already been reset'
  142. uid = cur_user[0]
  143. token = secrets.token_hex()
  144. try:
  145. #cur = get_db().execute('UPDATE user SET recovery = ?, recovered = 1 WHERE email = ?', (token, email,))
  146. cur = get_db().execute('UPDATE users SET recovery = ? WHERE uid = ?', (token, uid,))
  147. get_db().commit()
  148. except sqlite3.Error as e:
  149. print(e)
  150. return 'Something went wrong, ping the admins'
  151. return 'Reset token sent to user email'
  152. @app.route('/reset2', methods=['POST'])
  153. def reset2():
  154. if 'email' not in request.form or 'token' not in request.form:
  155. return 'Both fields are required!'
  156. email = request.form['email']
  157. token = request.form['token']
  158. try:
  159. cur = get_db().execute('SELECT * FROM users WHERE recovery = ? AND email = ? AND recovered != 1', (token, email,))
  160. cur_user = cur.fetchone()
  161. except sqlite3.Error as e:
  162. print(e)
  163. return 'Something went wrong, ping the admins'
  164. if not cur_user:
  165. return 'Wrong email or token or password already reset one time'
  166. else:
  167. newpassword = secrets.token_urlsafe(16)
  168. try:
  169. cur = get_db().execute('UPDATE users SET password = ?, recovered = 1 WHERE recovery = ? AND email = ?', (argon2.generate_password_hash(newpassword), token, email,))
  170. get_db().commit()
  171. except sqlite3.Error as e:
  172. print(e)
  173. return 'Something went wrong, ping the admins'
  174. return 'Your new password is ' + newpassword
  175. @app.route('/user', methods=['GET'])
  176. def show_user():
  177. session = check_session(request.cookies)
  178. if not session:
  179. return redirect('/login', 302)
  180. else:
  181. if not session['admin']:
  182. return render_template('user.html', authenticated=True, username=session['user'], flag2=flag2)
  183. return 'Good job! Here\'s the last flag: ' + flag3
  184. @app.route('/logout', methods=['GET'])
  185. def logout():
  186. response = current_app.make_response(redirect('/', 302))
  187. for cookie in request.cookies:
  188. response.set_cookie(cookie, value='', expires=0)
  189. return response
  190. @app.route('/robots.txt', methods=['GET'])
  191. def show_robots():
  192. return 'Disallow: /pub.asc'
  193. @app.route('/pub.asc', methods=['GET'])
  194. def show_pubkey():
  195. return app.config['PUBLIC_KEY']
  196. if __name__ == "__main__":
  197. app.run(host='0.0.0.0', port=7000)