nice blog lol
This commit is contained in:
parent
f002fc5187
commit
67491f2cd9
BIN
.img/maxstreams.png
Normal file
BIN
.img/maxstreams.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
.img/packets.png
Normal file
BIN
.img/packets.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
BIN
.img/ynoreset.png
Normal file
BIN
.img/ynoreset.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
32
README.md
32
README.md
@ -1,5 +1,11 @@
|
||||
# rr-dev
|
||||
based on observations made by cloudflare in the excellent blog: https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/
|
||||
|
||||
no clue if this actually works, but it seems to match the same behavior
|
||||
mentioned in the cloudflare blog, which seems to no longer be available
|
||||
from their blog link.
|
||||
|
||||
## collecting and analyzing
|
||||
1. start http/2 enabled nginx server:
|
||||
```
|
||||
cd server
|
||||
@ -17,10 +23,26 @@ python rr.py
|
||||
5. compare against the cloudflare blog notes (unless you have the pcap which seems to be gone now)
|
||||
|
||||
## notes
|
||||
no clue if this actually works, but it seems to match the same behavior
|
||||
mentioned in the cloudflare blog.
|
||||
server advertises maximum stream concurrency of 128:
|
||||
|
||||
obviously to weaponize it, it will take some extra effort like multithreading but i sure as fuck
|
||||
am not releasing a weaponized version fo free.
|
||||
![Maximum concurrent streams](.img/maxstreams.png)
|
||||
|
||||
greets to psyk0, slerig, and all the other juggalols out there
|
||||
1000 stream headers are sent split into two packets:
|
||||
|
||||
![Wireshark packet list](.img/packets.png)
|
||||
|
||||
>Interestingly, the RST_STREAM for stream 1051 doesn't fit in packet 15, so in packet 16 we see the server respond with a 404 response. Then in packet 17 the client does send the RST_STREAM, before moving on to sending the remaining 475 requests.
|
||||
|
||||
despite exceeding maximum number of advertised streams, the server never sends a RST_FRAME:
|
||||
|
||||
![No RST_STREAM frames from server](.img/ynoreset.png)
|
||||
|
||||
> No server RST_STREAM frames are seen in this trace, indicating that the server did not observe a concurrent stream violation.
|
||||
|
||||
obviously to weaponize it, it will take some extra effort like implementing concurrency. but don't do
|
||||
that shit for any reason other than research. i'm saying this explicitly because
|
||||
we've seen examples of "illegal code" before. i do this solely for research, and fun of
|
||||
course, because c'mon this shit is so interesting.
|
||||
|
||||
## greetz
|
||||
greetz to psyk0, shifty, and slerig. who needa stop slackin, but i still love em anyway.
|
||||
|
@ -24,7 +24,7 @@ def send_rr_packets(server='localhost', port=443, max_streams=1000):
|
||||
|
||||
headers = [
|
||||
(':method', 'GET'),
|
||||
(':path', '/foo'),
|
||||
(':path', '/lol'),
|
||||
(':authority', server),
|
||||
(':scheme', 'https'),
|
||||
]
|
||||
@ -47,7 +47,7 @@ def send_rr_packets(server='localhost', port=443, max_streams=1000):
|
||||
|
||||
|
||||
def main():
|
||||
send_rr_packets(server='localhost', port=443)
|
||||
send_rr_packets(server='localhost', port=443, max_streams=1000)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
Reference in New Issue
Block a user