Monday, September 7, 2009

The Network Monitor API: Part II

The LoadCapAndFilter example from Network Monitor Examples from Codeplex allows you to specify a particular filter from Network Monitor API. Some fragments from the code are below. Note how the string is escaped (e.g. \"GET\") :

[LoadCapAndFilter.cpp]
/Add filter
ret = NmAddFilter(myFrameParserConfig, L"http.request.command == \"GET\"", &myHTTPFilterID);
...
//Add field
ret = NmAddField(myFrameParserConfig, L"http.request.uri", &myHTTPFieldID);
....
// Obtain the value of http.request.uri from frame. We
// know that strings are passed as word pointer to unicode string in the variant.
..
ret = NmGetFieldValueString(myParsedFrame, myHTTPFieldID, 256, (LPWSTR)value);

Sample output:

LoadCapAndFilerHTTP.exe Miscellaneous_001.cap
sparser.npb:001.000 Successfully unserialized NPL parser 'C:\Users\Admin\AppData\Local\Microsoft\Network Monitor 3\sparser.npb.
Frame 14: HTTP: /crls/globalca1.crl
Frame 100: HTTP: /crls/globalca1.crl
Frame 227: HTTP: /crls/globalca1.crl
Frame 547: HTTP: /crls/globalca1.crl
....

I can modify the LoadCapAndFilter Network Monitor example to parse as needed. For example, Microsoft has a global load balacer that it contacts both before and after secondary authorization for Wireless Network Connections. It functions by contacting http://nssi.glbdns.microsoft.com/ncsi.txt and checking to see is a successful http request is returned. If it can't do so, the returned payload shows no http status code:

HTTP HTTP:Response, HTTP/1.0, Status Code = , URL: /ncsi.txt

If it gets a hit, this request shows:

HTTP:Response, HTTP/1.1, Status Code = 200, URL: /ncsi.txt

By changing the top code to (far) below, I can cycle through all my wireless sniffs to see how many times my Vista laptop tries to get: http://nssi.glbdns.microsoft.com/ncsi.txt  with :

for /f %i in ('dir /b *.cap') do LoadCapAndFilterGet_NCSI.exe %i 

[output]:
LoadCapAndFilterGet_NCSI.exe Test.cap
sparser.npb:001.000 Successfully unserialized NPL parser 'C:\Users\Admin\AppData\Local\Microsoft\Network Monitor 3\sparser.npb.
Frame 8012: HTTP: /ncsi.txt
Frame 8452: HTTP: /ncsi.txt
Frame 8815: HTTP: /ncsi.txt
Frame 9178: HTTP: /ncsi.txt
Frame 9560: HTTP: /ncsi.txt
...

[LoadCapAndFilterGETNCSI.cpp]:

//Add filter
ret = NmAddFilter(myFrameParserConfig, L"HTTP.Request.URI == \"/ncsi.txt\"", &myHTTPFilterID);
...
//Add field
ret = NmAddField(myFrameParserConfig, L"http.request.uri", &myHTTPFieldID);
....


Another example:

This code ...


//Add filter
ret = NmAddFilter(myFrameParserConfig, L"TCP.Port == 443", &myHTTPFilterID);
if(ret != ERROR_SUCCESS)
{
wprintf(L"Fail to load Add fitler, error: \n", ret);
}

//Add field
ret = NmAddField(myFrameParserConfig, L"SSL.TlsRecLayer.TlsRecordLayer.SSLHandshake.HandShake.ClientHello.Extns.ClientHelloExtension.ServerNameList.ServerName", &myHTTPFieldID);
if(ret != ERROR_SUCCESS)
{
wprintf(L"Fail to load Add field, error: \n", ret);
}

produces this output:

C:\Users\Admin\Documents\Network Monitor 3\Captures>LoadCapAndFilterTCP001.exe Test.cap
sparser.npb:001.000 Successfully unserialized NPL parser 'C:\Users\Admin\AppData\Local\Microsoft\Network Monitor 3\sparser.npb.
Frame 7160: TCP443: www.google.com
Frame 16097: TCP443: signin.evri.com
Frame 16341: TCP443: signin.evri.com
Frame 16577: TCP443: www.connect.facebook.com
Frame 16591: TCP443: www.connect.facebook.com
Frame 16599: TCP443: www.connect.facebook.com
Frame 16631: TCP443: www.connect.facebook.com

..

To make LoadCapAndFilter work, the correct return types for  NMGetFieldValue must be assigned. I had quite a few problems making other queries work, seemingly because of this.


// Obtain the value of http.request.uri from frame. We
// know that strings are passed as word pointer to unicode string in the variant.
WCHAR value[256];
ret = NmGetFieldValueString(myParsedFrame, myHTTPFieldID, 256, (LPWSTR)value);
  if(ret == ERROR_SUCCESS

1 comment:

  1. Very Informative..!! Thanks for sharing this is such a very nice post i really like it your blog.

    Network Security

    ReplyDelete