by Njål

SSL v3.0 POODLE vulnerability – fixing on IIS

poodle_3

A few days ago 3 Google researchers discovered a nasty SSL security bug – named POODLE (“Padding Oracle On Downgraded Legacy Encryption”) – CVE 2014-3566.

This vulnerability affects servers still running SSL 3.0. It centers on cipher block chaining (CBC) encryption implementation and allow attackers with a Man-in-the-Middle (MITM) position to derive the contents of a secure payload based on responses received from requests sent from a compromised browser to a legitimate server.

The first thing you should do is check if this affects your site. Scan using SSL Toolbox – https://ssltools.thawte.com/checker/views/certCheck.jsp

If this issue is detected – then you should disable SSL 3.0 support or disable SSL 3.0 CBC-mode ciphers. Here’s a bat file which does the job – just run it as a an administrator on your IIS server – and reboot.

REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" /v Enabled /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" /v Enabled /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" /v Enabled /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" /v Enabled /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 40/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 56/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 128/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128" /v Enabled /t REG_DWORD /d 00000000 /f

 

Rescan using SSL Toolbox after the reboot to make sure the vulnerability have been removed from your server.

Tags: ,
by Njål

Fixing HttpException 0x80004005 / COMException 0x80070001

When getting HttpContext.Current.Request.Params in a C# .NET IIS website – we got this error several times a day:

System.Web.HttpException (0x80004005): An error occurred while communicating with the remote host. The error code is 0x80070001. —> System.Runtime.InteropServices.COMException (0x80070001): Incorrect function. (Exception from HRESULT: 0x80070001)
at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
at System.Web.Hosting.IIS7WorkerRequest.ReadEntityCoreSync(Byte[] buffer, Int32 offset, Int32 size)
at System.Web.HttpRequest.GetEntireRawContent()
at System.Web.HttpRequest.GetMultipartContent()
at System.Web.HttpRequest.FillInFormCollection()
at System.Web.HttpRequest.EnsureForm()
at System.Web.HttpRequest.get_Form()
at System.Web.HttpRequest.FillInParamsCollection()
at System.Web.HttpRequest.GetParams()

 

Turns out that this is related to various offloading done by the Network Card (NIC) – meaning that the NIC is doing stuff on its own which the OS/IIS doesn’t always like. Go to the network card properties – and disable these features:

  • Flow Control
  • Ipv4 Checksum Offload
  • Large Send Offload V2 (IPv4)
  • Large Send Offload V2 (IPv6)
  • TCP Checksum Offload (IPv4)
  • TCP Checksum Offload (IPv6)
  • UDP Checksum Offload (IPv4)
  • UDP Checksum Offload (IPv6)

 

image

 

Also – make sure you disable Power Management for the NIC.

image

 

 

by Njål

Intelligencia UrlRewriter – Ashx Sessions getting lost

image

When debugging a Windows Azure website I kept getting null Sessions for my ashx pages. They worked perfectly on  IISExpress, so I thought this was a Azure flaw. It turned out that it was IIS 7.5 + Url Rewriting (I’m using the Intelligencia module) that caused the problem.

 

 

After adding this to my Web.config everything worked like expected again – also in IIS 7.5

<configuration>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" >
     ...
     ...
  </system.Webserver>
</configuration>

Also – make sure your ashx code implements IRequiresSessionState

public class ApiHandler : IHttpHandler, IRequiresSessionState
{
}
by Joakim

IIS: Cannot Start Website

After re-installing Windows on my laptop a little while ago, I got an error when setting up Internet Information Services (IIS) which I hadn’t seen before. When I tried to start the “Default Web Site”, IIS claimed that it couldn’t start it providing the following explanation; “The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020).”

website_nostart_1

Microsoft explains that the error code 0x80070020 translates to ERROR_SHARING_VIOLATION, and that the issue may related to another service on the computer grabbing TCP port 80 and/or 443.

