├── README.md └── websocket-harness.py /README.md: -------------------------------------------------------------------------------- 1 | This python script can be placed between traditional web penetration testing tools and WebSocket connections, which does translation from HTTP to WebSocket and back. Think of it like a fuzzing harness that is used for native code. 2 | 3 | Example: python websocket-harness.py -p 8000 -u ws://dvws.local:8080/authenticate-user 4 | 5 | In the example above, the WebSocket harness will listen on local loopback, and forward any HTTP POST requests to the target WebSocket endpoint (ws://dvws.local:8080/authenticate-user). 6 | 7 | Happy bug hunting! 8 | -------------------------------------------------------------------------------- /websocket-harness.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import socket,ssl 3 | import argparse 4 | import os 5 | from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer 6 | from websocket import create_connection, WebSocket 7 | from SocketServer import ThreadingMixIn 8 | import threading 9 | import websocket 10 | 11 | class WSWebServer(BaseHTTPRequestHandler): 12 | 13 | # Handler for POST requests 14 | def do_POST(self): 15 | content_len = int(self.headers.getheader('content-length', 0)) 16 | post_fuzz_body = self.rfile.read(content_len) 17 | fuzz_result = FuzzWebSocket(post_fuzz_body) 18 | self.send_response(200) 19 | self.send_header('Content-type','text/html') 20 | self.end_headers() 21 | self.wfile.write(fuzz_result) 22 | return 23 | 24 | # Handler for the GET requests 25 | def do_GET(self): 26 | self.send_response(200) 27 | self.send_header('Content-type','text/html') 28 | self.end_headers() 29 | self.wfile.write("WebSocket Fuzzing Harness: Please use POST request!") 30 | return 31 | 32 | class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): 33 | """Handle requests in a separate thread.""" 34 | 35 | def FuzzWebSocket(fuzz_payload): 36 | # send and recieve a request 37 | try: 38 | ws.send(fuzz_payload) 39 | fuzz_result = ws.recv() 40 | return fuzz_result 41 | except websocket.WebSocketConnectionClosedException as e: 42 | print 'Error:',e.args 43 | 44 | parser = argparse.ArgumentParser(description='Web Socket Harness: Use traditional pentest tools to assess web sockets') 45 | parser.add_argument('-u','--url', help='The remote WebSocket URL to target. Example: ws://127.0.0.1:8000/method-to-fuzz.', required=True) 46 | parser.add_argument('-p','--port', help='The port to bind to.', required=True, default=8000) 47 | args = parser.parse_args() 48 | 49 | ws = create_connection(args.url,sslopt={"cert_reqs": ssl.CERT_NONE},header={},http_proxy_host="", http_proxy_port=8080) 50 | 51 | try: 52 | # Setting up web harness/proxy server 53 | server = ThreadedHTTPServer(('', int(args.port)), WSWebServer) 54 | print 'WebSocket Harness: Successful bind on port', args.port 55 | 56 | # Wait forever for incoming http requests 57 | server.serve_forever() 58 | 59 | except KeyboardInterrupt: 60 | print 'WebSocket Harness: Exit command recieved. Shutting down...' 61 | server.socket.close() 62 | ws.close() 63 | --------------------------------------------------------------------------------