I'm trying to provide some form of mitigation or relief against slow HTTP POST attacks with IIS. Unfortunately due to the many bindings we have it would be very difficult to replace IIS with nginx to provide transfer rate control.
I have partial success with slow HTTP POST body attacks by using the connection timeout property. It seems to also affect Timer_EntityBody so if something isn't received on the socket for that many seconds (say 20) - http.sys will drop the connection.
IIS has a webLimits setting called "headerWaitTimeout" at the app host level: https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/weblimits
Old (web site defaults):
https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/sitedefaults/limits
It allows you to set a maximum time the client should send all HTTP headers. I can successfully set this value but when testing it with Kali Linux and 'slowhttptest' it seems not to have any effect. I also verified this behavior with wireshark.
Using this command on my Windows 2012 R2 server (IIS 8.5 but I suspect this is the same for IIS 10 on WS 2019):
netsh http show servicestate
I can see my main site's application pool has these settings:
URL group ID: A10000024000000F
State: Active
Request queue name: MyMainAppPool (name changed..)
Properties:
Max bandwidth: inherited
Max connections: 5000
Timeouts:
Entity body timeout (secs): 45
Drain entity body timeout (secs): 45
Request queue timeout (secs): 65535
Idle connection timeout (secs): 45
Header wait timeout (secs): 0
Minimum send rate (bytes/sec): 0
Authentication Configuration:
Authentication schemes enabled:
Number of registered URLs: 2
Registered URLs:
HTTPS://*:443/
HTTP://*:80/
Notice the request Q timeout is high (have no idea why - can't find this number in any level) and the header wait timeout is always 0. Other application pools inherit this properly. For example:
Timeouts:
Entity body timeout (secs): 45
Drain entity body timeout (secs): 45
Request queue timeout (secs): 65535
Idle connection timeout (secs): 45
Header wait timeout (secs): 25
Minimum send rate (bytes/sec): 768
I need a clue and pointer on where to go next. ETW traces show code in http.sys just waiting for new data. If there's any Microsoft IIS guru out there that can shed any light on this issue - Please share any info or pointer.
Thanks, Eli
Well, this just presented itself very recently. It really seems like problems are afraid whenever you try to expose them to the doctors :-) I found this small gem:
https://learn.microsoft.com/en-us/windows-server/networking/technologies/netsh/netsh-http
Basically, netsh http add timeout allows you directly manipulate the headerWaitTimeout of http.sys. Unlike the IIS webLimits section - this actually does the job!
I was able to set a timeout of 20 or 30 seconds on my site (actually this is global to the machine...) and tested the HTTP headers attack using this command:
(For a test of 1 connection with Wireshark capture)
Then when I moved the connection count to 2000 I saw a chainsaw-like behavior of the number of open connections which is what one may expect.
Headers report