From the command prompt I issued the following command, “netstat –o –n –a | findstr 0.0:80”, which gave me the ID of the process that was currently listening on port 80. Using the process ID (PID) it was easy to find the program in question using the “Task Manager”. And in my case the problem was Skype (might be another program in your case).

website_nostart_2

It turns out that Skype by default tries to use port 80 and 443 as alternatives for listening to incoming connections. And since I installed (and started) Skype before I set up IIS (and tried starting my website), Skype grabbed my port 80. Shutting down Skype (or just killing the Skype process from the Task Manager) allowed me to start my website since port 80 then became available again.

You can prevent Skype from grabbing port 80 and 443 by going into Skype’s “Tools –> Options –> Advanced –> Connection” and unchecking “Use port 80 and 443 as alternatives for incoming connections”.

website_nostart_3

by Joakim

Could not load file or assembly 'xyz' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Having recently performed a complete wipe and OS re-install/upgrade on my work computer, I also had to get all my projects etc. up and running again. After getting the source for one of the ASP.NET applications I’m working on, I built the source and ran it using the VS Development Server, no problem at all. However, when I set everything up manually in IIS (not IIS Express, that also also worked like a charm), I got the the beautiful yellow screen of death. And since it had been a while since I set this particular project up to run in IIS on my computer, the error dumbfounded me for a while.

could-not-load-assembly-1

Visual Studio did provide me with a warning when building the solution though, which jogged my memory.

could-not-load-assembly-2

One of the project dependencies was built specifically for the x86 architecture, and when running the web app in IIS the default setting for any Application Pool is NOT to enable 32-bit applications (at least on a 64-bit computer). This is easy to fix though, open up IIS Manager, find the App Pool in question, go into “Advanced Settings” and change the value for “Enable 32-Bit Applications” to “True” (or alternatively, and perhaps even better, replace the offending reference dll with a compatible version if you can).

could-not-load-assembly-3

No more yellow screen of death! Smile

by Stian

IIS Dynamic IP Restrictions

We just discovered the Dynamic IP Restrictions (DIPR) module for IIS 7.0 and above, which provides protection against denial of service and brute force attacks on web servers and web sites. This module is still, as of may 2012, only in “RC” version, but is absolutely worth a try.

The Dynamic IP Restrictions module includes these key features:

Inetmgr_DIPR

  • Blocking of IP addresses based on number of concurrent requests – If an HTTP client exceeds the number of concurrent requests allowed, that client’s IP address gets temporarily blocked.
  • Blocking of IP address based on number of requests over a period of time – If an HTTP client exceeds the number of requests made over a specified time interval, that client’s IP address gets temporarily blocked.
  • Allow list of IP addresses that will not be blocked – You can add a list of the IP addresses of clients you want to exclude from being blocked by the module regardless of other configuration.
  • Various deny actions – You can specify which response to return to an HTTP client for which the IP address is blocked. The module can return status codes 403 and 404 or just terminate the HTTP connection and not return any response.
  • Support for web servers behind a proxy – If your web server is behind a proxy, you can configure the module to use the client IP address from an X-Forwarded-For header.
  • IPv6 – the module provides full support for IPv6 addresses.

You can download the release candidates here:

by Andreas

Sharepoint debugging – process terminated by IIS

”The web server process that was being debugged has been terminated by IIS”

When debugging Sharepoint components you’re likely to come across this error message. It is easily fixed by turning off the ping IIS is sending the worker process at regular intervals to keep it alive.

Go to IIS Manager, select the Application Pool used by your Sharepoint app, choose advanced settings and turn the “Ping Enabled” setting under “Process Model” to FALSE:

image

by Njål

CORS = XmlHttpRequest to other servers – without JSONP

 

imageAs Webstep guru Thor Halvor explained in the this excellent blogpost – there are security restrictions to prevent/limit cross domain access of XMLHttpRequest’s – the cornerstone of AJAX.

