Archive for the ‘Development’ Category

Let me see that certificate a little more closely. Part 1 – Validating the Server’s Certificate

June 11th, 2008 by

If you are developing a client to a server service that communicates over SSL such as a Web Service then it is your job to ensure your server is the "real deal" and not some rouge server or man-in-the-middle. How do you do that? Validate the server's certificate. Make sure the certificate is for the domain you are accessing, make sure the certificate chain is valid, and make sure the certificate is signed by a trusted certificate authority (CA). Sound like a pain? Well it isn't. You get a lot for a little with the right API calls.

WinHttpReceiveResponse in C++ will return FALSE if the certificate has one of the following errors:

WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED

Certification
revocation checking has been enabled, but the revocation check failed to verify
whether a certificate has been revoked. The server used to check for revocation
might be unreachable.

WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT

SSL certificate is invalid.

WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED

SSL certificate was revoked.

WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA

The function is unfamiliar with the Certificate Authority that generated the server's certificate.

WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID

SSL certificate common name (host name field) is incorrect, for example, if you entered www.microsoft.com and the common name on the certificate says www.msn.com.

WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID

SSL certificate date that was received from the server is bad. The certificate is expired.

WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR

The application experienced an internal error loading the SSL libraries.

However, WinHttpReceiveResponse does not return these errors directly as a call to GetLastError() will only return ERROR_WINHTTP_SECURE_FAILURE if there is a problem with the server's certificate. You must use the CallBack WINHTTP_STATUS_CALLBACK to access the specific errors listed above.


public WINHTTP_STATUS_CALLBACK myOwnAsyncCallback( __in HINTERNET hInternet,
__in DWORD_PTR dwContext,
__in DWORD dwInternetStatus,
__in LPVOID lpvStatusInformation,
__in DWORD dwStatusInformationLength)
{
if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
// We have a certificate issue but which one? Take action before each break. This function must be thread safe and reentrant.
switch(*(DWORD*)lpvStatusInformation)
{
case WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED:
break;
case WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT:
break;
case WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED:
break;
case WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA:
break;
case WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID:
break;
case WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID:
break;
case WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR:
break;
}
}
HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
WINHTTP_STATUS_CALLBACK isCallback = WinHttpSetStatusCallback( hSession, WINHTTP_STATUS_CALLBACK)myOwnAsyncCallback,WINHTTP_CALLBACK_FLAG_SECURE_FAILURE,
NULL);
//The rest of your code including call WinHttpReceiveResponse

For more information see
http://msdn.microsoft.com/en-us/library/cc185684(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa383917(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa384266(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa384115(VS.85).aspx

It all comes back to the basics

April 29th, 2008 by

