Skip to content

Quick Start Examples

M Amin Nasiri edited this page Aug 12, 2024 · 24 revisions

Scapy  

Examples

In this wiki you can see some examples for working with this library.

Improved Version of Single Packet Attack (Black Hat 2024)

See This Page

Connection Setup

Before anything to do, you have to set up the connection and then work with different methods.

from h2spacex import H2OnTlsConnection

h2_conn = H2OnTlsConnection(
    hostname='http2.github.io',
    port_number=443
)

h2_conn.setup_connection()

For changing default Settings fields which the library sends, see this part.

Disable Logging (Printing)

to avoid printing some stuff and errors, you can do this technique:

  1. just add this to first line of your code:

       from h2spacex import logger
       logger.be_silent_key = True
    

also avoid using show_response_of_sent_requests function because it prints the responses!

Single Packet Attack on GET Requests (Requests without Body)

See GET-SPA-Methods

Single Packet Attack on POST Requests (Requests with Body)

Steps:

  1. Setup Connection
    1. You can parse response frames manually (Recommended Method)
    2. Or you can parse response frames automatically by using start_thread_response_parsing method (Not Ready Yet)
  2. Define Headers & Body for Requests
  3. Generate Stream IDs to Invoke Requests
  4. Create Header Frames & Data Frame Containing Last Byte
  5. Concatenate Header Frames (All frames except the last-byte for each request)
  6. Concatenate Data Frames (All frames which have last-byte for previous requests)
  7. Send Concatenated Header Frames
  8. Wait Some time (any scenario you have)
  9. Send Ping Frame (warming up connection)
  10. Send Concatenated Data Frames
  11. Parse the Response & Hopefully Get a Successful Race Condition on H2
  12. Close the Connection
from h2spacex import H2OnTlsConnection
from time import sleep
from h2spacex import h2_frames

h2_conn = H2OnTlsConnection(
    hostname='http2.github.io',
    port_number=443
)

h2_conn.setup_connection()

headers = """accept: */*
content-type: application/x-www-form-urlencoded
...
"""

body = """BODY
DATA...
...
"""
stream_ids_list = h2_conn.generate_stream_ids(number_of_streams=5)

all_headers_frames = []  # all headers frame + data frames which have not the last byte
all_data_frames = []  # all data frames which contain the last byte

for s_id in stream_ids_list:

    header_frames_without_last_byte, last_data_frame_with_last_byte = h2_conn.create_single_packet_http2_post_request_frames(
        method='POST',
        headers_string=headers,
        scheme='https',
        stream_id=s_id,
        authority="http2.github.io",
        body=body,
        path='/somePath'
    )
    
    all_headers_frames.append(header_frames_without_last_byte)
    all_data_frames.append(last_data_frame_with_last_byte)
    
# concatenate all headers bytes
temp_headers_bytes = b''
for h in all_headers_frames:
    temp_headers_bytes += bytes(h)

# concatenate all data frames which have last byte
temp_data_bytes = b''
for d in all_data_frames:
    temp_data_bytes += bytes(d)    

# send header frames
h2_conn.send_frames(temp_headers_bytes)

# wait some time
sleep(0.1)

# send ping frame to warm up connection
h2_conn.send_ping_frame()

# send remaining data frames
h2_conn.send_frames(temp_data_bytes)

# parse response frames
resp = h2_conn.read_response_from_socket(_timeout=3)
frame_parser = h2_frames.FrameParser(h2_connection=h2_conn)
frame_parser.add_frames(resp)
frame_parser.show_response_of_sent_requests()

# close the connection to stop response parsing and exit the script
h2_conn.close_connection()

Parse Response Manually (Recommended Method)

Except using start_thread_response_parsing method, you can use this technique when you sent all of your requests:

Send all requests
.
.
# parse response frames
resp = h2_conn.read_response_from_socket(_timeout=3)
frame_parser = h2_frames.FrameParser(h2_connection=h2_conn)
frame_parser.add_frames(resp)
frame_parser.show_response_of_sent_requests()

Parse Response (Threaded) + Response Times for Timing Attacks

You have to use this method to get response times in nano seconds:

  • Use start_thread_response_parsing() method after setting up the connection or after sending your requests:
...IMPORTS...

h2_conn = H2OnTlsConnection(
    hostname='http2.github.io',
    port_number=443
)

h2_conn.setup_connection()

# ...Send Requests with Single Packet Attack Technique...

h2_conn.start_thread_response_parsing(_timeout=3)
while not h2_conn.is_threaded_response_finished:
    sleep(1)

if h2_conn.is_threaded_response_finished is None:
    print('Error has occurred!')
    exit()

frame_parser = h2_conn.threaded_frame_parser

h2_conn.close_connection()

for x in frame_parser.headers_and_data_frames.keys():
    d = frame_parser.headers_and_data_frames[x]
    print(f'Stream ID: {x}, response nano seconds: {d["nano_seconds"]}')

Change the Default Client Settings

For changing default Settings, before setting up the connection, you can use this method:

h2_conn = H2OnTlsConnection(
    hostname='nxenon.ir',
    port_number=443
)
# change the library default value
h2_conn.DEFAULT_SETTINGS['SETTINGS_MAX_CONCURRENT_STREAMS']['value'] = 100
# you can also change other Settings values
.
h2_conn.setup_connection()

To avoid sending a Setting at all, just set the value of that Settings to None.

Default Settings Keys & Values

DEFAULT_SETTINGS = {
   'SETTINGS_HEADER_TABLE_SIZE': {
       'id': 1,
       'value': 4096
   },
   'SETTINGS_ENABLE_PUSH': {
       'id': 2,
       'value': 0
   },
   'SETTINGS_MAX_CONCURRENT_STREAMS': {
       'id': 3,
       'value': 100
   },
   'SETTINGS_INITIAL_WINDOW_SIZE': {
       'id': 4,
       'value': 65535
   },
   'SETTINGS_MAX_FRAME_SIZE': {
       'id': 5,
       'value': 16384
   },
   'SETTINGS_MAX_HEADER_LIST_SIZE': {
       'id': 6,
       'value': None  # this Setting will not be sent, bcs its value is None
   },
}

Proxy Example

h2_conn = H2OnTlsConnection(
    hostname='http2.github.io',
    port_number=443,
    proxy_hostname='127.0.0.1',
    proxy_port_number=10808
)

TODO

  • Single Packet Attack - POST &...
    • implement
  • Single Packet Attack - GET
    • Remove END_STREAM flag
    • Content-Length: 1 Method
    • POST Request with x-override-method: GET header
  • Response Parsing
    • implement
    • implement threaded response parser
    • Body Decompression
      • gzip
      • br
      • deflate
  • Proxy
    • Socks5 Proxy
Clone this wiki locally