Flash and silverlight has the same restrictions – and solves this by using crossdomain.xml and clientaccesspolicy.xml. These files are placed on the server you want to communicate with – and must contain * or the domain you want to contact the server from.

Anyways – there is a similar mechanism that XMLHttpRequest supports. This mechanism is called CORS – Cross-origin resource sharing. It is a newer(2004) and preferred alternative to JSONP – and works more or less like the xml files mentioned above. The only difference is that it isn’t implemented as a file – it’s part of the HTTP Header. This makes it a bit more difficult to set up than the others.

When a javascript on siteA wants to make a request to siteB – then the script first makes an initial OPTIONS request to site B – and looks at the HTTP Header it receives.

Access-Control-Allow-Origin: *

 

If the value is * – then it means that XmlHttpRequests can communicate with that site – from any other server – and a regular XMLHttpRequest can be made just like you were communication with your own server. You can of course type in domain names here to prevent everybody from using your API.

Here’s how to configure this on an Microsoft IIS Server – Web.Config – under the <configuration> node

<system.webServer>
  <httpProtocol>
    <customHeaders>
       <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

 

So to sum it up: use CORS whenever possible, instead of hacking your way around with JSONP. You’ll have prettier code, better error handling and it’s safer to use with regard to XSS Attacks as far as I have understood. Also – CORS supports all types of HTTP requests (Get/Post/Put,Delete), while JSONP only supports Get.

Read more about CORS here:
http://my.opera.com/core/blog/2011/10/28/cors-goes-mainline

A third (and the newest) alternative is UMP – I might blog more about this some other time.

by Njål

Complete Dump of Asp.net WebRequest

 


Alternate way of dumping logs

 

Here’s a simple but very handy method that lists out all relevant data for a Asp.net web request. Posted Parameters, Query String, Http Headers, Cookies and Session variables are returned – and can be logged out to file/console etc.

Note that this static method can be called anywhere from your code – it does not have to be inside a aspx/ashx etc. The only requirement is that the code must run inside IIS and a web request must be assosiated with the current thread.

 

 

 

public static string DumpRequest()
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("");
    sb.AppendLine("-------------  PostedParameters --------------");
    foreach (string key in HttpContext.Current.Request.Form.Keys.Cast<string>().OrderBy(f => f))
    {
        sb.AppendLine(key.PadLeft(40, ' ') + " : " + HttpContext.Current.Request.Params[key]);
    }

    sb.AppendLine("");
    sb.AppendLine("-------------  Query String ------------------");
    foreach (string key in HttpContext.Current.Request.QueryString.Keys.Cast<string>().OrderBy(f => f))
    {
        sb.AppendLine(key.PadLeft(40, ' ') + " : " + HttpContext.Current.Request.QueryString[key]);
    }

    sb.AppendLine("");
    sb.AppendLine("-------------  Http Headers -------------------");
    foreach (string key in HttpContext.Current.Request.Headers.Keys.Cast<string>().OrderBy(f => f))
    {
        sb.AppendLine(key.PadLeft(40, ' ') + " : " + HttpContext.Current.Request.Headers[key]);
    }

    sb.AppendLine("");
    sb.AppendLine("--------------  Cookies -------------------------");
    foreach (string key in HttpContext.Current.Request.Cookies.Keys.Cast<string>().OrderBy(f => f))
    {
        sb.AppendLine(key.PadLeft(40, ' ') + " : " + HttpContext.Current.Request.Cookies[key].Value + " - ExpireDate: " +  HttpContext.Current.Request.Cookies[key].Expires);
    }

    sb.AppendLine("");
    sb.AppendLine("---------------  Session ------------------------");
    foreach (string key in HttpContext.Current.Session.Keys.Cast<string>().OrderBy(f => f))
    {
        sb.AppendLine(key.PadLeft(40, ' ') + " : " + HttpContext.Current.Session[key]);
    }

    return sb.ToString();
}

 

The result looks like this::

-----------------------------------------  PostedParameters -----------------------------------------

