-----------
QuicDraw(H3): HTTP/3 Fuzzing and Racing (Client)
-----------
_ _
(_) | | ______
__ _ _ _ _ ___ __| |_ __ __ ___ __ /\ /\___ /
/ _` | | | | |/ __/ _` | '__/ _` \ \ /\ / / / /_/ / |_ \
| (_| | |_| | | (_| (_| | | | (_| |\ V V / / __ / ___) |
\__, |\__,_|_|\___\__,_|_| \__,_| \_/\_/ \/ /_/ |____/
|_| _______
\ |QFS____| -------------------- HTTP/3
\ |_//
|_|
GitHub: https://github.com/cyberark/QuicDrawH3
License: Apache-2.0 License
Author: Maor Abutbul <CyberArk Labs>
-----------QuicDraw is a security research tool designed for fuzzing and racing HTTP/3 servers.
QuicDraw implements the Quic-Fin-Sync on HTTP/3 (over QUIC), for race-condition testing.
The tool was originally published as part of CyberArk Labs' research: "Racing and Fuzzing HTTP/3: Open-sourcing QuicDraw(H3)"
- Implements the
Quic-Fin-Syncon HTTP3 (over QUIC), for race-condition testing. - Supports fuzzing multiple requests with the
FUZZand wordlist (-wargument) mechanisms. - Custom HTTP headers functionality (
-Hargument).- Note: Custom headers are converted to lowercase since we have seen issues with some server implementations.
- Supports SSLKEYLOGFILE (
-largument) for TLS decryption/inspection via packet analyzers such as Wireshark. - Based on aioquic (http3_client)
- aioquic is a library for the QUIC network protocol in Python.
- It features a minimal TLS 1.3 implementation, a QUIC stack, and an HTTP/3 stack.
Prerequisite:
- python >=3.9
- pip3
The easiest way to install QuicDraw is to run:
pip install quicdrawquicdraw -hIf there are no wheels for your system or if you wish to build QuicDraw from source.
Clone the repository:
git clone https://github.com/cyberark/quicdrawh3.git
python3 -m build
pip install .\dist\quicdraw-<VERSION>.tar.gzInstall module dependencies. (You may prefer to do this within a Virtual Environment)
quicdraw -hquicdraw <https://http3_server.com/path>HTTP POST requests are determined by using the -d argument followed by the HTTP POST data to be sent.
quicdraw <https://http3_server.com/path> -d '{"key":"value"}'log secrets to a file, for use with Wireshark
To inspect the traffic in wireshark: Open Wireshark → Edit → Preferences → Protocols → TLS and set “(Pre)-Master-Secret log filename” to the full path of secrets.log
Using the verbose (-v) output will log (print) the request data to be sent and the HTTP response content.
In the case of GET requests (no -d argument supplied), the request URL (:path) will be logged (printed).
To use the same request multiple times (using the Quic-Fin-Sync / single-packet), use the -tr/--total-requests argument.
Note: If a WORDLIST (-w) argument is specified, this argument (-tr TOTAL_REQUESTS) is overridden by the wordlist number of lines.
quicdraw <https://http3_server.com/path> -d '{"key":"value"}' -H 'Authorization: bearer eyJ...' -tr 12quicdraw <https://http3_server.com/path> -d '{"key":"value"}' -H 'Authorization: bearer eyJ...' -H 'content-type: application/json' -l /m2a/ssl_key_log_file.log -tr 12Repeat the same request 12 times (-tr 12), use Quic-Fin-Sync, log (-l) TLS secrets, and print verbose (-v) output including HTTP response content
quicdraw <https://http3_server.com/path> -d '{"key": "value"}' -H 'Authorization: bearer eyJ...' -H 'content-type: application/json' -l /m2a/ssl_key_log_file.log -tr 12 -vFuzzing in QuicDraw is based on a simple concept, like other web fuzzers (Ffuf, Wfuzz),
go over the data section (-d), and replace any reference to the FUZZ keyword with the value given in the wordlist (-w) as the payload.
To define fuzzing, use the wordlist (-w/--wordlist) argument with the FUZZ keyword anywhere in the DATA (-d argument) section.
Note: If the payload (-d) does not include the FUZZ keyword, the same data will be sent according to the number of lines in the wordlist file.
Use Quic-Fin-Sync, go over the data section (-d), and replace any reference to the FUZZ keyword with the value given in the wordlist file (-w) as the payload
quicdraw <https://http3_server.com/path> -w path/to/wordlist -d '{"example_key":"FUZZ"}'We welcome contributions of all kinds to this repository. For instructions on how to get started and descriptions of our development workflows, please see our contributing guide
- The
Quic-Fin-Syncis mostly effective in POST requests (using the-dargument).- GET requests will benefit from the mechanism, but according to our tests, only a few requests "fit" on a single QUIC packet.
- The fuzzing mechanism (
FUZZand--wordlist/-w) only works in POST messages data or in the GET request URL (:path) argument. - Currently, the fuzzing mechanism only works once, meaning if the data argument is supplied (
-d), we assume fuzzing on the POST data, supplying theFUZZkeyword in the URL (:path) will result in sending the URL (:path) as-is (including theFUZZkeyword). - We do not support multiple different domains in the current version. (For different paths, you can use the FUZZ keyword in the URL's path part)
- "socket.gaierror: [Errno 11001] getaddrinfo failed" error returned on DNS error
Copyright (c) 2025 CyberArk Software Ltd. All rights reserved
This repository is licensed under the Apache-2.0 License - see LICENSE for more details.
Feel free to contact us via GitHub issues if you have any feature requests or project issues.