December 10, 2009

Sniff HTTP traffic with ASP.NET Development Webserver

During developing webapplications or -services, every now and then you will face a strong desire to be able to see the HTTP traffic that is sent back and forth between a client and the webserver.

Tracing local HTTP traffic is not easy

You will quickly find out, that this task sounds easier than it actually is when your client and your server reside on the same machine. There are tools like Fiddler (and tons of others, but this is my favorite), but they all suffer the same problem: Requests to localhost/127.0.0.1 cannot be captured because they are optimized by the windows network stack and bypass the usual hooks used by capturing tools. Thus you either need to use your network card's IP address for submitting requests or - if you don't have a local ipaddress when e.g. you use DHCP and are disconnected from the network - you need to install the MS Loopback Adapter and use this adapter's IP address (see installing MS Loopback Adapter)

ASP.NET Development Webserver is locked down on "localhost"

If you are like me and like the ASP.NET Development Webserver (aka "Cassini" or "WebDev.Webserver") that comes with Visual Studio (and recently also with the Windows 7 SDK), you can't use it to capture traffic. Probably due to legal issues, the ASP.NET Development WebServer (aka Cassini) contains code that binds the TCP socket to the 127.0.0.1 address only and also contains a check, that the requesting client resides on localhost. In this case you have 2 choices:

a) setup a Webapplication in IIS this is possible but nasty when you want to do it in a build script

b) follow the instructions below to patch the WebDev.WebHost.dll on your system

Steps to patch WebDev.WebServer

Note: All steps below assume you have .NET 3.5 Service Pack 1 and the Windows 7 SDK installed. But with basic familarity of IL code you shouldn't have much problems applying those steps to e.g. the version of WebDev.WebServer that comes with VS 2005 (note, that this version resides under the installroot of VS!)

Step 1

Create a new directory "C:\patchcassini" that we will use to work and change to this directory on the commandline. You can create any directory you want, but I will refer to it as C:\patchcassini below.

Step 2

Copy the WebDev.WebHost.dll from the GAC to your working directory and disassemble into an IL script. The following batch script shows how this is done:

set SDKHOME=C:\Program Files\Microsoft SDKs\Windows\v7.0




cd C:\patchcassini

rem refresh copy from GAC
copy /Y C:\Windows\assembly\GAC_32\WebDev.WebHost\9.0.0.0__b03f5f7f11d50a3a\WebDev.WebHost.dll .

REM create backup
copy WebDev.WebHost.dll WebDev.WebHost.original.dll

REM disassemble
"%SDKHOME%\bin\ildasm.exe" WebDev.WebHost.original.dll /out=WebDev.WebHost.il

This will create 2 new files in your folder: WebDev.WebHost.il and WebDev.WebHost.res. Note that the script also creates a backup of the original assembly

Step 3

Patch the generated IL script. There are 2 things you have to do:

1) Open the script in any editor and find & replace all occurrences of [System]System.Net.IPAddress::Loopback with [System]System.Net.IPAddress::Any

2) Find the method body of Connection::get_IsLocal() (just search for this string), you will see something like

.method assembly hidebysig specialname
        instance bool get_IsLocal() cil managed
{
 ....
} // end of method Connection::get_IsLocal

Replace the whole method body with the code as shown below:

.method assembly hidebysig specialname
        instance bool  get_IsLocal() cil managed
{
.maxstack  2
IL_0014:  ldc.i4.1
IL_0015:  ret
} // end of method Connection::get_IsLocal
Step 4

You need to recompile the IL script and reinstall the patched dll into the GAC. Since we also modified a signed dll, we need to turn off signature validation for this dll. The batch script below shows how this is done:

set FRAMEWORKHOME=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
set SDKHOME=C:\Program Files\Microsoft SDKs\Windows\v7.0

REM recompile the patched IL script into WebDev.WebHost.dll
%FRAMEWORKHOME%\ilasm.exe /output=WebDev.WebHost.dll /quiet /resource=WebDev.WebHost.res /debug /dll WebDev.WebHost.il

rem Remove validation
"%SDKHOME%\bin\sn.exe" -Vr WebDev.WebHost.dll

rem Install into GAC, forcing overriding any existing assembly
"%SDKHOME%\bin\gacutil.exe" /i WebDev.WebHost.dll /f

Enjoy!

After patching and reinstalling the WebDev.WebHost.dll, hitting F5 in VS to launch your webapplication allows you to access the Webserver using any local IP address and thus allows tools like Fiddler to capture the traffic.

Hint: You can also make your life easier by registering the Webserver in the context menu of any folder. Just use the registry script below:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\webdev.webserver.9]
@="ASP.NET Webserver 2008"

[HKEY_CLASSES_ROOT\Directory\shell\webdev.webserver.9\command]
@="\"C:\\Program Files\\Common Files\\Microsoft Shared\\DevServer\\9.0\\WebDev.WebServer.EXE\"  /port:81 /vpath:\"/\" /path:\"%1\""

This allows you to launch the Webserver using a rightclick of your mouse on any arbitrary folder:

image

Hope this helps!

4 comments:

Matthew said...

Thanks for this - worked a treat

If anyone wants a version of the patched file - contact me through

http://www.ap16.com

Thanks

Matthew Clements

Rob said...

Yup, works perfectly. Easy fix too :)

Thnx
/Rob

Richard Byrdk said...
This comment has been removed by the author.
Richard Byrdk said...
This comment has been removed by the author.