#!/usr/bin/env python3 ''' Sample password reset process which is vulnerable to padding oracle attacks Copyright (C) 2016-2017 Blindspot Security LLC Author: Timothy D. Morgan This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ''' import http.server import tokenutils listen_ip = '127.0.0.1' listen_port = 8888 class MyHandler(http.server.BaseHTTPRequestHandler): def do_HEAD(s): s.send_response(200) s.send_header("Content-type", "text/html") s.end_headers() def do_GET(s): if s.path.startswith('/generate-reset-token'): s.send_response(200) s.send_header("Content-Type", "text/html; charset=utf-8") s.end_headers() s.wfile.write(b"Reset Your Password") s.wfile.write(b"") user = s.path.split('user=')[1] url = 'http://%s:%d/reset-password?token=%s' % (listen_ip,listen_port,tokenutils.generateResetToken(user)) s.wfile.write(('

If this were a real application, we would have emailed the user "%s" the following URL so they could reset their password:

' % user).encode('utf-8')) s.wfile.write(('%s' % (url,url)).encode('utf-8')) s.wfile.write(b"") elif s.path.startswith('/reset-password'): token = s.path.split('token=')[1] result,info = tokenutils.validateResetToken(token) if result: s.send_response(200) s.send_header("Content-type", "text/html; charset=utf-8") s.end_headers() s.wfile.write(b"Reset Your Password") s.wfile.write(("

Hello %s, you may now reset your password:

" % info['user']).encode('utf-8')) s.wfile.write(b"

New password:

") s.wfile.write(b"

Verify password:

") s.wfile.write(b"

") s.wfile.write(b"") else: s.send_response(200) s.send_header("Content-type", "text/html; charset=utf-8") s.end_headers() s.wfile.write(b"Reset Your Password") s.wfile.write(b"

Oops! There was a problem with your reset token

") s.wfile.write(b"

ERROR: %s

" % info.encode('utf-8')) s.wfile.write(("

Please return here to try again.

" % (listen_ip,listen_port)).encode('utf-8')) s.wfile.write(b"") else: s.send_response(404) s.send_header("Content-type", "text/html; charset=utf-8") s.end_headers() s.wfile.write(b"Not Found") s.wfile.write(b"

Greetings traveler. We think you want to start at ") s.wfile.write(("this page.

" % (listen_ip,listen_port)).encode('utf-8')) s.wfile.write(b"") if __name__ == '__main__': httpd = http.server.HTTPServer((listen_ip, listen_port), MyHandler) try: httpd.serve_forever() except KeyboardInterrupt: pass httpd.server_close()