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.
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).
I just crashed a 2008 R2 server without a rule, just with "Enable Kernel Caching".
Not sure if it is relevant, but I first added a rule for .png, and then removed it again. Still worked.
Can't edit the top comment anymore :( but it has been found that indeed no rules are needed to exploit this (my previous answer is outdated and wrong!)
If you can't afford to reboot your servers right now to install the patch, at least you can add this to your web.config and deploy your websites ASAP :
Instead of updating every single web.config of your website I think it is better to just update once and for all by updating machine.config. What you say ?
Seems like you can't add a system.webServer node on the machine.config, but you could add it to applicationHost.config (source: http://www.iis.net/learn/get-started/planning-your-iis-archi... ) so yes, that would be faster. You have to make sure that none of your web.config files override that setting though!
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.
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!
That was my case as well... initialized IIS on a fresh server to test against. (took me a while to figure out that IIS wasn't even setup, since the IIS manager was on the server) ... accidentally crashed my local machine too (forgot to change the localhost to the ip of the server whyn copy/pasting the url from the browser on the server)
Do you happen to have a screenshot of the BSOD, or could test it a second time to take a screenshot? I don't really have a free test server that I can crash anymore since I tested this morning when not a lot of people were at the office yet.
Yep. I tried curl -v to get all the raw headers line by line and the payload is there, and I also tried in telnet, both return a 200 page.
I read the microsoft security bulletin and it says that your IIS server is protected if Kernal Caching is off, maybe that's why our servers are neither blocking the request nor crashing with the request.
I was able to crash mine (local win8.1 and win2012 server) without any rules specified, only the checkbox enabled for kernel caching... it may vary based on windows version.
One other possibility, is that your systems have already been compromised and are giving you back incorrectly safe-looking output. I'm not saying its probable, just possible.
confirmed the above command crashed my win 2012 r2 server on AWS with no output cache rules.
I found a png being served by my home page, and after 2 of the above requests the server crashed.
I installed the pending windows updates and after a restart the problem seems to be gone.
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.
I don't have a MS server with IIS installed, but I would be very interested if the exploit check from the OP would be negative with kernel caching disabled. Anyone care to test this?
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"
From the linked page: "TUX has never been an integrated part of the official Linux kernel, although it has been shipped in some distributions, notably Red Hat, SuSE and Fedora."
Sure. My point is that Microsoft isn't the entity to put a web server (or at least components of one) in the kernel. Some may look at it and laugh about how silly that idea is, but in reality many have tried it.
Yep. Another reason folks are against systemd, as it also includes a baked-in http server. Systemd is also poised to become a veritable "second kernel" on linux systems and nobody seems to care enough to stop it.
I agree that systemd is a bad idea in the sense that they are doing too much all at once. It is a fine level of arrogance to assume that there wont be problems along the way :P That being said this thread is about the poor souls who are running IIS servers.
OpenSSL's heartbleed was incredibly hard to patch because of the sheer number of products that link to the OpenSSL libraries. It required painstaking effort to ensure everything was running the latest releases. And the severity of Heartbleed was such that all encrypted information could be deciphered.
Whereas this problem... is a simple server crash that can be fixed by running a Windows Update. Not even on the same scale of vulnerability.
I personally worried about the simplicity of the attack. Granted at this stage, its just a DoS, but then take corporate patch cycles into account.. In reality, most aren't going to get patched, at best, for another week or so. Security is still second-fiddle at many companies.
Sounds like the author understands the bug but does not understand why it allows remote code execution (which I don't understand either; once details are released it should be clarified).
That's a good point, because in the example we can clearly see how to check if a system is or not patched and that, using this attack, we can crash a Windows Server.
The remote execution part is completely missing (fortunately), but I was wondering if this gives the admin rights on machine (I have absolutely no experience on Windows Server machines, so I don't know how it works in terms of services, permissions and roles).
I would guess it involves spamming the server with specially crafted requests to fill memory with bytecode. After some trial and error (vast simplification) the request from the article could be used to divert the flow of execution into the bytecode spam, rather than causing DoS. The DoS is likely because flow of execution is being diverted to a random area of memory that doesn't contain anything executable, and so crashes instead.
The heap spraying is the missing puzzle piece from the article.
I have trouble understanding what you want to say but I did not say what you quoted me with. Please don't put words in my mouth.
The title was giving people the wrong impression about the severity of the vulnerability. This has nothing to do with "avoid giving people ideas" which would be stupid anyways.
IIS has several components. One of them, the vulnerable part here, is running in kernel space. In kernel space you have access to everything.
As far as I know, IIS is the only(bar embedded devices running a single address space OS and various ancient/obsolete toys servers on linux) used in production that handles part of HTTP in kernel space (or ring 0 if you will).
Sure. I read est as saying that Administrators are more restricted in Server 2008 than they were in earlier Windows versions. I assumed they were talking about the relatively well known technique of scheduling a cmd shell to run as SYSTEM, which that blog mentions being prevented in Server 2008.
But you would still expect an Administrator account to be able to load files onto the system, so obtaining the SYSTEM shell remains pretty easy.
The distinction between SYSTEM and Administrator was a convenience, and if I understood est correctly, it still is.
Why is it inherently 'madness' to have part of your HTTP stack running in kernel space? I think it's generally accepted that handling TCP in the kernel isn't madness; what's the magic distinction between dealing with TCP packets from remote machines and dealing with HTTP requests from remote machines that makes one of them an acceptable activity to carry out in kernel space, and one not?
To be clear about http.sys, it's not what you would normally consider a 'web server'. It leaves things like 'serving files' and 'authentication' and stuff up to userland application processes like IIS. But it allows multiple userland applications to be routed HTTP requests directly, without an IPC dispatch.
They aren't the only ones who do this: https://www.freebsd.org/cgi/man.cgi?accf_http . All sorts of things are kernel-accelerated on modern operating systems, including lots of network operations. From that perspective, this is just one more and it could potentially have a huge benefit (like the same page served count on fewer hardware) for customers who need it.
Obviously it's critically important that MS get this right if they're going to offer it at all, but that's pretty much a tautology when talking about kernels and core OS functionality. Judge them on a bad implementation, not on any inherent badness in the idea.
Yeah, I completely missed that in order for kernel caching to work, HTTP has to be parsed within the kernel, and so I was making an invalid point. It happens.
Well, of course you can make such a web server on any OS where you can modify or extend the kernel, but TUX is not exactly a popular or recommended solution. There's a reason the reference manual is dated 2001.
IIS is marketted by MS as a VERY capable web server... typically out-performing other web servers by a large margin. The caching system for IIS has always been one of their crowning achievements, working better than most systems. Though, these days most will put a caching server(or cluster) in front of their operations servers. Just the same, it has worked pretty well. Though I predict this feature will be removed, or disabled by default in future versions.
I'm kind of surprised this issue wasn't discovered previously. Fortunately, there doesn't seem to be an exploit beyond crashing the server yet (which is bad enough). (sigh, kind of glad I'm in the process of migrating everything away from IIS).
According to comments in the other discussion here about this it might not IIS be only, because that kernel component is used for other HTTP services as well:
Nope. WinRM or Power shell seem to use it too. Enabled by default. (Just created a 2012R2 server last night.)
Plus if you have reservations created with HTTP.SYS, your app doesn't even have to be running. A friend tried turning off IIS, but port 80 would still respond.
Nor is every machine's port 80 publicly reachable. Everyone behind a NAT won't be, for example (unless they've explicitly forwarded the port for the purposes of running such a server.)
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.
Confirmed: I couldn't force a BS using the originally supplied range numbers, but changing it as per above to 100 did the trick (windows 2008 non R2 & 2012 R2)
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.
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
}
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.
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 };`.
It is common for code which is designed to trigger security bugs in systems to be published with several errors, so that skiddies can't just compile and run.
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).
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.
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.
HTTP.sys feeds directly into the IIS Request Queue. When that queue overruns, (i.e. too many pending requests that are waiting on a backend NAS or other resource) it's HTTP.sys providing the 503 error, not IIS.
Yup, that's not that special though. All major OS have the TCP/IP stack in the kernel. And many (but not all) OS have at least parts of their GUI stacks in the kernel.
MS actually moved the GUI stack into the kernel around NT 4. Used to be (so legend has it) if the video driver crashed on earlier versions of NT, you could restart it, and the system didn't go down. But, you know, PERFORMANCE!!1. Win.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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/ -H "Range: bytes=00-18446744073709551615"
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.
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.
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.
They pretty much have. Sometimes people make mistakes that lead to vulnerabilities like this. It will be patched soon, then forgotten, and life will return to normal for everyone using IIS. We'll still run http in the kernel for performance purposes and everyone will conclude that no damage was really done. People will still use the same tech.. this vulnerability is not game changing and it'll be business as normal.
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, etc in the past couple months. Hell, sambra runs as root too.
There's a lot of security stupidity out there. I'm still waiting for a unixy OS to be written in something like Rust.
I'm actually sort of glad that my national defense forces get a jump on this stuff. Especially if it's only a few days or a week to secure their systems and (for the clandestine services) to retool their exploits. I believe there are actual clandestine actions in the national interest happening and it would be nice to see those enabled. (e.g. Stuxnet/sabotaging foreign nuclear weapons development)
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 -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).