-----------------------------------------  Query String ---------------------------------------------
                                username : ted@example.com

-----------------------------------------  Http Headers ---------------------------------------------
                                  Accept : text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
                          Accept-Charset : ISO-8859-1,utf-8;q=0.7,*;q=0.3
                         Accept-Encoding : gzip,deflate,sdch
                         Accept-Language : en-US,en;q=0.8
                           Cache-Control : max-age=0
                              Connection : keep-alive
                                  Cookie : timeOffset=-120; gs_u=1746198188:22843:26224:1320393450549; LANG=en; USER=a33f8…
                                    Host : dev.filemail.com
                              User-Agent : Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) Chrome..

-----------------------------------------  Cookies --------------------------------------------------
                                  __utma : 155161261.1943841533.1313506820.1324476330.1325070578.60 - ExpireDate: 01.01.0001 00:00:00
                                  __utma : 155161261.1943841533.1313506820.1324476330.1325070578.60 - ExpireDate: 01.01.0001 00:00:00
                                  __utmc : 260895642 - ExpireDate: 01.01.0001 00:00:00
                                  __utmz : 155161261.1313506820.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) - ExpireDate:
                                  __utmz : 155161261.1313506820.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) - ExpireDate:
                       ASP.NET_SessionId : a2xlln05ibzzd2ajywhpizc0 - ExpireDate: 01.01.0001 00:00:00
                                    gs_u : 1746198188:22843:26224:1320393450549 - ExpireDate: 01.01.0001 00:00:00
                                    LANG : en - ExpireDate: 01.01.0001 00:00:00
                              timeOffset : -120 - ExpireDate: 01.01.0001 00:00:00
                                    USER : a33f8a58568f430e8a0d48115ac7b13c - ExpireDate: 01.01.0001 00:00:00

-----------------------------------------  Session --------------------------------------------------
                                       - : -
                              UserObject :

 

by Njål

Problems with Recycle Bin in Umbraco – No Document exists with Version '00000000-0000-0000-0000-000000000000'

I recently had some problams emptying the Recycle Bin in Umbraco 4.6.1.  I clicked Empty Recycle Bin – but after a few items got removed the progress suddenly stopped showing 201 items remaining. Crap.

Internet Explorer displayed a Javascript Error msg (with a stacktrace):

No Document exists with Version '00000000-0000-0000-0000-000000000000'

Waiting, restarting IIS and trying to empty the recycle bin again did not help. Time to Google.

I found part of the solution here:

The sql

SELECT * FROM umbracoNode, cmsContent -- return nodes
WHERE
nodeObjectType = 'C66BA18E-EAF3-4CFF-8A22-41B16D66A972' -- that are of type 'Content'
AND
umbracoNode.id NOT IN (SELECT nodeId FROM cmsContent) -- but are not in the 'Content' table

helped me identidy orphan nodes that should be removed.

For each unique umbracoNode.Id in the result (you will get a lot of rows with the same id using the sql above) i ran the sql below to remove these nodes.

DECLARE @TEMPID INT
SET @TEMPID= 1843 -- TYPE IN ID HERE - e.g. 1843

DELETE
FROM         cmsContent
WHERE     (nodeId IN (Select id from umbracoNode where parentID = @TEMPID))

DELETE
FROM         cmsPropertyData
WHERE     (contentNodeId IN (Select Id from umbracoNode where parentID = @TEMPID))

DELETE
FROM         umbracoNode
WHERE     (id IN (Select id from umbracoNode where parentID = @TEMPID))

DELETE
FROM         umbracoNode
WHERE     (ID = @TEMPID)

Then I tried emptying the recycle bin again. Now it deleted 10 more items before it stopped.

I repeated the steps above again – first I ran the select sql to find the new orphan nodes, and then I ran the delete sql’s. I was able to remove 43 more items from the recycle bin this way.

I repeated this procedure until my Recycle Bin was empty (I had to do it 6-7 times or so).

Make sure to backup your database before trying this approach.