Web Security Blog

Syndicate content
Official Blog of Trustwave's SpiderLabs - SpiderLabs is an elite team of ethical hackers, investigators and researchers at Trustwave advancing the security capabilities of leading businesses and organizations throughout the world.
Updated: 2 hours 26 min ago

Announcing ModSecurity v2.8.0

Tue, 2014-04-15 20:04


The ModSecurity Project team is pleased to announce the availability of v2.8.0.  To see the full release notes or download the the source packages, see the ModSecurity GitHub project release tab:

https://github.com/SpiderLabs/ModSecurity/releases

New Features

Version 2.8.0 comes with five important new features:

  • Status Reporting
  • JSON Request body Parser
  • @detectXSS Operator
  • SecConnReadStateLimit and SecConnWriteStateLimit Directives
  • FULL_REQUEST and FULL_REQUEST_LENGTH Variables

In addition to great new functionality, we have also improved the following:

  • Debug and Troubleshooting Documentation
  • Testing Platforms
  • Project Development Metrics
ModSecurity Status

See our previous blog post entitled "Introducing ModSecurity Status Reporting".  Status Reporting simply provides the project team with some basic community usage data including the # of users, OS and web server platforms and software versions in use. This functionality is not enabled by default in ModSecurity, however we have activated it as part of our Recommended Base config file.  

The information that will be sent to the modsecurity.org server is also shared with the community through the website: http://status.modsecurity.org/.

 

For the full list information that is sent to the ModSecurity website, check the ModSecurity Reference Manual.

JSON Parser

ModSecurity will automatically parse request body content when the Content-Type headers are:

  • www-x-form-urlencoded, or
  • multipart/form-data

If the request body Content-Type is something else, such as XML, then a SecRule is used to dynamically trigger libxml2 using the “requestBodyProcessor” parser.

Similarly, we have extended the request body parser support to now handle JSON content using yajl (Yet Another JSON Library).  

When this configuration is used, ModSecurity will parse the JSON contents and populate the standard ARGS collection.  We will be releasing a full blog post soon outlining the new JSON request body parsing feature.  More information on the JSON Parser is available at: ModSecurity Reference Manual.

@detectXSS Operator

The new @detectXSS operator uses the most recent libinjection code that identifies possible XSS attacks.  The new operator is active within both of our live demos:

More information about libinjection XSS detection: https://speakerdeck.com/ngalbreath/libinjection-from-sqli-to-xss

SecConnReadStateLimit  and SecConnWriteStateLimit Directives

In previous versions of ModSecurity we introduced two directives to help combat Slow HTTP DoS Attacks:

  • SecReadStateLimit
  • SecWriteStateLimit

While these directives are helpful to mitigate attacks, they lacked the capability to correlate client IP address data.  With ModSecurity v2.8.0, we have deprecated the previous directives for two new ones:

These directives establish a per-IP address limit of how many connections are allowed to be in SERVER_BUSY_READ or SERVER_BUSY_WRITE state.  The big difference is that they are now able to accept optional parameters: @ipMatch, @ipMatchFromFile and @ipMatchF to allow for white-listing exceptions of these thresholds.

Note: This functionality is only available to Apache users.

FULL_REQUEST and FULL_REQUEST_LENGTH Variables

As a ModSecurity rule writer, I have found occasions where I would like to analyze the entire HTTP request content all within one single variable, rather than parsed into separate individual variables.  This is now possible with FULL_REQUEST which contains the full request content including: request URI, headers and the request body. The format is essentially the same as what the browser sends across the wire with headers and the request body separated by a “blank line”.  In this release there is also available the FULL_REQUEST_LENGTH, which contains the amount of bytes that will be used when FULL_REQUEST is requested.  

Debug and Trouble-Shooting Documentation

We have published documentation to aid the community in reporting bugs and steps for troubleshooting problems. Sometimes due to very specific configurations and/or dependency versions it is not possible for our development team to reproduce, in a timely manner way, an error reported by our users. In order to reduce the time to respond to these kinds of problems, we created the following documentation: Debugging ModSecurity.  This is not a developer guide or debugging utility, but rather simple documentation that can provide enough information to the users to eventually debug and report (with rich and detailed information) a problem whenever a crash is detected.  In addition, we have published the IIS-Troubleshooting guide. It provides very important information those who are facing problems with the ModSecurity for IIS version.

Testing Platforms

We have updated our continuous integration platform to use ARM.  Besides the support for Linux (32 and 64 bits), Windows with different versions of Visual Studio - our Buildbots - can now compile our code inside a BeagleBone Black.

Our BeagleBone black is running Ubuntu 13.10 for ARM with all the developer tools installed, a build with all the regression tests is taking about 16 minutes for Apache and 14 minutes for Nginx. So far our Beagle made 182 builds of a total of 1610 made by all the slaves combined.

Project Development Metrics

A useful site for analyzing open source projects is Ohlo.  There is a bunch useful tools and analysis graphs that show the health of the project.  Here is an overview of the ModSecurity project:

GitHub also provides many interesting project development tools including “Graphs”.  With Graphs it is possible to figure out project metrics such as: what time of day or day of week does the project receive commits from the community?  This question can be answered by reviewing the GitHub ModSecurity punch card.

The balls diameter represents the amount of commits. The time is represented in the “X” axis and the day of the week on the “Y” axis.

Bug Fixes