Recently there has been a lot of talk in the security community about the Flash ActionScript exploit written by Mark Dowd (http://documents.iss.net/whitepapers/IBM_X-Force_WP_final.pdf). I will not go into a breakdown of the exploit as others have already done a great job of blogging about it. What I would like to discuss is two big takeaways that even programmers who are not "uber-hackers" can appreciate.

The first takeaway is the importance of understanding and implementing the fundamentals. The exploit above occurs because of a NULL dereference triggered by an out of memory return by malloc(). I remember in my first C programming class when I was working with a partner an a project and he was trying to properly implement malloc(). I had already been using C for a few years and always checked the return of a function. I could not figure out why he was not checking to make sure sufficient memory had been allocated. He gave me the excuse that it would require a lot of code to check the return value and that since the data structure was small the allocation would fail. Nonsense, as I demonstrated by filling up the 640K of standard memory. He then argued that we would be better off implementing XMS or EMS to access the other 3MB of "high" memory, a silly argument if ever there was one.

When non-security professionals describe what hackers do they often say that hackers look for ways to bypass restrictions and go around roadblocks. This is a somewhat fair description, but what they may not know is that often hackers are merely taking advantage of mistakes or the faulty reasoning of programmers who tried to skip or work around something simple or basic that they felt would be too much work to implement properly. The original "hacks" were simply ways of getting things done quicker, easier, or more elegantly but sometimes there is a fundamental reason for doing things one way and the "hack" just gets you into hot water. Anyone who has ever picked up a C programming book and looked at the function info for malloc() knows that it is NOT guaranteed to return the memory requested. Obviously, it is a BAD idea to simply assume that it succeeded in allocating all the memory requested. Know your functions/methods and how to properly implement them.

The second takeaway for the average programmer is the need to integrate and leverage the latest in security functionality in your code from the ground up. What do I mean by this? Follow-up research on the exploit has shown that if DEP had been turned on and opted-in the exploit would not have worked. DEP marks portions of memory as NX (No Execute). Such areas in memory will trigger a processor fault if an attacker attempts to execute shellcode they have somehow loaded into such memory. Is DEP a panacea- No. But it provides a second layer of defense. Now you might say- DEP is a system setting that users or admins or Microsoft can turn on or off, there is nothing I can do as a programmer. This is not true. First of all, you need to write your application to make sure it works properly with DEP turned on. You need to test your application to verify this. You need to inform users so they know they can safely use DEP with your application.

A number of other features like ASLR (Address space layout randomization), /GS (canary based buffer overflow detection), etc. are provided now by Visual Studio and other compilers or by the latest versions of the Windows operating system. Developers should be building their code to use these basic security tools that are in most cases so easily integrated. None of these features can prevent all security threats, but there are many applications out there using outdated compilers or failing to implementeven the simplest of automated defenses for lack of awareness or a fear of performance degradation. To the former- browse through just a few of the numerous security respurce out there and then review your compiler/linkers security related flags; to the latter- given the massive code bloat in this object oriented development world compared with the (good) old days of hand tuned assembly in a COM file what is a one or two percent more overhead :) .

Using ASP.Net session handling with secure sites (set the secure flag)

February 4th, 2008 by

One of the common problems we see with many web applications is reliance on ASP.Net sessionID without understanding the security ramifications. ASP.Net provides web developers with a powerful means of tracking user state and identity with very little coding. Rather than creating your own custom authentication cookie, handling the trickiness of forms auth or mapping your cookie to a Windows identity, password policy implementation, not to mention creating server objects to store the state for a given user, ASP.net does it all for you.

ASP.Net offers two methods of tracking session state- URL or cookie. URL based methods are used in cases where it is expected that some users will have disabled cookies and still need a server-side session to track state. This has become less common as more and more of the web relies on cookies. In addition the URLs look ugly and are considered unacceptableby many usability gurus.

The second method is a cookie sent as a header to the server. This cookie is sent over HTTP or HTTPS and is used by ASP.net to link an incoming request to the server-side state. So you are running your site on SSL, where is the problem? By default, the SessionID is just a cookie the browser sends it when making any response to the domain. If you go to https://yourapp/application, you will be sent a cookie over SSL that I cannot see. If I e-mail you a link to click for http://yourapp/application, I will see the cookie sent over HTTP as long as your server responds on port 80.

What you want to do is set the 'secure' flag on the cookie. You have many options for doing this: adsutil set w3svc/1/AspKeepSessionIDSecure 1 will tell ASP.net to mark the session cookie as Secure. When a cookie is marked as secure it will not be sent by the web browser unless the connection to the server is over https. You must be aware that the user will now have no session state if they browse to the site using http your application will need to redirect http requests to https in order to access the session state.

Is the ASP.Net session ID the only cookie I can protect in this way? No. You can use a web.config configuration to customize the security of all your cookies (http://msdn2.microsoft.com/en-us/library/ms228262.aspx). You will also be able to set cookies to be HttpOnly which adds its own element of security and is supported by newer browsers.

Finally, you can set both the secure flag and the HttpOnly flag for any other cookies you set programmatically through ASP.Net with http://msdn2.microsoft.com/en-us/library/ms228262.aspx.

A few other things to remember-

ASP.Net sessions expire after 20 minutes UNLESS a new request is seen. Otherwise they can remain until the server is recycled.

SessionIDs can be reused. When stored as a cookie the sessionID will go to any machine hosting the same parent domain. They will NOT have the server-side state though unless some clustering or back-end logic handles sharing state across servers. If you want to ensure that reuse does not happen, rather than using Session.Abandon you must overwrite the ASP.Net session cookie with an empty cookie value. To properly end a session or force a user to start a new one use Session.Abandon.

For more information checkout – http://msdn2.microsoft.com/en-us/library/ms972969.aspx

Microsoft Releases the sources to the .Net framework

January 17th, 2008 by

I suppose this is news to a lot of people. http://weblogs.asp.net/scottgu/archive/2008/01/16/net-framework-library-… The easy access to the source should help people. Even if it helps them use someone elses library. I'll get back to that thought in a second.

Of course the Intermediate Language (IL) can be looked at with it's rich meta data with ILDASM. It's kind of odd looking at “machine” intructions for a virtual machine. As far as I can tell there's close to no documentation about their OP codes or a language reference. The one (and only) great book I've found is …Expert .NET 2.0 IL Assembler
by Serge Lidin, S. Lidin

The much easier way to wander around is Reflector. You'll want the file disassembler add-in (let's you save all the files in an assembly).

