Thursday, August 11, 2011

IIS 7.5, ASP.NET and log4net FileAppender lock error

Logging is a big part of any application.  In a recent MVC3 web application, I was having trouble getting my log4net configuration to log successfully to a file.  At first I had no idea why nothing was logging.  The symptoms I saw were that the destination file was being created, but nothing was getting logged to it.

Step 1:  Turn on log4net internal debugging.
Visit the Log4net FAQ and look under the troubleshooting section.  There you will find a faq on turning on the log4net internal debugging feature.  Basically it uses the windows trace system and then logs those trace alerts to a file.

Step2: Inspect the debugging
After taking a look at the debugging output, I noticed the following error.

log4net:ERROR [RollingFileAppender] Unable to acquire lock on file xxxxx. Access to the path 'xxxxx' is denied.

At least now I had a place to look.

Solution
There are two things that I had to do to make this solution work.
1)  In a web environment, there could be multiple threads trying to write to the logging file at once (depending on how you have things setup).  By default, log4net tries to acquire an exclusive lock to the files it is trying to write to.  You can override this default behaviour by telling log4net to use minimalistic locking.  You can find out more information in the faq by looking for "How do I get multiple process to log to the same file".

In any event, the configuration you want to add to your fileappender is

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

2) Make sure the application pool you are trying to use has file permission access to write to that file.  In IIS 7.5, you can setup your application pools to use application pool identities, instead of networkservice or another named account.  You can find more information about this here.  Basically, an application pool identity is kind of a "virtual account".  In order to give access to the file, you have to give the user "IIS AppPool\<AppPoolName>" permission to write to that file.

Happy logging!

Thursday, August 4, 2011

IIS 7.5 and .NET Security: Part 1 - Security through Obscurity

There are several different security features that you are going to want to use to protect your web server. One of the techniques that you should use is security through obscurity. I want to be very clear, this is only ONE aspect of security.  It should definitely not be the only thing you do.  I further want to stress that this won't be very good defense against a targeted attack.  At best, you will be able to fool a large percentage of the script kiddies who are only looking for the easy scores.


The first step in any attack is recon. Anything we can do to misguide or delay this step pays dividends later on.  If you can make a tool think that your IIS server is an apache server, great.  It just means the results the attacker will get will be bogus.

Most recon involves both OS and webserver fingerprinting.  I will only focus on webserver fingerprinting. Most techniques focus on a few basic things.

1)  Extension of the page being served.  Example: .aspx
2)  Server headers.  By default IIS will claim that it is IIS
3)  Session tokens.  For example: jsessionid is almost always a java application, which helps narrow down the field of web servers.

There are lots of articles on the interwebs about (1), so I will skip it here.

2)  One of the easiest ways to change the server headers is to install webknights.  Among the many features that webknights has to offer, changing the server headers is one of them. 

Doing this is quite simple.  In the webknights configuration file there is a "Headers" section.  You can set the server header value to anything you want it to be.  A good one is something like "Apache/2.0.64".

3)  You need to change the cookie name used to store the session id.  By default it is something like ASP.NET_SessionId.  If that doesn't say hack me, I'm not sure what does.  The SessionState Element inside the webconfig allows for an optional parameter called cookieName that will allow you to change the name used.  I suggest you change it.  You can use something like Id, or ApplicationId, or WebsiteId, or something else really really generic.  If you want to continue trying to mimic an application running on apache, you can make your attackers salivate and change the name to phpsessionid. 

Once again, this is just a couple of tricks you can use to try and fool some script kiddies.  Most of this stuff will delay a targeted attack at best.