In this release, 18 bugs were also fixed.  The complete list of bug is listed below:

  • Correctly handling inet_pton in IIS version;
  • Nginx was missing a terminator while the charset string was mounted (Ref: #148);
  • Added mod_extract_forwarded.c to run before mod_security2.c (Ref: #594);
  • Added missing environment variables to regression tests;
  • Build system is now more flexible by looking at liblua at: /usr/local/lib;
  • Fixed typo in README file;
  • Removed the non standard compliant HTTP response status code 44 from modsecurity recommended file (Ref: #665);
  • Fixed segmentation fault if it fails to write on the audit log (Ref: #668);
  • Not rejecting a larger request with ProcessPartial. Regression tests were also added (Ref: #597);
  • Fixed UF8 to unicode conversion. Regression tests were also added (Ref: #672);
  • Avoiding segmentation fault by checking if a structure is null before access its members;
  • Removed double charset-header that used to happen due a hardcoded charset in Nginx implementation (Ref: #650);
  • Now alerting the users that there is no memory to proceed loading the configuration instead of just die;
  • If SecRuleEngine is set to Off and SecRequestBodyAccess On Nginx returns error 500. Standalone is now capable to identify whenever ModSecurity is enabled or disabled, independently of ModSecurity core (Ref: #645); 
  • Fixed missing headers on Nginx whenever SecResponseBodyAccess was set to On and happens to be a filter on phase equals or over 3. (Ref #634);
  • IIS is now picking the correct version of AppCmd while uninstalling or installing ModSecurityISS. (Ref#632).
What's next?

Besides new features, for the next release we are aiming to do the following:

  • Solaris and FreeBSD Support on our regression test platform.
  • Better documentation on how to build ModSecurity in different platforms.
  • Documentation on how to contribute to the project including: how to use git, how to request a merge, how to edit and test our code, how to create new regression tests.

Submitted by Felipe Costa and Ryan Barnett

Categories: web server

[Honeypot Alert] JCE Joomla Extension Attacks

Wed, 2014-03-26 09:54

Our web honeypots picked up some increased exploit attempts for an old Joomla Content Editor (JCE) Extension vulnerability.  

Although this vulnerability is a few years old, botnet owners are heavily scanning for sites that are vulnerable and attempting to exploit them.

Exploit Details

Here are the exploit details from the vulnerability write-up on Exploit-DB:

Web Honeypot Logs - Attack Sequence Step 1: Attempt to Upload a PHP Webshell

The first step in this attack is to attempt to upload a webshell/backdoor file to the JCE ImageManager.  Here is how the attack looked in the default Apache access_log file:

This entry shows a POST request to the ImageManager Joomla Plugin using the "com_jce" option.  We can also see a tell-tale sign of a malicious program in the User-Agent string value "BOT for JCE".  Unfortunately, the default Apache access_log does not actually log the critical POST payload for this request so we can not see what was sent.  Fortunately, we also have our ModSecurity WAF installed so we can go to the detailed audit log file to see the complete transaction.  Here is the same transaction as logged by ModSecurity:

We notice a few things here:

  • Under Section "B" - We can see the POST request is "MultiPart" meaning that it is an attempt to upload a file attachment.
  • Under Section "J" - we can see the meta-data about the file attachment.  It was a file called "food.gif".
  • Under Section "H" - we see two different rules triggered on this request.  One for a missing Accept request header and one from our commercial ModSecurity rules package for the suspicious User-Agent value.
File Attachment Analysis 

ModSecurity has the ability to capture and store file attachments.  When we inspect the "food.gif" file, we find the following:

This is an obfuscated PHP file.  After decoding, we find this section of code:

This is a typical webshell/backdoor that allows the attacker to submit OS commands and upload files:

Step 2: Rename File Extension

After uploading the webshell file, the attacker next needs to rename the file and change the file extension from ".gif" to ".php" so that it will be executed as code by the application.  There are known exploit tools to achieve this task.  Here is an example screenshot of a PHP exploit page:

The source code of the page shows the attack details:

The highlighted section show the JSON request body content that uses the "folderRename" action to change the uploaded file extension.  This is how the actual attack attempt looked in the ModSecurity audit log file:

Note under Section H that our commercial rule captured this attack attempt.

Step 3: Access the Webshell

The last step in the attack sequence was for the attacker to try and access the webshell file:


Since the exploit attempt did not work, the honeypot returned a 404.

Conclusion

Attackers are constantly scanning the internet for web sites that have out-dated software.  It is critical that web site owners stay vigilant in updating their software and applying patches.  In addition, using a Web Application Firewall (WAF) such as ModSecurity can also aid operational security personnel with incident response by providing essential transactional data. 

Categories: web server

Google Summer of Code (GSoC) + OWASP + ModSecurity = Awesome

Thu, 2014-03-20 08:05

OWASP is again participating in the Google Summer of Code (GSoC) Program for 2014 by acting as a Mentoring Organization.  This is an outstanding opportunity for college students to get a chance to contribute to open source projects, gain experience and make some money over the summer.  Here is a quick graphic that shows how GSoC works:

There are many OWASP Project Ideas for students to choose from.

GSoC Ideas for ModSecurity

We had great success last year when Mihai Pitu created a port of ModSecurity to the Java platform by using JNI interface to hook in the standalone ModSecurity code.  This year, we have even more ideas for students to choose from!  Time is running out for submissions so you better hurry.

OWASP ModSecurity Core Rule Set (CRS) - ModSecurity Ruby API

Brief explanation: Adding the capability of rapid prototyping to ModSecurity functionalities trough scripts will open the possibility for easy rules production and customization, It also opens the possibility for a large community such as Ruby developers to create their own customization on the top of ModSecurity and so customize their own rules, analog of today's Lua support.

Expected results: An implementation able to handle Ruby scripts which will interact to ModSecurity as Lua does.

References: Embedding Ruby into C++ (ModSecurity is C, using C++ as reference): http://aeditor.rubyforge.org/ruby_cplusplus/index.html ModSecurity Reference Manual, Lua: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecRuleScript

Knowledge Prerequisite: C and Ruby programming and ModSecurity Development Guidelines - http://www.modsecurity.org/developers/. Mentor: Felipe Zimmerle Costa and Ryan Barnett - OWASP ModSecurity Core Rule Set Project Leader

OWASP ModSecurity Core Rule Set (CRS) - ModSecurity Python API

Brief explanation: Adding the capability of rapid prototyping to ModSecurity functionalities trough scripts will open the possibility for easy rules production and customization, It also opens the possibility for a large community such as Python developers to create their own customization on the top of ModSecurity and so customize their own rules, analog of today's Lua support.

Expected results: An implementation able to handle Python scripts which will interact to ModSecurity as Lua does.

References: Embedding Python into C/C++: http://docs.python.org/3.3/extending/embedding.html ModSecurity Reference Manual, Lua: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecRuleScript

Knowledge Prerequisite: C and Python programming and ModSecurity Development Guidelines - http://www.modsecurity.org/developers/. Mentor: Felipe Zimmerle Costa and Ryan Barnett - OWASP ModSecurity Core Rule Set Project Leader

OWASP ModSecurity Core Rule Set (CRS) - Create "Sniffer-Mode"

Brief explanation:

The ModSecurity code includes a "standalone" version that wraps a light weight Apache/APR around the ModSecurity code. This is used as the basis for the ports to the IIS/Nginx web server platforms. The goal for this project task is to extend this standalone version so that it can accept a data feed of network traffic (e.g. libpcap) data as input and apply the ModSecurity CRS rules. Possible solutions could be:

  • Create a ModSecurity "plugin" for the Snort IDS.
  • Create a ModSecurity "plugin" for the Suricata IDS.
  • Add libpcap sniffer wrapper to standalone ModSecurity code to directly pull data off the wire.

Expected results:

This new sniffer mode would allow organizations to run ModSecurity/OWASP ModSecurity CRS in an out of line mode as they do IDS systems.

Knowledge Prerequisite:

C programming and ModSecurity Development Guidelines - http://www.modsecurity.org/developers/.

Mentor: Felipe Zimmerle Costa and Ryan Barnett - OWASP ModSecurity Core Rule Set Project Leader

OWASP ModSecurity Core Rule Set (CRS) - Implement DoS Prevention Code

Brief explanation: https://github.com/SpiderLabs/ModSecurity/issues/416

Implement a request velocity learning engine to identify dynamic DoS thresholds for both the site and for the particular URL.

Expected results:

The new C code in ModSecurity will allow us to add new DoS Protection methods to the OWASP ModSecurity CRS.

Knowledge Prerequisite:

C programming and ModSecurity Development Guidelines - http://www.modsecurity.org/developers/.

Mentor: Felipe Zimmerle Costa and Ryan Barnett - OWASP ModSecurity Core Rule Set Project Leader

OWASP ModSecurity Core Rule Set (CRS) - Create a Positive Learning/Profile Engine

Brief explanation: See this academic/research paper for ideas of the type of learning we are looking for - http://www.cs.ucsb.edu/~vigna/publications/2003_kruegel_vigna_ccs03.pdf

ModSecurity needs a profiling engine that implements the various AppSensor Detection Points - http://blog.spiderlabs.com/2011/08/implementing-appsensor-detection-points-in-modsecurity.html.

Expected results:

The new engine will implement more detection points to detect abnormal request attributes.

Knowledge Prerequisite:

C programming and ModSecurity Development Guidelines - http://www.modsecurity.org/developers/.

Mentor: Felipe Zimmerle Costa and Ryan Barnett - OWASP ModSecurity Core Rule Set Project Leader

OWASP ModSecurity Core Rule Set (CRS) - Create an Engine to Detect Application Flow Anomalies

Brief explanation:

Need an engine that can track normal application flow paths (click-flows) for business logic transactions - such as transferring money from accounts. After profiling normal application path flows, we want to then be able to alert to anomalies. This type of logic can help to prevent Banking Trojan attacks.

Example - let's say an application has a multi-step checkout process to purchase an item. This new engine would be able to profile/learn which URLs are accessed in what order and identify if clients skip steps or jump directly to other URLs in the flow.

Expected results:

The engine will be able to alert on anomalous application flows.

Knowledge Prerequisite:

C programming and ModSecurity Development Guidelines - http://www.modsecurity.org/developers/.

Mentor: Felipe Zimmerle Costa and Ryan Barnett - OWASP ModSecurity Core Rule Set Project Leader

Categories: web server

WordPress XML-RPC PingBack Vulnerability Analysis

Wed, 2014-03-12 11:41

There were news stories this week outlining how attackers are abusing the XML-PRC "pingback" feature of WordPress blog sites to launch DDoS attacks on other sites.  This blog post will provide some analysis on this attack and additional information for websites to protect themselves.

Not A New Vulnerabilty

The vulnerability in WordPress's XML-RPC API is not new.  Here is data from the WordPress bug tracker from 7 years ago.

While the vulnerability itself is not new, it has only been within the past couple years that attack code/tools have been made available.  This has certainly helped increase attacks by ScriptKiddies and resulted in more actual DDoS attacks.

WordPress XML-RPC Pingback DDoS Attack Walkthrough

The XML-RPC pingback functionality has a legitimate purpose with regards to linking blog content from different authors.  The issue is that this functionality can be abuse by attackers to use the XML-RPC pingback feature of a blog site to attack a 3rd party site.

Patsy Proxy Attacks

SpiderLabs colleague Daniel Crowley gave a great presentation at DerbyCon in 2012 entitled "The Patsy Proxy: Getting others to do your dirty work" where he discussed various scenarios for sending attack traffic through 3rd party sites/services that will forward data onto other sites. (Slides here).  Additionally, there have tools released in the community that extend this concept. One such tool is called "DDoS attacks via other sites execution tool (DAVOSET)" and it has the capability to send attacks through many different public sites that will forward traffic.  Here is an example listing of URLs from DAVOSET -

As you can see, sending attack data through a "Patsy Proxy" site is quite easy.  Now let's take a look at the WordPress XML-RPC Pingback issue.

WordPress XML-RPC Pingback DDoS attack

Here is an example attack command using curl -

The YELLOW highlighted data is a WordPress "Patsy Proxy" site while teh ORANGE highlighted data is the target/victim website.  It is important to note for testing purposes that you must include the "Content-Type: text/xml" request header data otherwise the XML-RPC service will not treat the request as valid and will issue the following response:

With the previous request sent by the attacker, the Patsy Proxy WordPress site then initiates this HTTP request to the target/victim site -

Notice that the format of the HTTP request is only two lines:

  • URI
  • Host request header

This intelligence can be used by Web Application Firewalls (WAFs) that are protecting the victim sites to identify attack requests.  Normal web browsers send many more request headers.  While the pingback DDoS attack doesn't utilize any type of amplification as other more recent network protocol attacks (e.g. NTP), requests can cause more damage on the victim site if the URI is initiating a computationally expensive back-end query or process.

Protections Disable XML-RPC

It is possible to disable the XML-RPC process altogether if you do not want to use it.  There are even plugins that will disable it.

Disable Pingback Reqests

You may also disable the pingback feature by adding the following to your functions.php file:

Identify Initial Pingback Requests

By using a WAF, you can identify inital pingback XML attack requests on your WordPress site.  We have added rules to our commercial SpiderLabs ModSecurity rules package to identify this attack.

Identifying Pingback Initiated Requests on the Victim Site

As mentioned previously, even though the construct of the URI line might be dynamic, the fact is that all proxies XML-RPC pingback requests will only have two lines in the HTTP request.  WAFs can be used to identify these anomalies and then respond (perhaps by pushing out IP based blocking to infrastructure systems).

Categories: web server

Bloodletting the Arms Race: Using Attacker's Techniques for Defense

Thu, 2014-03-06 08:48

Submitted by Ziv Mador and Ryan Barnett

This blog post will summarize a recent talk that we (Ryan Barnett and Ziv Mador) gave at the RSA 2014 conference where we showed how tactics used by different cyber-criminal gangs could be used by defenders.  You can also listen to this previous SpiderLabs Radio podcast where Karl Sigler interviewed us about our talk.

Turning the Bad Guys Against Themselves

You may be familar with the Ouroboros symbol where a Serpent is eating its own tail.  It symbolizes cyclicality and self-recreation and is applicable to the constant battles that security vendors/researchers have when facing bad guys.  For our presentation, we used a modified version called "Dual Ouroboros" where you have two Serpents eating each other's tails.

This is the essence of the concept that we wanted to promote in our talk where we want to leverage the tactics and techniques used by one group of criminals and apply them defensively to help protect against a different criminal element. 

Standard Adversarial Relationship

Typically, there are are pairings of security vendors (products) vs. malware families.  In the following diagram, we have Web Fraud Detection vendors squaring off against Banking Trojan malware such as Zeus/SpyEye.  Additionally, we have Secure Web Gateways vs. Exploit Kits such as Blackhole.

During these battles, there is a constant "Arms Race" where defenders try to develop new methods for detection malicious behaviour and criminals try to evade or hide from defensive detection methods.  The following cartoon is a perfect example of the type of iterative Arms-Race process we are fighting.

Let's take a quick overview look at these four key players.

Banking Trojans

Symantec released a very good infographic entitled "The State of Financial Trojans 2013" that provides relevant data as to scope and impacts.  Here is a table from that report that lists the top banking trojan families.



Zeus' Webinject Functionality

One of the key capabilities of banking trojans are "webinjects" where the malware is able to dynamically modify the raw HTTP data just before/after the web browser.  Here is an example of different webinjects that manipulate various login page HTML in attempts to phish extra data from users.

As a real example, we showed the following "webinjects.txt" data in our live presentation demo that attempts to trick the user into providing their ATM PIN number:

When an infected user goes to the "login.html" page on the fake banking site, the login form would look like the following:

If the user enters in this data, Zeus will grab the information and send it off to a Command & Control (C&C) web site where the banking trojan operator can use this information to conduct account takeovers or to initiate fraudulent Electronic Fund Transfers (EFTs) siphoning money out of the victim's account into money mule accounts.  Here is an example screenshot of fraudulent EFTs from the Zeus C&C interface:

Client-side Web Fraud Detection Examples

Web Fraud Detection vendors use many different techniques to identify fraud activities but we will focus on the top two:

Client-side Device Identification/Browser Fingerprinting

How unique, and trackable, is your web browser?  Web Fraud Detection vendors are able to identify an incredible amount of data about end users by enumerating various device/browser characteristics.  If you want to test our your own web browser, go to the Panopticlick website to check.  Here is an example snippet when I went there using Google Chrome:

The webpage checks many different characteristics of my web browser including:

  • User-Agent
  • Accept Headers
  • Browser Plugin Details
  • Time Zone
  • Screen Size
  • System Fonts

By correlating all of this data, my browser was considered unique amongst almost 4M browsers tested.  This data, as opposed to IP Address information, is a much more robust method for tracking users of your web application.  Here is an example of updated HTML for the fake banking login page with new javascript calls to Web Fraud Detection code:

The "md5.js" script simply provides client side hashing capabilities.  The "fingerprint.js" file implements many of the same browser environment checks that Panopticlick looks for.

When this code executes, it will will generate a client fingerprint hash and then send this back to the server in a beacon request -

Server-side fraud detection processes can then check this fingerprint against reputation systems to see if this client has been associated with any fraud activities.

Webpage Integrity

The key defensive capability we need to identify if a banking trojan has manipulated the HTML data that left the web application is to be able to validate the data once it reaches the browser.  With this concept in mind, we can leverage the work done by the University of Washington Computer Science and Engineering team on a project called “Detecting In-flight Page Changes with Web Tripwires.”  Here is a a quick visual -

The "webtripwire.js" javascript call in the HTML issues an XHR request back to the web server for the same page but this time is includes a new "WebTripwireCheck: On" header:

This results in the following request/response -

The HTTP response now includes the "WebTripwireHash" header.  The client-side javascript then calculates the hash of the actual response and then compares it with the header hash.  If they do not match, then an alert issued to the user:

Zeus Removes Fraud Code

The "webinject" functionality is actually a misnomer.  In addition to being able to "add" extra data to the HTML, it also has the ability to REMOVE or manipulate data.  It is this capability where Zeus can be used to neuter client-side fraud detection code.  Here is an updated webinject entry that will strip out all data in between the "data_before" and "data_after" HTML.

This technique effectively renders the Fraud Detection code useless....  How can we protect our defensive code against webinject removal from Zeus?

Exploit Kits

Exploit kits are the mechanisms used to exploit client-side vulnerabilities to deliver malware payloads to victim's computers.  Here is a quick list of the top Exploit Kits SpiderLabs tracked for Q4 2013 -

Here is the typical Exploit Kit attack flow where a user goes to a website that has been compromised and it includes a malicious IFRAME that points to the actual Exploit Kit code.

Use of Obfuscation

Here is an example of some Blackhole Exploit Kit code that checks for various plug-in/software versions before sending the exploit payloads -

This code would be easily identified by static signature detection systems.  In order to evade detection, Exploit Kits use obfuscation techniques.  Here is an example of the same code, however it has been put through a basic Ceasar Cipher data substitution change -

This is functionally equivalent code as web browsers would execute the javascript and it would return the original code.

Interestingly, both Exploit Kits and Web Fraud Detection Code have the same challenge: How can they protect their code and evade detection by their adversary?  

Using Exploit Kit Obfuscation Techniques for Defense

Why can't we re-use the same type of Obfuscation used by Exploit Kits to protect our Web Fraud Detection code?

The idea is to take our stanard banking login HTML and place it inside a layer of javascript obfuscation.  Here is what the new HTML looks like for our login page -

Again, the user notices no different in functionality as the page renders properly and our Anti-Fraud code triggers as normal.  Zeus, on the other hand has problems.  Zeus gains access to the raw HTTP data stream by using the wininet.dll library.  It modifies the data outside the context of the Internet Explorer web browser.  This means that, at the point in time where webinjects would run, the layer of javascript obfuscation prevents webinject from triggering on the normal HTML tags.

So Defenders Win, right?!?!?

The Arms Race Continues... 

The use of Exploit Kit Obfuscation techniques used to protect defensive code is a novel idea, however in the end this is only a roadblock.  Banking Trojan operators have way too much money on the line to just give up.  Therefore, we surmize that they would respond to this type of defense by modifying Zeus source code to implement De-Obfuscation algorithms.

Here is an example of the modified "httpgrabber" Zeus code that includes the new De-Obfuscation algorithm -

This code can be used by specifying the new "O" flag in the "set_url" definition -

This modified configuration would result in the following -

  • Zeus would de-obfuscate the raw HTTP data in intercepts with wininet.dll
  • Strip out the Anti-Fraud Detection javascript code
  • Issue a webinject to add in the fake "ATM PIN" form field
Backporting De-Obfuscation Routines to Secure Web Gateways 

As we work through our gaming theory of probably response actions, we have come to the place in time where Banking Trojan authors have implemented de-obfuscation routines within their code to try and normalize the data.  Odds are that the SpiderLabs Incident Response/Forensics and Research Malware Teams would obtain samples of modified Zeus.  We could then take this updated de-obfuscation functionality and supplement the existing ones within the SWG appliances.  

The end result being that one cyber criminal element (Banking Trojan authors) would be helping security vendors to better detect another cyber criminal element (Exploit Kits).

Beyond Obfuscation

We demonstrated one defensive technique in this blog post, obfuscation, however Exploit Kits also use other tacticts that we leverage.  One example is polymorphic variable names where the values of key variables change upon each invocation of the page.  Here is an example screenshot of the polymorphic variables in our demo -

By changing these variables each time the page is loaded, it makes it more challenging for static analyzers (or banking trojans) to normalize.

Conclusion

What we demonstrated in this blog post is a single tactical example (using Exploit Kit obfuscation to protect defensive code) of a more strategic concept (using attacker tactics for defense).  While this particular use-case to break the functionality of banking trojan webinjects is cool, it is not panacea.  What we really want to promote as a takeaway concept for this topic is this -

Know Your "Friend's" Enemy

Far too often, defensive security personnel are stuck in an echo chamber as they are locked in on battling their adversary.  You may in fact gain inspiration and revelation by talking with security practitioners/researchers in a different knowledge domain.  This often happens when the SpiderLabs Research malware, client/server and vulnerability teams interact with each other.  The result is that each team comes away with new ideas to implement within their own security domains.

If you are a Financial institution and would like assistance with implementing the defenses outlined within this blog post, please contact us.

Categories: web server

ModSecurity Advanced Topic of the Week: Detecting Browser Fingerprint Changes During Sessions

Wed, 2014-02-19 14:28

This blog post will discuss a section from Recipe 8-5: Detecting Browser Fingerprint Changes During Sessionsin my book "Web Application Defender's Cookbook: Battling Hackers and Protecting Users".   

Web Client Device Fingerprinting

Web client fingerprinting is a centerpiece of modern web fraud detection systems and goes way beyond simply capturing the User-Agent field submitted by clients within web transactions.  For instance, common web client fingerprinting usually includes sending client executable code that queries the browser for various settings such as:

  • Current screen size
  • Time zones
  • Browser plug-ins
  • Language Settings

Once the client-side fingerprinting code is completed, it then needs to create a new cookie value to pass the data back to the web application for evaluation.  The advantage of utilizing client fingerprinting is that it allows you to do two important tasks:

  1. Identify clients using real web browsers.  If the web client is some type of automated program or script, it most likely will not properly process client-side code such as JavaScript.  Without this processing, if a client does not submit the proper fingerprinting cookie, they will be easily blocked.
  2. Uniquely identify clients even when their source address locations change.  Even if the client IP address changes, the actual browser fingerprint data will not change.  This makes this detection superior to relying upon tracking source location changes.
Application Session Tracking with ModSecurity

Before we can set and track client device fingerprints, we first must configure ModSecurity to create Application SessionID-based persistent storage.  Basically, we will monitor for any outbound "Set-Cookie" response headers leaving the application that are setting a SessionID.  We will then use that data as a "key" to create local collection data.  We can then track data about this SessionID.  Here is an example rule from the OWASP ModSecurity CRS Session Hijacking conf file that will initiate a local session collection using the ModSecurity setsid action:

# # This rule will identify the outbound Set-Cookie SessionID data and capture it in a setsid # SecRule RESPONSE_HEADERS:/Set-Cookie2?/ "(?i:(j?sessionid|(php)?sessid|(asp|jserv|jw)?session[-_]?(id)?|cf(id|token)|sid).*?=([^\s].*?)\;\s?)" "chain,phase:3,id:'981062',t:none,pass,nolog,capture,setsid:%{TX.6},setvar:session.sessionid=%{TX.6},setvar:tx.ip=%{remote_addr},setvar:tx.ua=%{request_headers.user-agent}" SecRule UNIQUE_ID "(.*)" "t:none,t:sha1,t:hexEncode,capture,setvar:session.csrf_token=%{TX.1}"

As an example of how this might look, let's use the IBM AppScan demo.testfire.net web application as our demo.  When you go to the login page, it will issue a Set-Cookie response header:

The ModSecurity CRS rules shown above would then create the following local persistent storage using the ASP.NET_SessionId value as the key:

collection_store: Retrieving collection (name "default_SESSION", filename "/tmp/default_SESSION") collection_store: Wrote variable: name "__expire_KEY", value "1392833832". collection_store: Wrote variable: name "KEY", value "xhxwbh45kgemppyzubgbevjt". collection_store: Wrote variable: name "TIMEOUT", value "600". collection_store: Wrote variable: name "__key", value "xhxwbh45kgemppyzubgbevjt". collection_store: Wrote variable: name "__name", value "default_SESSION". collection_store: Wrote variable: name "CREATE_TIME", value "1392833232". collection_store: Wrote variable: name "UPDATE_COUNTER", value "1". collection_store: Wrote variable: name "sessionid", value "142746277840". collection_store: Wrote variable: name "csrf_token", value "1dc112da33eaa98e5613787b39f3bc9b10c877d8". collection_store: Wrote variable: name "ip_hash", value "a90c80bf0f0fc7f79224cd129783eaa26c358d5b". collection_store: Wrote variable: name "ua_hash", value "02ef1221431736846709d15d966da967d704d3b8". collection_store: Wrote variable: name "LAST_UPDATE_TIME", value "1392833232". collection_store: Persisted collection (name "default_SESSION", key "xhxwbh45kgemppyzubgbevjt").

Now that we have Session-based storage, we can activate our rules to conduct client device fingerprinting for the duration fo the session. 

Client Device Fingerprinting with ModSecurity

The first step in this process is to use ModSecurity to inject JavaScript code links within outbound html response bodies.  Here is some example code that achieves this goal:

SecContentInjection On SecStreamOutBodyInspection On # # -=[ Send Browser Fingerprint Code ]=- # SecRule RESPONSE_STATUS "@streq 200" "chain,id:'981802',phase:4,t:none,nolog,pass"         SecRule RESPONSE_HEADERS:Content-Type "@beginsWith text/html" "chain"                 SecRule &SESSION:KEY "@eq 1" "chain"                         SecRule STREAM_OUTPUT_BODY "@rsub s/<\/head>/<script type=\"text\/javascript\" src=\"\/md5.js\"><\/script>|0A|<script type=\"text\/javascript\" src=\"\/fingerprint.js\"><\/script>|0A|<\/head>/" "capture,setvar:session.fingerprint_code_sent=1"

When this code runs, it will do the following:

  • Verify the HTTP Status Code is 200
  • Check the Content-Type Response Header to ensure we are only injecting our code into HTML responses.
  • Verify that a Session Collection has been created (SESSION:KEY exists).
  • Insert our JavaScript calls within the HTML head tag.

The updated HTML would look similar to the following:

The first call is for the file md5.js which is a helper file that provides md5 hashing capabilities.  The second file is called fingerprint.js and is based on the “browser fingerprint” JavaScript code created by security researcher Gareth Heyes.  Once ModSecurity has injected this code, the rules set a new Session variable:

collection_store: Persisted collection (name "default_SESSION", key "xhxwbh45kgemppyzubgbevjt"). collection_store: Retrieving collection (name "default_SESSION", filename "/tmp/default_SESSION") collection_store: Wrote variable: name "__expire_KEY", value "1392834311". collection_store: Wrote variable: name "KEY", value "xhxwbh45kgemppyzubgbevjt". collection_store: Wrote variable: name "TIMEOUT", value "600". collection_store: Wrote variable: name "__key", value "xhxwbh45kgemppyzubgbevjt". collection_store: Wrote variable: name "__name", value "default_SESSION". collection_store: Wrote variable: name "CREATE_TIME", value "1392833232". collection_store: Wrote variable: name "UPDATE_COUNTER", value "5". collection_store: Wrote variable: name "sessionid", value "142746277840". collection_store: Wrote variable: name "csrf_token", value "1dc112da33eaa98e5613787b39f3bc9b10c877d8". collection_store: Wrote variable: name "ip_hash", value "a90c80bf0f0fc7f79224cd129783eaa26c358d5b". collection_store: Wrote variable: name "ua_hash", value "02ef1221431736846709d15d966da967d704d3b8". collection_store: Wrote variable: name "LAST_UPDATE_TIME", value "1392833711". collection_store: Wrote variable: name "fingerprint_code_sent", value "1". 

This variable is used to activate the subsequent enforcement rules.  Here are the fingerprint.js script contents:

The first section of code shows the various web browser characteristics we are correlating for our browser fingerprint.  It then takes the combined values and creates a truncated md5 hash value that we use to set a new cookie value for the domain called browser_hash.  When new web requests are sent back to the web server, they will now contain our new cookie value:

The first time that we receive a request with a browser_hash cookie, can use the following rule to SAVE this fingerprint as valid for the remainder of the Session:

# # -=[ Save the initial Browser Fingerprint Hash in the Session Collection ]=- # SecRule &SESSION:BROWSER_HASH "@eq 0" "chain,id:'981803',phase:1,t:none,nolog,pass"         SecRule REQUEST_COOKIES:BROWSER_HASH ".*" "setvar:session.browser_hash=%{matched_var}"

This rule will save the initial browser_hash data within the current session-based collection as shown here:

collection_store: Retrieving collection (name "default_SESSION", filename "/tmp/default_SESSION") collection_store: Wrote variable: name "__expire_KEY", value "1392836702". collection_store: Wrote variable: name "KEY", value "xhxwbh45kgemppyzubgbevjt". collection_store: Wrote variable: name "TIMEOUT", value "600". collection_store: Wrote variable: name "__key", value "xhxwbh45kgemppyzubgbevjt". collection_store: Wrote variable: name "__name", value "default_SESSION". collection_store: Wrote variable: name "CREATE_TIME", value "1392835058". collection_store: Wrote variable: name "UPDATE_COUNTER", value "16". collection_store: Wrote variable: name "sessionid", value "145812282394". collection_store: Wrote variable: name "csrf_token", value "87c66072b2c1327aa464183ddbf83c02512eb9ee". collection_store: Wrote variable: name "ip_hash", value "a90c80bf0f0fc7f79224cd129783eaa26c358d5b". collection_store: Wrote variable: name "ua_hash", value "02ef1221431736846709d15d966da967d704d3b8". collection_store: Wrote variable: name "fingerprint_code_sent", value "1". collection_store: Wrote variable: name "LAST_UPDATE_TIME", value "1392836102". collection_store: Wrote variable: name "browser_hash", value "ffa85f45a3".

Now that we have browser fingerprint data for the current session, we can re-validate it on every request with the following new rules:

# # -=[ If Browser Fingerprint JS was sent previously, then enforce the  #     existence of the browser_hash Cookie field. ]=- # SecRule SESSION:FINGERPRINT_CODE_SENT "@eq 1" "chain,id:'981804',phase:1,t:none,block,msg:'Warning: Browser Fingering Cookie Missing.'"         SecRule &REQUEST_COOKIES:BROWSER_HASH "@eq 0"   SecRule SESSION:FINGERPRINT_CODE_SENT "@eq 1" "chain,id:'981805',phase:1,t:none,block,msg:'Warning: Browser Fingering Cookie Mismatch.',logdata:'Expected Browser Fingerprint: %{session.browser_hash}. Browser Fingerprint Received: %{request_cookies.browser_hash}'"         SecRule &REQUEST_COOKIES:BROWSER_HASH "@eq 1" "chain"                 SecRule REQUEST_COOKIES:BROWSER_HASH "!@streq %{session.browser_hash}"

The first rule ensures that the client actually submits the browser_hash cookie data.  If it is missing, then odds are that the client is not a real web browser and is most likely some type of automated program or script.

The second rule ensures that any browser_hash cookie submitted matches the initial browser_hash data we received.  If these browser_hashes do not match, then this means that something hash changed with the browser fingerprint characteristics that we track.  Most likely, it means that this is a different client using the SessionID token.  There is some debug log data that shows processing when a browser mismatch is found:

Rule 100b4ea00: SecRule "REQUEST_COOKIES:BROWSER_HASH" "!@streq %{session.browser_hash}" Transformation completed in 0 usec. Executing operator "!streq" with param "%{session.browser_hash}" against REQUEST_COOKIES:browser_hash. Target value: "ecfd017596" Resolved macro %{session.browser_hash} to: ffa85f45a3 Operator completed in 82 usec. Resolved macro %{session.browser_hash} to: ffa85f45a3 Resolved macro %{request_cookies.browser_hash} to: ecfd017596 Resolved macro %{request_headers.host} to: localhost Warning. Match of "streq %{session.browser_hash}" against "REQUEST_COOKIES:browser_hash" required. [file "/usr/local/apache/conf/crs/base_rules/REQUEST-43-APPLICATION-SESSION-HIJACKING.conf"] [line "45"] [id "981805"] [msg "Warning: Browser Fingering Cookie Mismatch."] [data "Expected Browser Fingerprint: ffa85f45a3. Browser Fingerprint Received: ecfd017596"] [tag "Host: localhost"] Conclusion

With these rules in place, you will be able to more accurately identify potential session hijacking conditions with your application users vs. trying to rely upon client IP address information which may legitimately change during the course of a session (especially if the user is on a mobile device).  It is recommended that these types of rules be used in a collaborative fraud detection configuration.

Categories: web server

Introducing ModSecurity Status Reporting

Tue, 2014-01-28 18:08

The Trustwave SpiderLabs Research team is committed to making ModSecurity the best open source WAF possible.  To this end, we have deployed Buildbot platforms and revamped regression tests for our different ports to ensure code quality and reliability.  But we want to take it even further. The question is, how else can we improve ModSecurity development and support?

To best answer that question, we need some basic insight into the ModSecurity user community:

  • How many ModSecurity deployments are there?
  • What versions of ModSecurity are being used?
  • How many users are running the latest version?
  • What web server platform is ModSecurity used with?

With this sort of information, we could more easily prioritize issue resolution based on the amount of users of each version or feature and deliver new features and fixes more quickly.  To gather this sort of insight, today we are introducing a new real-time status reporting mechanism.   

    Solution – Status Reporting

We are introducing a new DNS-based reporting mechanism to ModSecurity with the inclusion of the "SecStatusEngine" directive.  When enabled, this directive will send the following data to the ModSecurity Project team:

  • Anonymous unique id for host
  • Versions of:
    • Libxml2
    • Lua
    • ModSecurity
    • PCRE
    • Web Server Software

Once the HTTP server is started, ModSecurity gathers this "status" data and then encodes it using Base32. This encoded string is tempered with dots in a given regular space, after that a suffix is added. This suffix is the subdomain "status" which is part of the domain "modsecurity.org". Below it is an example of the information that is transmitted. Figure 1.a. contains  the information in plain text, and the Figure 1.b. contains the very same information encoded. As you can see, it looks like a normal DNS name, except for the length.

Figure 1: (a) Plain/text data; (b) Encoded data.

Here is an example of what would be reporting in the local web server log files upon ModSecurity startup:

[Mon Jan 20 10:55:22.000876 2014] [:notice] [pid 18231:tid 140735189168512] ModSecurity for Apache/2.7.7 (http://www.modsecurity.org/) configured. [Mon Jan 20 10:55:22.000937 2014] [:notice] [pid 18231:tid 140735189168512] ModSecurity: APR compiled version="1.4.6"; loaded version="1.4.6" [Mon Jan 20 10:55:22.000944 2014] [:notice] [pid 18231:tid 140735189168512] ModSecurity: PCRE compiled version="8.32 "; loaded version="8.32 2012-11-30" [Mon Jan 20 10:55:22.000948 2014] [:notice] [pid 18231:tid 140735189168512] ModSecurity: LUA compiled version="Lua 5.1" [Mon Jan 20 10:55:22.000951 2014] [:notice] [pid 18231:tid 140735189168512] ModSecurity: LIBXML compiled version="2.7.8" [Mon Jan 20 10:55:22.001020 2014] [:notice] [pid 18231:tid 140735189168512] ModSecurity: StatusEngine call: "2.7.7,Apache/2.4.4 (Unix),1.4.6/1.4.6, 8.32 /8.32 2012-11-30,Lua 5.1/(null),2.7.8/(null),96ce9ba3c2fb71f7a8bb92a88d560d44dbe459b8" [Mon Jan 20 10:55:22.089012 2014] [:notice] [pid 18231:tid 140735189168512] ModSecurity: StatusEngine call successfully submitted.

ModSecurity will then perform a DNS query to a subdomain under ".status.modsecurity.org", by performing a normal name resolution (DNS lookup).  The DNS protocol was selected as most organizations deploy their web servers behind a firewall with restricted egress filtering that do not allow outbound HTTPs calls or any other kind of connection to the Internet. Although outbound connections are very restrictive from DMZs, DNS queries are often allowed.  We use a special configured tinydns (DNS Server) that responds to all subdomains under the "status.modsecurity.org" domain. Every time that a query is received, the server responds to it by pointing to an IP address, and then it saves the request in the log file. This log file is parsed by a script which decodes the Base32 information and gathers other information, such as date and time of the request. With the information in plaintext, the content is saved in a database.

Once the data is saved in our database, it is exported to a public web page through a JSON API.  Since we don't have any significant data yet, the API is working with very limited information – it basically returns results that were gathered in a given space of time (this time slice can be chosen by the API user). Figure 2. illustrates an example of how the JSON looks. In this particular example, the information between epoch (Unix format) 0 and 1390252267 was requested, this specific set of data was collected from internal tests. The url used to generate this example was: http://status.modsecurity.org/api/0/1390252267. For more information about the API, have a look on the API documentation: https://github.com/SpiderLabs/ModSecurity-status/wiki/API-Documentation

Figure 2. JSON data returned by the API.

The geolocation data presented is based on the IP address of the DNS server that sent the final query to our servers.  This information is not obtained from the server that is actually running ModSecurity.  Assuming that the DNS server is somewhat near the ModSecurity host (in order to avoid latency), it is possible to retrieve the approximate geolocation information without exposing the server/user.  Another concern for the ModSecurity Project team was to decide exactly what data to report. For instance: it is necessary to uniquely identify each server, otherwise we would fail to distinguish between a server that was restarted and a server that just started to use ModSecurity. In order to do that, without retrieving any information about the user, a SHA-1 hash was generated. It uses as input some information extracted from the server, like server name and MAC address of the network device. But, to protect the user's data and privacy, it never exchanges the name or the MAC address in plaintext.  Even with these precautions, users may still be uncomfortable to sharing information.  It is for this reason that this feature is disabled by default.  In order to participate and "opt-in" users have to set SecEngineStatus On within their ModSecurity configuration files.  If you use the modsecurity.conf-recommended file in the modsec_status GitHub branch, this setting is already enabled.  

Status Reporting Map

You are also invited to have a look at our status map. This last piece of the status reporting feature  shows a live listing "heatmap" of servers that are using ModSecurity and can be found at http://status.modsecurity.org. Since we are in beta, we have just a few registrations. Figure 3. illustrates what we do expect to have in a near future (the heatmap was randomly generated).

Figure 3. Example on how the data will be displayed at http://status.modsecurity.org website.

Help Testing

We need help from the community testing this new feature.  Since the code is in a beta state, it is not merged into ModSecurity mainline, but it is available under our GitHub repository in the branch "modsec_status". Don't forget to set SecEngineStatus to On. By using it, you may notice the log entry regarding SecSatusEngine in your error.log.

The code from all the components used by SecStatusEngine (web, scripts, etc.) are open source and published under the SpiderLabs GitHub Repo: https://github.com/SpiderLabs/ModSecurity-status. Patches for ModSecurity itself are available under ModSecurity git repo at: https://github.com/SpiderLabs/ModSecurity.

The next steps we will take in developing this feature will be including charts and a richer API with filters and more data. This will allow us to retrieve more valuable information from this raw data. But first we need some significant raw data because it is very hard to plot any chart without it.

This project is open source. So if you are interested in any particular data from this database, feel free to get your hands dirty and submit a patch or provide suggestions. Both are very welcomed!

This blog was co-authored by Felipe "Zimmerle" Costa and Ryan Barnett.

Categories: web server

ModSecurity Advanced Topic of the Week: HMAC Token Protection

Fri, 2014-01-24 12:40

This blog post presents a powerful feature of ModSecurity v2.7 that has been highly under-utilized by most users: HMAC Token Protection.  There was a previous blog post written that outlined some usage examples here, however we did not properly demonstrate the protection coverage gained by its usage.  Specifically, by using the HMAC Token Protection capabilities of ModSecurity, you can reduce the attack surface of the following attacks/vulnerabilities:

  • Forceful Browsing of Website Content
  • Automated Botnet Attacks
  • Manipulation of Query String Parameters
  • Reflected Cross-Site Scripting
  • Cross-Site Request Forgery (CSRF) Protection
Excerpts of this blog post will discuss Recipe 1-2: Preventing Data Manipulation with Cryptographic Hash Tokens from my book "Web Application Defender's Cookbook: Battling Hackers and Protecting Users".   Recipe 1-2: Preventing Data Manipulation With Cryptographic Hash Tokens

This recipe will show you how to use ModSecurity to implement additional hash tokens to outbound html data in order to prevent data manipulation attacks.  At the time of writing this book, the capabilities outlined in this recipe are available in ModSecurity version 2.7.  Future versions may have different or extended functionality.

Ingredients

Background

Web developers cannot rely upon web browser security mechanisms to prevent data manipulation.  With this being the case, how can we implement an external method of verifying that outbound data has not been manipulated when returned in a follow-up request?  One technique that can be used is to parse the outbound html response body data, calculate digest hashes for content and then inject additional token data into select locations.  The data that we are injecting are called request parameter validation tokens and are essentially cryptographic hashes of select html page elements.  The hashes enable us to detect if the client attempts to tamper with the data.  

Example Configuration

Here are some example ModSecurity directives and rules that implements basic hashing protections:

SecDisableBackendCompression On
SecContentInjection On
SecStreamOutBodyInspection On
SecHashEngine On
SecHashKey rand
SecHashParam "hmac"
SecHashMethodrx "HashHref" "\.(aspx?|php)"
SecHashMethodrx "HashFormAction" "\.(aspx?|php)"
SecRule REQUEST_URI "@validateHash \.(aspx?|php)" "phase:2,id:1000,t:none,block,msg:'Hash Validation Violation.',ctl:hashEnforcement=On,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}"

The first directive called SecDiableBackendCompression is only needed in a reverse proxy setup and is used if the web application is compressing response data in the gzip format.  This is needed so that we can parse the response html data and modify it.  ModSecurity’s default configuration is to only make copies of transactional data in memory and inspect them while buffering the real connection.  The next two directives are used together, however, to be able to modify and fully replace the original buffered response body with the new one.  The next four SecHash directives configure the basic settings.  In this configuration, ModSecurity will use a random encryption key as the hash salt value and will also use the REMOTE_ADDR of the client as an additional item in the hash calculation. It will then hash HTML  HREF and Form Action components that match the defined regular expression.  In this example, we are only applying these protections to web pages with .php, .asp and .aspx file extensions.  The final SecRule is used for validation and enforcement of the hash tokens. 

A Practical Example Walk-Through

For our example web application, we will be using the public demo web application Acuart.  When a client requests the main webpage through ModSecurity with the Hash token protections, this is what the debug log shows when processing the returned HTML data to the client:

Starting phase RESPONSE_HEADERS.
This phase consists of 8 rule(s).
Content Injection: Nothing to inject.
Output filter: Bucket type TRANSIENT contains 1251 bytes.
Output filter: Receiving output (f 10a803d38, r 10a8020a0).
Output filter: Bucket type TRANSIENT contains 2845 bytes.
Output filter: Receiving output (f 10a803d38, r 10a8020a0).
Output filter: Bucket type EOS contains 0 bytes.
Output filter: Completed receiving response body (buffered full - 4096 bytes).
init_response_body_html_parser: assuming ISO-8859-1.
init_response_body_html_parser: Successfully html parser generated.
Signing data [privacy.php]
Signing data [AJAX/index.php]
Signing data [guestbook.php]
Signing data [userinfo.php]
Signing data [login.php]
Signing data [cart.php]
Signing data [artists.php]
Signing data [categories.php]
Signing data [AJAX/index.php]
Signing data [guestbook.php]
Signing data [cart.php]
Signing data [disclaimer.php]
Signing data [artists.php]
Signing data [categories.php]
Signing data [index.php]
Signing data [search.php?test=query]
hash_response_body_links: Processed [0] iframe src, [0] hashed.
hash_response_body_links: Processed [0] frame src, [0] hashed.
hash_response_body_links: Processed [1] form actions, [1] hashed.
hash_response_body_links: Processed [23] links, [15] hashed.
inject_hashed_response_body: Detected encoding type [ISO-8859-1].
inject_hashed_response_body: Using content-type [ISO-8859-1].
inject_hashed_response_body: Copying XML tree from CONV to stream buffer [4733] bytes.
inject_hashed_response_body: Setting new content value 4733
inject_hashed_response_body: Stream buffer [4733]. Done
Hash completed in 3215 usec.

As you can see from this logging output, ModSecurity dynamically inserted hmac hashes for 15 HREF links and 1 Form action in the web page.  Here is how this appears to the user when they mouse over links in the web page:

Notice the link now has a new "hmac" parameter value appended to the end.  When the client makes subsequent requests, ModSecurity will ensure the following:

  1. HMAC Token Exists - the request includes an hmac parameter token value.  If the hmac token is missing, an attacker be attempting to bypass the protections by stripping out the token altogether.
  2. HMAC Token Mismatch - That the hmac value submitted in the requests matches the re-calculated server-side value within ModSecurity when it analyzes the live HTTP request data. 

If either of these scenarios happen, then ModSecurity will generate alerts.  Let's look at the real-world attack scenarios listed at the beginning of the blog post to see how this works.

Forceful Browsing Attacks

In the Acuart demo website, there is a Forceful Browsing attack/vulnerability with the "showimage.php" resource.  Under normal circumstances, this is how the resources is accessed:

The resource has one parameter called "file" and it is supposed to be used to access image files.  The attacker, however, is able to change the data in the "file" parameter to access other files such as the Database Connection config file:

If an attacker attempts to send that specific request, ModSecurity will generate the following event:

Rule 10094a408: SecRule "REQUEST_URI" "@validateHash \\.(aspx?|php)" "phase:2,log,tag:%{request_headers.host},id:1000,t:none,block,msg:'Hash Validation Violation.',ctl:hashEnforcement=On,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.msg=%{rule.msg},setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}"
Transformation completed in 1 usec.
Executing operator "validateHash" with param "\\.(aspx?|php)" against REQUEST_URI.
Target value: "/showimage.php?file=./database_connect.php"
Request URI without hash parameter [/showimage.php?file=./database_connect.php]
Operator completed in 83 usec.
Ctl: Set HashEnforcement to On.
Setting variable: tx.anomaly_score=+%{tx.critical_anomaly_score}
Recorded original collection variable: tx.anomaly_score = "0"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: anomaly_score=0+5
Set variable "tx.anomaly_score" to "5".
Setting variable: tx.msg=%{rule.msg}
Resolved macro %{rule.msg} to: Hash Validation Violation.
Set variable "tx.msg" to "Hash Validation Violation.".
Setting variable: tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}
Resolved macro %{rule.id} to: 1000
Resolved macro %{matched_var_name} to: REQUEST_URI
Resolved macro %{matched_var} to: /showimage.php?file=./database_connect.php
Set variable "tx.1000-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-REQUEST_URI" to "/showimage.php?file=./database_connect.php".
Resolved macro %{request_headers.host} to: testphp.vulnweb.com
Warning. Request URI matched "\\.(aspx?|php)" at REQUEST_URI. No Hash parameter [file "/usr/local/apache/conf/crs/base_rules/REQUEST-00.conf"] [line "10"] [id "1000"] [msg "Hash Validation Violation."] [tag "testphp.vulnweb.com"]

The attacker attempted to to simply remove the hmac token parameter altogether and this is a violation.  In the event that the attacker includes an hmac token, it would generate the following event data:

Rule 10094a438: SecRule "REQUEST_URI" "@validateHash \\.(aspx?|php)" "phase:2,log,tag:%{request_headers.host},id:1000,t:none,block,msg:'Hash Validation Violation.',ctl:hashEnforcement=On,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.msg=%{rule.msg},setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}"
Transformation completed in 0 usec.
Executing operator "validateHash" with param "\\.(aspx?|php)" against REQUEST_URI.
Target value: "/showimage.php?file=./database_connect.php&hmac=c7857949531753f07f692db8cb446d6233ed5a5d"
Validating URI /showimage.php?file=./database_connect.php size 42
Signing data [showimage.php?file=./database_connect.php]
Operator completed in 160 usec.
Ctl: Set HashEnforcement to On.
Setting variable: tx.anomaly_score=+%{tx.critical_anomaly_score}
Recorded original collection variable: tx.anomaly_score = "0"
Resolved macro %{tx.critical_anomaly_score} to: 5
Relative change: anomaly_score=0+5
Set variable "tx.anomaly_score" to "5".
Setting variable: tx.msg=%{rule.msg}
Resolved macro %{rule.msg} to: Hash Validation Violation.
Set variable "tx.msg" to "Hash Validation Violation.".
Setting variable: tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}
Resolved macro %{rule.id} to: 1000
Resolved macro %{matched_var_name} to: REQUEST_URI
Resolved macro %{matched_var} to: /showimage.php?file=./database_connect.php&hmac=c7857949531753f07f692db8cb446d6233ed5a5d
Set variable "tx.1000-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-REQUEST_URI" to "/showimage.php?file=./database_connect.php&hmac=c7857949531753f07f692db8cb446d6233ed5a5d".
Resolved macro %{request_headers.host} to: testphp.vulnweb.com
Warning. Request URI matched "\\.(aspx?|php)" at REQUEST_URI. Hash parameter hash value = [c7857949531753f07f692db8cb446d6233ed5a5d] Requested URI hash value = [6c1ee35d09112aba381a4aae49eed9620585f2b2] [file "/usr/local/apache/conf/crs/base_rules/REQUEST-00.conf"] [line "10"] [id "1000"] [msg "Hash Validation Violation."] [tag "testphp.vulnweb.com"]

This event shows that ModSecurity identified a mismatch between the hmac token hash submitted vs. the one that it calculates based on the actual request data.  

Forceful Browsing Using Automation

If an attacker tries to use tools to automate the enumeration of resources on the site, this activity can also be blocked.  For example, if an attacker tries to use a tool such as the OWASP Zed Attack Proxy's (ZAP) "Forced Browse" Plugin, these requests will be denied as the tool is not following URL links that the web application provided to the end user and are thus missing hmac tokens.  Here is an example screenshot of ZAP's Forced Browse session where the requests were blocked by ModSecurity's Hash Token engine:

Automated Botnet Attacks

In a previous blog post, I outlined the typical Botnet recuitement lifecycle:

In Step2 2, the Botnet client conducts Search Engine queries to try and identify websites that might be vulnerable to specific, widespread vulnerabilities.  Based on those results, the Botnet client will then send pre-crafted attack payloads to the target website.  Here is an example of some attack code functions found within a typical perl-based IRC Botnet client that send PHP code injection payloads:

The highlighted sections of code show that the Botnet client is sending these attack payloads directly to the URL returned from the Search Enginer results for a target site.  If a Botnet client blindly sends attacks at URLs they will blocked by the ModSecurity Hash Token protections due to missing hmac tokens.  

Query String Injection Attacks

SQLi in Query String Parameter

The Acuart "artists.php" resource has an SQL Injection vulnerability.  The following screenshot shows an SQLi attack in the "artists" parameter that successfully enumerates the DB user:

This is how the normal HREF link to this page looks in the HTML:

As you can see, the HREF link already includes the parameter "artists=1" data.  When the user clicks on the link, it sends that parameter to the web app.  In this case, that parameter is used, insecurely, within a back-end SQL query.  With the ModSecurity HMAC token protection in place, however, that same HTML now looks like this:

If an attacker tries to tamper with the artists data and send this same SQLi request through ModSecurity with the hmac token protections, it will be blocked.  This event will be generated if they do not supply an hmac token:

[Thu Jan 23 17:07:04.692542 2014] [:error] [pid 38405:tid 4453466112] [client 127.0.0.1] ModSecurity: Access denied with code 403 (phase 2). Request URI matched "\\\\.(aspx?|php)" at REQUEST_URI. No Hash parameter [file "/usr/local/apache/conf/crs/base_rules/REQUEST-00.conf"] [line "10"] [id "1000"] [msg "Hash Validation Violation."] [tag "testphp.vulnweb.com"] [hostname "testphp.vulnweb.com"] [uri "http://testphp.vulnweb.com/artists.php?artist=0+div+1+union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A1%2C2%2Ccurrent_user"] [unique_id "UuGSh8CoAWcAAJYF7zQAAADT"]

This is an event if they have an hmac but try and inject the SQLi payload into the "artists" parameter value:

[Thu Jan 23 17:14:53.335440 2014] [:error] [pid 38405:tid 4447563776] [client 127.0.0.1] ModSecurity: Access denied with code 403 (phase 2). Request URI matched "\\\\.(aspx?|php)" at REQUEST_URI. Hash parameter hash value = [a5e6d5e6653b8cefa4681ed86fd6f4ef71701d45] Requested URI hash value = [663886560b52de38ca40323c27c2ebd6545474cf] [file "/usr/local/apache/conf/crs/base_rules/REQUEST-00.conf"] [line "10"] [id "1000"] [msg "Hash Validation Violation."] [tag "testphp.vulnweb.com"] [hostname "testphp.vulnweb.com"] [uri "http://testphp.vulnweb.com/artists.php?artist=+div+0+union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A1%2C2%2Ccurrent_user&hmac=a5e6d5e6653b8cefa4681ed86fd6f4ef71701d45"] [unique_id "UuGUXMCoAWcAAJYF7zgAAADI"]

It is important to note that this defense is aimed at reducing the attack surface of pre-populated query_string parameter data and won't protect against all injection point vectors (such as those sent in POST payload parameter fields).

Cross-Site Scripting (XSS)

The Acuart demo app has a number of XSS flaws including one in the "searchFor" parameter of the "search.php" page:

When an attacker (or victim) sends a request such as this to the search page, the data is refected back within the response executes the JS code:

Since this XSS vector occurs over a POST request, an attacker could create the following HTML code on a different site/page to auto-submit this data:

How can the ModSecurity HMAC Token mechanism protect against this attack vector?  

Notice the HTML Form "action" data highlighted in red?  This is the location where the form will POST data to.  This is important.  One of the key requirements of this attack is that the target URL must be idempotent.  This means that the attacker must know what URL location to use ahead of time to send the XSS payload to.  This is where the Hash Token defense comes into play.  

Non-Idempotent (Unique) URLs

When the SecHashMethodrx "HashFormAction" "\.(aspx?|php)" directive is used, the search Form action data is updated to include the hmac token:

 In order to defeat these types of Reflected XSS attacks, we can modify our SecHashKey directive settings to include additional data such as the client's IP Address or the current applicaton SessionID data: SecHashKey rand SessionID.

SecDisableBackendCompression On
SecContentInjection On
SecStreamOutBodyInspection On
SecHashEngine On
SecHashKey rand SessionID
SecHashParam "hmac"
SecHashMethodrx "HashHref" "\.(aspx?|php)"
SecHashMethodrx "HashFormAction" "\.(aspx?|php)"
SecRule REQUEST_URI "@validateHash \.(aspx?|php)" "phase:2,id:1000,t:none,block,msg:'Hash Validation Violation.',ctl:hashEnforcement=On,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/PARAM_MANIPULATION-%{matched_var_name}=%{matched_var}"

With this updated configurtion - every hmac is unique for each user/session.  Here is how the updated debug log processing looks:

Starting phase RESPONSE_HEADERS.
This phase consists of 8 rule(s).
Content Injection: Nothing to inject.
Output filter: Bucket type TRANSIENT contains 1251 bytes.
Output filter: Receiving output (f 10a803d38, r 10a8020a0).
Output filter: Bucket type TRANSIENT contains 2845 bytes.
Output filter: Receiving output (f 10a803d38, r 10a8020a0).
Output filter: Bucket type EOS contains 0 bytes.
Output filter: Completed receiving response body (buffered full - 4096 bytes).
init_response_body_html_parser: assuming ISO-8859-1.
init_response_body_html_parser: Successfully html parser generated.
Signing data [privacy.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [AJAX/index.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [guestbook.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [userinfo.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [login.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [cart.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [artists.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [categories.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [AJAX/index.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [guestbook.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [cart.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [disclaimer.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [artists.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [categories.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [index.php]
Using session id [wecm5b45fsznvm552hzoz3bl]
Signing data [search.php?test=query]
Using session id [wecm5b45fsznvm552hzoz3bl]
hash_response_body_links: Processed [0] iframe src, [0] hashed.
hash_response_body_links: Processed [0] frame src, [0] hashed.
hash_response_body_links: Processed [1] form actions, [1] hashed.
hash_response_body_links: Processed [23] links, [15] hashed.
inject_hashed_response_body: Detected encoding type [ISO-8859-1].
inject_hashed_response_body: Using content-type [ISO-8859-1].
inject_hashed_response_body: Copying XML tree from CONV to stream buffer [4733] bytes.
inject_hashed_response_body: Setting new content value 4733
inject_hashed_response_body: Stream buffer [4733]. Done
Hash completed in 3215 usec. 

In essence, what this means is that an attacker can no longer copy/paste attack code including an hmac token and force another user to use it.  This means that this defense can also help to prevent Cross-Site Request Forgery (CSRF) attacks as the hmac tokens function similarly to anti-CSRF tokens.

Conclusion

Hopefully this blog post has demonstrated the power provided by the HMAC Token protections in ModSecurity WAF.  By deploying these configurations, you can significantly reduce your attack surface for a number of issues.  If you have any feedback or questions, please contact the ModSecurity Project Team.

Categories: web server

Setting HoneyTraps with ModSecurity: Adding Fake HTML Comments

Tue, 2014-01-14 13:35
This blog post continues with the topic of setting "HoneyTraps" within your web applications to catch attackers.  Please review the previous posts for more examples: This blog post will discuss Recipe 3-3: Adding Fake HTML Comments from my book "Web Application Defender's Cookbook: Battling Hackers and Protecting Users".   Recipe 3-3: Adding Fake HTML Comments

This recipe will show you how to add fake HTML comment data that may be flagged if ever accessed or used by a client.

Ingredients

HTML Comments

The Hypertext Markup Language provides a syntax which allows developers to embed comment information within the html code.  The HTML RFC states the following:

3.2.4 Comments

HTML comments have the following syntax:

<!-- this is a comment -->

<!-- and so is this one,

    which occupies more than one line -->

White space is not permitted between the markup declaration open delimiter("<!") and the comment open delimiter ("--"), but is permitted between the comment close delimiter ("--") and the markup declaration close delimiter (">"). A common error is to include a string of hyphens ("---") within a comment. Authors should avoid putting two or more adjacent hyphens inside comments.

Information that appears between comments has no special meaning (e.g., character references are not interpreted as such).

Note that comments are markup.

While the intended purpose of this functionality is to be helpful, it often divulges sensitive data.  Let’s look at a practical example. 

During the reconnaissance phase, an attacker will most likely run an automated spidering tool against the site.  They can then review various elements of the site off-line and look for pieces of sensitive information.  For example, Figure 3-1 shows the Burp Suite Pro application assessment tool.

Figure 3-2: Burp Suite’s Engagement Tool Find Comments 

This screenshot demonstrates how to use the find comments action of the engagement tools interface.  This will search through any saved HTTP transactional data.  Figure 3-2 shows some example output with various html comment data.

Figure 3-3: Burp Suite’s Find Comments Search Results

While the html comments show here are rather innocuous, there are other examples that are not.  Figure 3-3 shows an example where the web developer has decided to place stack trace debugging information within the html comments.

Figure 3-4: Stack Trace Data Inside HTML Comment

This information should never be sent to a client as it exposes the inter-workings of the application.  With this data, an attacker may be able to better plan and execute attacks against your web application.  

Adding Fake HTML Comments with ModSecurity

Building upon the configuration in the Adding Fake robots.txt Entries configuration, we can add another ModSecurity directive called SecStreamOutBodyInspection:

SecContentInjection On SecStreamOutBodyInspection On

This directive will place the normal RESPONSE_BODY variable data (HTML) into a re-allocatable buffer which allows us to modify and re-inject this buffer back into the response body stream.  In layman’s terms, this directive allows us to be able to modify outbound response data. 

Now that we have the capability to dynamically insert our own data, we need to choose a good location to deploy our honeytrap HTML comment.  An ideal candidate is to seed any login pages with this fake data as attackers are sure to focus their attention in this location.  Figure 3-4 shows the html for an example login page.

Figure 3-5: Example DVWA Login Page HTML

Note the highlighted FORM tag data in the html source code?  That is going to be our key data element to use as our injection point.  We can then use the following ruleset to insert out honeytrap html comment data directly in front of the open FORM tag:

SecRule REQUEST_FILENAME "@streq /dvwa/login.php" "chain,id:'999007',phase:4,t:none,nolog,pass,setvar:'tx.form_comment_honeytrap=<form action=\"login.php\" method=\"post\">'"        SecRule STREAM_OUTPUT_BODY "@rsub s/%{tx.form_comment_honeytrap}/<!-- DEBUG - the source code for the old login page is login.php.bak -->%{tx.form_comment_honeytrap}/d"

The key piece of data to focus on is in the second SecRule where the @rsub operator is using macro expansion to do our data substitution and prepending our honeytrap comment information.  With this rule in place, Figure 3-5 shows how the new html data looks.

Figure 3-6: Fake HTML Comment Data

Now that we have set our trap, we must create a separate ModSecurity rule that will identify if a client ever attempts to access the fake login.php.bak page.

SecRule REQUEST_FILENAME "@streq /login.php.bak" \   "id:'999008',phase:1,t:none,log,block,msg:'HoneyTrap Alert: Fake HTML Comment Data Used.',setvar:ip.malicious_client=1"

If this alert ever triggers, you know that the client is reviewing HTML source code and inspecting comment data.  You can then choose how to react to client based in this intel.  In the example rule, we are setting a new local variable "malicious_client" to the IP-based persistent storage collection.  This flag will allow you react as you want whenever the client returns to the site.  Perhaps you want to simply create audit logs of this user's activities or optionally proxy their connections off to some other honeypot web application.  The response actions are varied however the key is that you were able to use this honeytrap to identify the suspicious disposition of this user.

Conclusion

Hopefully this blog post has give you ideas on how you might implement similar types of fake HTML comments to entice and track would-be attackers on your site.  Make sure to use variation in the types of data that you use in your honeytraps so that it will not be easy to identify.  Examples can include:

  • HTML comments contained links to hidden (unlinked) directories
  • Backup files (e.g. - with .orig extensions)
  • Authentication credentials for a test or debug account.  Don't laugh.  We have seen this more than once...
Good luck combating attackers on your site!
Categories: web server