I've wandered around in the framework a good deal and for the most part it isn't ….mmmmm…. productive. Some beanhead professor once upon a time decided that everything possible should be private. I'm not sure what this accomplishes except that it kills all kinds of code reuse. For example you want the listbox control to handle hotkeys or whatever just a tad differently for your application. You should just be able to overload the “broken” part of .Net. No can do, private. Don't get me wrong, on occasion you can redo some function. You borrow the code in Reflector, modify the part that doesn't work for you, and then you have to figure out how to get it's 4 uses of private calls fixed. Copy the whole object you say! Good idea. Now you have 4 other internal objects to copy. Lame lame lame. It's a big ole spider web.

The best cheat is to add yourself a CustomAttribute listing your assembly as a a “friend”. Of course this makes the signature invalid, so not exactly distributable. You could really cheat and sign your own version! Ahah. Who knows what's next? Mmmhmm, you have to drag all the other Microsoft Internal Friends with you. It's a tar baby I tell ya.

Who want's to talk about COM and application integration now? Makes you love those little itty bitty tools that don't depend on a thing. I wish thee were more.

Visual Studio 2008 CRT bug

January 16th, 2008 by

I run into this “issue” alot compiling this open source project or that open source project (winpcap, cygwin, delegate, snort, nmap. It's a fun MACRO problem. I love MACROs. </sarc>

Here's what your compiler will give you.


12>C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\stdio.h(358) : error C3163: '_vsnprintf': attributes inconsistent with previous declaration
12> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\stdio.h(350) : see declaration of '_vsnprintf'
12>Generating Code...

Now this looks like a no brainer, I mean the two declarations are 8 lines apart! So I stare for a while. (Looks the same to me). Hmmmm. Then I try following a few MACRO's, often futile if you don't have browser symbols built yet. Perhaps I have some crazy path with my includes!? I only have 12 SDKs or something installed. So I turn on /showIncludes (how did it take 20yrs to add this option?) Looks good again…..

Crap time for the Big Guns — If you love MACRO programming you know what's next. Turn on the C++ listing output. The listing output is what the compiler really compiles are the preprocessor has had it's merry way with the code. 2MB of the finest night time reading you'll ever find. Per source file of course. I was kinda dreading trying to find the function after all it's beautification had been stripped.

I've read a lot of code over the years. I'm not even sure what this is…much less what it would preprocess out to.


__DEFINE_CPP_OVERLOAD_STANDARD_NFUNC_0_2_ARGLIST_EX(int, __RETURN_POLICY_SAME, _CRTIMP, _snprintf, _vsnprintf, _Pre_notnull_ _Post_maybez_ char, _Out_cap_(_Count) _Post_maybez_, char, _Dest, _In_ size_t, _Count, _In_z_ _Printf_format_string_ const char *, _Format)

I digress…

It just compiles when you turn on the listing output.

I'll type it more slowly this time, in case that didn't sink in. The compiler switch, that just spits out more information, changed things just enough to have everything compile. Neato, unless that sort of thing keeps you up at night.

btw, the fix, if you've been reading this far, is to not #define vsnprintf in _your_ project. The CRT must redefine it once or thrice.

How to apply domain restrictions to a browser plugin (ActiveX or XPCOM)

January 15th, 2008 by

For Internet Explorer, there's Microsoft's Sitelock. For Mozilla, I'm not sure what there is… In that case, we've been working on some solutions that could hold up cross-browser on a Windows platform. Sitelock takes a solid approach, check out the code and you'll see it implements the IObjectSafetySiteLockImpl, replacing the ATL IObjectSafety interface. What am I talking about? Well sometimes, when you develop a browser plugin like an ActiveX control for IE or an XPCOM object for Mozilla, you only want it to load and run from a few trusted domains. The plugin/control runs potentially powerful code after all, executing in the user's context. For example, you're a large social networking site, and your new control helps synchronize offline and online data for the user. Well first off, you want to make sure it's secure as possible:

  1. code flaws have been identified and addressed (buffer overflows, leaks, etc.)
  2. repurposing threats have been identified and mitigated (the control should not do anything more than it needs, and should be very careful when performing file, registry, or network operations)

To gain a higher level of assurance that this control won't be exploited, you take more steps to restrict the domains which are allowed to call it.

So without Sitelock for Mozilla, we're in search of an alternative solution that will work across both IE and Mozilla. We know a few things available for the cross-browser domain restriction solution:

  • we can use C/C++
  • we have access to the DOM
  • we have access to COM+
  • we'd like access to WININET but that's too far down the stack

Right now, we're primarily interested in getting the true domain which is loading and calling the plugin. How can we gaurantee this? We try getting it from the DOM's document.domain property, but know that the document.domain property has historically been a source of security vulnerability in all major browsers. There have even recently been ways to spoof the address bar, or the domain property using JavaScript and other means, and there likely will in the future. For example:

FireFox
http://www.thespanner.co.uk/2007/11/14/spoofing-firefox-protected-object

IE 6/7.
http://www.0×000000.com/hacks/crossdomain/crossdomain.html

Safari/Windows
http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-3514

After some research we're testing some other options. Right now our best bet might be looking like:

  • using IWebBrowser2::get_LocationURL() for Internet Explorer
  • using window.location.href for Mozilla
  • InternetCrackUrl() to parse the hostname
  • After some testing we don't see the document.domain type issues present in window.location.href, so it seems to be holding up short some unknown browser-flaw.

    ~Chris Weber

I18N input validation whitelist filter with System.Globalization and GetUnicodeCategory

April 24th, 2007 by

Maybe you’re building internationalized code and wondering how to build a whitelist filter that will support all the different character sets your planning to support. If you support more than ten, especially some of the larger east Asian sets, this might seem like an unwieldy or tricky process.
Well luckily it’s easier than most people would think. Building a good input validation filter can be simplified with .Net’s GetUnicodeCategory. But use the method from the System.Globalization namespace as the other one in System.Char looks like it may become the subordinate.

With GetUnicodeCategory you can simply build a whitelist supporting the character categories you want to allow. So get away from thinking you have to write a regEx filter and list out all the character ranges you want to allow in each character set, it’s much simpler than that!

The Unicode standard assigns ever character to one of about 31 categories. They make sense too, for example Other Control charactes (Cc) , Lowercase Letter (Ll), Uppercase Letter (Lu), Math Symbol (Sm). So for example you might want to only allow letters, numbers, and punctuation in your whitelist. This could be achieved with the following snippet:


char cUntrustedInput; // the untrusted user-input
UnicodeCategory cInputTest = CharUnicodeInfo.GetUnicodeCategory(cUntrustedInput);
if (cTestCategory == UnicodeCategory.LowercaseLetter ||
cTestCategory == UnicodeCategory.UppercaseLetter ||
cTestCategory == UnicodeCategory.DecimalDigitNumber ||
cTestCategory == UnicodeCategory.TitlecaseLetter ||
cTestCategory == UnicodeCategory.OtherLetter ||
cTestCategory == UnicodeCategory.NonSpacingMark ||
cTestCategory == UnicodeCategory.DashPunctuation ||
cTestCategory == UnicodeCategory.ConnectorPunctuation)
{
// character looks safe, continue
}
else
{
// character is not allowed, fail
}

Not too bad eh.

Access to .Net System.dll internal functions

February 22nd, 2007 by

Occasionally you will discover a nice class or function you would like to use. I stumbled across [mscorcfg]Microsoft.CLRAdmin.Fusion.AddAssemblytoGac(string strAssembly). Oddly enough there's no way to add an assembly to the gac from .Net code. This would be just great for MSBuild tasks, or even installing.

If you try and use this class or function you get this result.


c:\dev\test\private test.cs(10,9) : error CS0122: 'Microsoft.CLRAdmin.Fusion' is inaccessible due to its protection level

Turns out using this function is pretty easy in theory. .Net only checks permissions at link time. You could do get around this the hard way by using ILAsm, or Reflection in C#.

Here's how you would do this using Reflection.

public static Int32 AddAssemblyToGac(string strAssembly)
{
object[] args = newobject[] { strAssembly };
BindingFlags bindingFlags = (BindingFlags)314;
return ((Int32)(FusionType.InvokeMember("AddAssemblytoGac", bindingFlags, null, null, args)));
}

Well that just opens up about a million possibilities. Just try and “fix” one class from the ASP.NET framework and you have to drag in 12 million interfaces. Now you are set, just use the same one's that it was using. This is going to save me tons of time. There's no way I'm writing a million Reflection proxy interfaces. Nevermind the fact that you can just call the interface using IL. There just has to be a good way to do this from C#. Worse case we could lie/cheat to the compiler.

The C# team has added a nice Attribute for us to do this.

[InternalsVisibleTo("AndrewsAssembly, PublicKeyToken=0b00fde735121dcc")]

You can read up on it viewing InternalsVisibleToAttribute.

So ILDasm System.Web.dll, or your favorite assembly, and recompile adding this CustomAttribute. Compile your assembly and you are off and running.

Here's a view from Lutz Roeder's Reflector of my test app using an internal System.Web enum.

Web Services denial of service attacks – XmlTextReader

February 19th, 2007 by

Most Web Services I look at are built using the .NET Framework and ASP.NET. Today we’re seeing more with ASP.NET’s AJAX extensions but that’s a different story. Many developers choose to implement SOAP and XML as part of their WS solution, and in doing so can inadvertently open the application server up to DoS issues.

First there’s XML. When developers choose to implement XmlTextReader or XmlReader from the .NET Framework, they need to understand the behaviors of these classes. MSDN documents this quite well. I will usually do a quick code review to find implementations of these objects, because the issues can be identified a little faster through code than through testing.

XmlTextReader defaults to allowing external DTD’s to be specified. This leads to a whole enchilda of issues, and gives attackers a nice bit of control over the host server. Be sure to set the ProhibitDTD property equal to true. Furthermore, there’s no strict schema validation unless the developer implements one.SOAP is fine, but developers need to implement a custom SOAP extension to enforce strict schema validation. Otherwise it gets pretty easy for an attacker to abuse the WS by embedding things like:

  • large payloads
  • large number of elements
  • nested elements
  • malformed data

To name a few… Without strict validation, I’ve seen web services easily abused. For example, by sending a few large requests, it becomes trivial to consume memory on the host server which eventually leads to resource starvation. To learn more about implementing a custom SOAP Extension to tackle this problem, read the MSDN article:

http://msdn.microsoft.com/msdnmag/issues/03/07/XMLSchemaValidation/

CSIDL – Shell constants, enumerations, and flags

December 26th, 2006 by

I worked on an application which had a couple of requirements:

  1. Allow users access to their local drive content within a defined scope (e.g. either the entire drive, or the My Documents folder only)
  2. Prevent users from accessing files outside of the defined scope. So they shouldn’t be able to access network drives, USB keys, etc.

To acheive this, the shell constants were used, as defined in the Windows SDK.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp

This worked well, and after we looked at the code we actually ran a battery of tests to confirm. So for example we tried the following types of canonicalizations:

  • \\host\share\file
  • \\?\folder\file
  • \\10.10.10.10\share\file
  • \\.\folder\file

We kept going, and tried breaking out of the local scope as well:

  • ..\..\..\..\boot.ini
  • ../../../../boot.ini
  • ..%2fboot.ini

And all that sort of stuff. Using the CSIDL constants proved successful, and we could see this through debugging. Everything we entered was merely relative to the constant value, there was no way to change it.