Monday, April 13, 2009

Mod-Security - Real Time Web Filtering


Mod-Security is a "real-time" application firewall for Apache. It's able to detect, log, deny, and take action on web attacks, and security related events for your Apache web server.

Installation is a breeze on a Debian system running Apache2:

#apt-get install libapache2-mod-security
#a2enmod mod-security
#/etc/init.d/apache2 force-reload

From there you can use the great documentation to start adding rules.

Just add a new section like so in the apache2.conf file:

<IfModule mod_security.c>

...new rules....

</IfModule>



Here's a quick entry to alert your would-be attackers that you know of their path traversal attempt for /etc/passwd:

I.E the user here requested: http://myserver/test/../../etc/passwd and we redirect them to /busted.html.


Here's the rule:
SecFilter /etc/passwd "deny,log,status:406,redirect:/busted.html

and the results:




This is a mere fraction of the capabilites with Mod-security. From there you can investigate a whole range of options, including denying DOS attempts using httpd-guardian.

Happy Filtering!

Friday, April 3, 2009

Tcpdump - The Truth Will Be Known!

So the other day I had a client complain that their Google Search Appliance was not indexing some content.

OK. Fair enough I say. What file?

This one:

http://mysecretserver/DocView.aspx?portalName=command&disposition=line&elementId=king

What is that?

Oh, It's a PDF streamed from a Database.

OK. Fair enough I say. Any other Details?

Well, user1 can't get the file, when he downloads it, it has no content and its size is 0 bytes, but user2 can!

OK. Fair enough I say, what's up with user1?

Shrug.

Let's see the headers and investigate! (LiveHTTPHeaders and ieHTTPHeaders are great tools to debug HTTP traffic)

User1:

GET /DocView.aspx?portalName=command&disposition=line&elementId=king HTTP/1.1
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: mysecretserver
Connection: Keep-Alive
Authorization: NTLM TlRMTVNAoACgBIAAAAEAAQAFIAAAAcABwAYgAAAAA(snipped for length)+dZ1kiREvfK1VVE

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 25 Mar 2009 20:46:16 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Content-Disposition: attachment; filename="myfile.pdf"
Transfer-Encoding: chunked
Cache-Control: private
Content-Type: application/pdf


User2:

GET /DocView.aspx?portalName=command&disposition=line&elementId=king HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1)
Host: cesdev.srv.gapac.com
Connection: Keep-Alive
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAHgAAAAAAAAaABoAXgAA(snipped for length)2Ovd51wDOjmS+tKpflzIe8cV2rna

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 25 Mar 2009 18:35:13 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Content-Disposition: attachment; filename="myfile.pdf"
Cache-Control: private
Content-Type: application/pdf


Hmmm, both show an HTTP 200 OK, but one user gets the file, the other get a 0 length file.

Nothing obvious just yet. Are we sure one user really gets the file?

Well, let's tcpdump!

Tcpdump is the Attorney, Judge, and Jury on the Lan, the truth will come out!

So I used the following syntax on the customer LAN for tcpdump:

tcpdump -i eth0 -s 0 -w /tmp/output.my.cap host mysecretserver -C 50

-s 0 means use the required length to catch whole packets.
-C 50 splits up large packet dumps to be no larger than 50 MB.
-"host mysecretserver" focuses solely on packets to and from mysecretserver.

Aha.

I see that User1 does get the full file, you can see the first bit of data after Content-Type: application/pdf while viewing the capture in WireShark (The Stenographer on the LAN - it will display back the truth to you!):



User2 does not.

Well the only difference I see between a working user and a non-working user is:Transfer-Encoding: chunked and also user1 is sending "HTTP/1.0" where user2 is sending "HTTP/1.1"

Well, sure enough, as per RFC 2616:

A server MUST NOT send transfer-codings to an HTTP/1.0 client.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html

That header is clearly needed to coerce the web server to send the data reliably and ensure transmission!

Please update your webserver to send data to an HTTP 1.0 client or make sure the GSA always sends an HTTP 1.1 request. Either will resolve this.

Mark this as Solved!