IIS headerWaitTimeout ssems to have no effect on slow HTTP header attacks

787 views Asked by At

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

1

There are 1 answers

0
voguemaster On

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:

slowhttptest -c 1 -H -i 5 -r 200 -t POST -u http://<url to post>/.../ -p 30 -x 20 -l 120

(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