From 7573f1769f1e24ed1d9ba6c2d4ef19b1d8070265 Mon Sep 17 00:00:00 2001 From: minhtrannhat Date: Mon, 19 Aug 2024 04:18:28 -0400 Subject: [PATCH] feat(server): Setup basic Echo QUIC server - Generated server private key, Certificate Signing Request (CSR) and self-signed certificate. --- README.md | 19 +++++++++++ requirements.txt | 29 +++++++++++++++++ server.crt | 23 +++++++++++++ server.csr | 18 +++++++++++ server.key | 28 ++++++++++++++++ src/quic_reflection_attack/__init__.py | 0 src/quic_reflection_attack/server.py | 45 ++++++++++++++++++++++++++ 7 files changed, 162 insertions(+) create mode 100644 README.md create mode 100644 requirements.txt create mode 100644 server.crt create mode 100644 server.csr create mode 100644 server.key create mode 100644 src/quic_reflection_attack/__init__.py create mode 100644 src/quic_reflection_attack/server.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..16bb9f8 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# QUIC Reflection Attack Simulation + +Tested on the Python 3.12 + +## Goals + +- Learn about the basics of the QUIC protocol and the python `aioquic` library. + +## Setup + +- Install Python3.12 and Pip +- Consider using a python virtual environment +- Run `pip install -r requirements.txt` + +## Progress + +- [ ] Server implementation +- [ ] Client (Victim) implementation +- [ ] Client (Bad Actor) implementation diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e187cd7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,29 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile - -o requirements.txt +aioquic==1.2.0 +attrs==24.1.0 + # via service-identity +certifi==2024.7.4 + # via aioquic +cffi==1.16.0 + # via cryptography +cryptography==43.0.0 + # via + # aioquic + # pyopenssl + # service-identity +pyasn1==0.6.0 + # via + # pyasn1-modules + # service-identity +pyasn1-modules==0.4.0 + # via service-identity +pycparser==2.22 + # via cffi +pylsqpack==0.3.18 + # via aioquic +pyopenssl==24.2.1 + # via aioquic +service-identity==24.1.0 + # via aioquic +uvloop==0.20.0 diff --git a/server.crt b/server.crt new file mode 100644 index 0000000..80ba07d --- /dev/null +++ b/server.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID6TCCAtGgAwIBAgIUA6R0Oohkukp0PbSKG2yCqBv7YL0wDQYJKoZIhvcNAQEL +BQAwgZsxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1v +bnRyZWFsMRMwEQYDVQQKDApNaW5oVHJhbkxUMRowGAYDVQQLDBFRdWljUmVmbGVj +dGlvbkF0azERMA8GA1UEAwwITWluaFRyYW4xJDAiBgkqhkiG9w0BCQEWFW1pbmhA +bWluaHRyYW5uaGF0LmNvbTAgFw0yNDA4MTgxOTAwNTBaGA8zMDEwMDQxMjE5MDA1 +MFowgZsxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1v +bnRyZWFsMRMwEQYDVQQKDApNaW5oVHJhbkxUMRowGAYDVQQLDBFRdWljUmVmbGVj +dGlvbkF0azERMA8GA1UEAwwITWluaFRyYW4xJDAiBgkqhkiG9w0BCQEWFW1pbmhA +bWluaHRyYW5uaGF0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AMbS8p4wjNHUfnGc8sGdBRIEOMHQ+/QCtKnltgkt0i3fVfl0x9iMsORQjayLvJRJ +zgfA7yO6bpIVM4XfJavIxSyLCZT7uHEYWPfzNmvGHiOhdr9wuI6XMbeDDEU09t1A +pYWA+yiW6yDWQcg3fKA4DsmMFP5ebHPtDO+Wz3jtRkatynCD9AsAxqPmy7v/ruBB +sELyVvFGORDUk5po2OSrRb7Awlkwx2LhkhMYH7pNXmkJYbSjc8k0krWcQQLU7c17 +c81PQvmb7Co9I6hVqZ0yxzmJ8G+EWtJSEdPNGLO8dUkvH6tmWZNgb2RMB3QMRsJF +LDFu0bt3OI/wwDrSwfU3dykCAwEAAaMhMB8wHQYDVR0OBBYEFPQrcuSoVRkrKJlZ +Beg7I2ssQpf1MA0GCSqGSIb3DQEBCwUAA4IBAQA/fuJy0ROp2zd2F8fKaoteC/7f +GQmd9AGPqdpuadxxFaOgpX2Skrf42p4GgPalPr2D7YZOxhmraSFWVHlSSxrSjiK0 +fpLE8SGvL8ioGiFwiMza+m9+lOYdN1oPiHLFnklkRGIjAK09HCe3bYdhyOpCSYD9 +ANqTAUNG1KN0PKFK+VoAK188fdbTF6vDc1PEVo/ManEeNzLIc/KModme264NJQhE +h4q21gbVaH+DdwpMZP29E+FLiOo+27BI1cwWyofv763BzWsZzwqGP3sK9vz6l8CK +giNruYNoQ/5Nd2xkB86sOdaryl6FYTCyr3p+oqGcfao5r0PY1B7ZYrFFhb6W +-----END CERTIFICATE----- diff --git a/server.csr b/server.csr new file mode 100644 index 0000000..b3aaff4 --- /dev/null +++ b/server.csr @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIC9jCCAd4CAQAwgZsxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxETAP +BgNVBAcMCE1vbnRyZWFsMRMwEQYDVQQKDApNaW5oVHJhbkxUMRowGAYDVQQLDBFR +dWljUmVmbGVjdGlvbkF0azERMA8GA1UEAwwITWluaFRyYW4xJDAiBgkqhkiG9w0B +CQEWFW1pbmhAbWluaHRyYW5uaGF0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMbS8p4wjNHUfnGc8sGdBRIEOMHQ+/QCtKnltgkt0i3fVfl0x9iM +sORQjayLvJRJzgfA7yO6bpIVM4XfJavIxSyLCZT7uHEYWPfzNmvGHiOhdr9wuI6X +MbeDDEU09t1ApYWA+yiW6yDWQcg3fKA4DsmMFP5ebHPtDO+Wz3jtRkatynCD9AsA +xqPmy7v/ruBBsELyVvFGORDUk5po2OSrRb7Awlkwx2LhkhMYH7pNXmkJYbSjc8k0 +krWcQQLU7c17c81PQvmb7Co9I6hVqZ0yxzmJ8G+EWtJSEdPNGLO8dUkvH6tmWZNg +b2RMB3QMRsJFLDFu0bt3OI/wwDrSwfU3dykCAwEAAaAVMBMGCSqGSIb3DQEJBzEG +DARlY2hvMA0GCSqGSIb3DQEBCwUAA4IBAQChwKgKdLGzkO0Towus06ioPDfy7nAz +cVjlA8HTHx7GURbBElCOwXEot78t3UOgLHlJYQ9J9v/8w0rKmby3WmjV1pwmZoZH +Scef1DYhpYvPSGHpEaPHdvDx+tOoa7x2AvLgzMrdJZui2wVbmRUmXfdb8v8ZjK12 +7e/IifMK2dLc/U4csf7VkS/+WmuuE/4C3eaA0F6nBzkdB2ecwZbWelzTNLVf/u7h +a3XTFbFIrd7RU2kbDuU0o/5K5nrvx4ZHZzeaTy+hVVY1R5WwEITnb3/mxY3OvkfH +cNcXtYTr2Fp+Uw7YIPKSDGv7EXnCHErYzmNOP3OazWT+aAYPbzwa4ACN +-----END CERTIFICATE REQUEST----- diff --git a/server.key b/server.key new file mode 100644 index 0000000..77698ed --- /dev/null +++ b/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDG0vKeMIzR1H5x +nPLBnQUSBDjB0Pv0ArSp5bYJLdIt31X5dMfYjLDkUI2si7yUSc4HwO8jum6SFTOF +3yWryMUsiwmU+7hxGFj38zZrxh4joXa/cLiOlzG3gwxFNPbdQKWFgPsolusg1kHI +N3ygOA7JjBT+Xmxz7Qzvls947UZGrcpwg/QLAMaj5su7/67gQbBC8lbxRjkQ1JOa +aNjkq0W+wMJZMMdi4ZITGB+6TV5pCWG0o3PJNJK1nEEC1O3Ne3PNT0L5m+wqPSOo +VamdMsc5ifBvhFrSUhHTzRizvHVJLx+rZlmTYG9kTAd0DEbCRSwxbtG7dziP8MA6 +0sH1N3cpAgMBAAECggEACDWZkvKKPfe6KNLEKz5igTXvagFJBfA+qW00sPhVX1OD +Z0NtJQHaI/M3hlJWvQC3IxbSSPVfr2R0tihak9c8XPR4ttAV84V/1u0R6C1L/Uij +cJAk7q5LfTpJ/WmMb+JFc1e6BxkEKFzwZmX0HWFzKts/2qjnbXnyOMpPUrzpU+2y +b+Y+o8FW3RRCvxADm5U4YrQPaJsObScduK9xxK95RoTvp27oXtu7vL2MqCZbucbQ +lua4u29T5U5XKGIqd8G7UTsj2nXVFArqXGG0N0CIQnyqbNGLrrpAd9FuyJeXnsgP +xBh2H+CcXBsDrqqfk45pzme76dQRN9SDsfFy7CIESQKBgQDt8XQDivYYOh+syF58 +OYKjrqEEoaBQQkqY8m48KbopnRmPHiy7JbWM7wWsEWDgItGtATBDvPPzx6FnhqJO +80S0VD0P91a4WUy7a1A1SQvyI9ZUaJVEsWHQY5lzMmU3NJHeYo/lovtQ3h5DgNL8 +gHpCgSxmUKT48CsrZikDf0BZCwKBgQDV6YXECThpT/BikDkRxF+w0fUqg6L5P4pG +W857y6n4j5BKFwNPPbrREEXI1RpLLM/8D0gVKlS9hYOamWZiH6J+3I1FltRJxrju +Q9OiyKI+MErj+bEq6nPVA8tV2IfZYsmq2S7K8XXvuMG/QAOIHIT3O/B2Plvk0DwS +O6yAD7QZGwKBgBwuZsEsqi0AZVP/f0FTRmfAfQ2hXu1ijJdEz02M26GmG6rZtg6M +Ts5cWN2iSUkClrbY1zCOpo4O7MzoIz0ajt6Uw46qirjWysG/2gYVmraZC/9/S36R +S7Z0tW3xYA+DyGsAXW6jOQTA6fCwx0xkoxZRWkLb9k4Nk+9V8DGb1rE1AoGAD99v +JJfGjtH2tWmcQnw+2YEK3ye7bSFQ4l2nmboIF8CXZVgFz9h1x1OcygU+GTvvBvYf +VCq69QE2Pb+KQFe2mBFHjlVd1Uegq1VvG9Ilb9XniLkbc2LIS5MngGw70F6rNjk9 +ZqO6K5qbDdTzLiNnnmzdL/j6mqT1AClbaHlB1OcCgYA/qlAHtzVpHWeWg8UtNNjW +S5Mfdcld/wIy0T1dsw7ha8PPnwHU2aSydCrqIdyw4Ol0AuGNUsq+qpdfKHdyD/Li +7JxfTFUSXuqbzC6odFXZBZNBtphHUyvVwk4QybRXMVMVPIvOkvebij2kTiRanTjZ +jUp2nUaVQw4kDaiECn6NXQ== +-----END PRIVATE KEY----- diff --git a/src/quic_reflection_attack/__init__.py b/src/quic_reflection_attack/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/quic_reflection_attack/server.py b/src/quic_reflection_attack/server.py new file mode 100644 index 0000000..fb4821f --- /dev/null +++ b/src/quic_reflection_attack/server.py @@ -0,0 +1,45 @@ +import asyncio +from typing import Optional +import uvloop + +from aioquic.quic.configuration import QuicConfiguration +from aioquic.quic.connection import QuicConnection +from aioquic.quic.events import QuicEvent, StreamDataReceived +from aioquic.asyncio import serve # type: ignore + + +class QuicServerProtocol: + def __init__(self): + self.quic: Optional[QuicConnection] = None + + def quic_event_received(self, event: QuicEvent) -> None: + if isinstance(event, StreamDataReceived): + print(f"Received data on stream {event.stream_id}: {event.data.decode()}") + + assert self.quic is not None, "QUIC Connection is not initialized" + + # Echo the received data back to the client + self.quic.send_stream_data(event.stream_id, event.data) + + +async def main(): + configuration = QuicConfiguration( + is_client=False, + alpn_protocols=["quic-echo"], # our own custome ALPN protocol + ) + + # Load your SSL certificate and private key + configuration.load_cert_chain("server.crt", "server.key") # type: ignore + + await serve( + "localhost", + 8000, + configuration=configuration, + create_protocol=QuicServerProtocol, + ) + + await asyncio.Future() # Run forever + + +if __name__ == "__main__": + uvloop.run(main())