Fuzzing and Brute force.
Fuzzing and Brute force are two automated methods of discovering vulnerabilities, endpoints or parameters in a target.
Both methods attempt to do the same thing, supply the target with a large number of possible inputs, and check the output for unexpected behavour.
As such the terms tend to be used interchangeably, however there are subtle differences in the approach and the level of automation.
Brute Force
A Brute Force attack will take a list of possible inputs, and try each of them against the server looking for positive responses. The success or failure of the attack will depend on the list of inputs supplied to the brute forcer.
Brute Force Example
The Classic example for bruteforce is password cracking. Here we try to gain access to a system by trying each item in a list of passwords until we get success
There are several types of brute force attack:
Simple Brute Force
In this approach we simply try every possible combination of input characters until we get a result.
For example if we were trying to crack a password we could try A then B the C:
- A
- B
- C
- .... (And the rest of the printable characters)
- AA
- AB
They are useful for guessing simple or short passwords, but with longer items can take a long time, as the number of guesses is the length of the password to the power of the search space.
Important
Password complexity is one reason why you are asked for letters, numbers and symbols in your passwords. You can see from the table below, that increasing the complexity of the password, makes a big difference to the maximum possible combinations. (However, its still not as much of a difference as length)
Input Set | Search Space | Possible Combinations in 4 letter password2 | Possible combinations in 5 symbol password \(n^5\) |
---|---|---|---|
lower case | \(26\) | $ 26^4 = 456,976$ | \(11,881,376\) |
UPPER and lower case | \(26+26 = 52\) | $52^4 7,311,616 $ | \(380,204,032\) |
All Letters and Numbers | $26+26+10 = 62 $ | \(62^4 14,776,336\) | \(916,132,832\) |
Letter Numbers and top row Symbols | \(26+26+10+10 = 72\) | \(72^4 26,873,856\) | \(1,934,917,632\) |
All printable | $96 | \(92^4 84,934,656\) | \(6,590,815,232\) |
The advantage of the simple brute force is that it allows us to discover items without using a list.
By trying every possible combination, theoretically, we will find the value3
Dictionary Based attacks.
Arguably the most common brute force attack is the dictionary attack. Here we build a list of possible inputs then work through the list using each item as input.
Dictionary attacks against some systems can be pretty effective. We will look at directory busting for enumerating websites in the next page.
One drawback of dictionary attacks is building the dictionary itself. For the attack to work, we need to have a realistic set of possible inputs. Sources like Seclists (see below) , can be useful here.
Password Mutation
Because of password policy, raw dictionary attacks are less useful against passwords. Unless the password list contains the exact combinations used, then the attack will not find it.
To work around this we can use tools to "muate" the password lists. These will make common subsitutions, to help the inputs meet the password criteria, and generate a new list for the brute force attempt.
As users, we also don't really help ourselves here. People commonly l33t'ify passwords, swapping teh same set of letters for the other symbols.
- a / @ /4
- s / 5
Additionaly, 1! or 2021!" is a common ending to a dictionary word, so adding combinations like this can be useful.
Reverse Brute forcing / Credential Stuffing
Rather than focus on one user, Reverse brute force takes a commonly used password and attempts to use it on many user accounts. Like a dictionary attack it relies on the fact that people only use a small(ish) number of words for passwords, and that some may be more common than others.
Credential Stuffing is similar, but focuses on a specific user. Once a username / password combination has been identified, it is checked against several sites to see if there is a match. This can be useful in the case of password reuse.
Rainbow Tables
Rainbow tables are a special case of brute force attacks, that can work with hashed, but unsalted passwords.
Rather than attempt to brute force the password "Live", we make use of pre-calculated hash values for words in a dictionary. This means that we only have to crack the hashes once, store the result, then use the stored values to lookup the plaintext for the hash.
Fuzzing
I like to think of Fuzzing as a slightly more intelligent version of brute force. Here the inputs will be modified based on the outputs observed. This means that the fuzzer can "learn" about the target system and modify its behaviour to reduce the workload, and / or increase the chance of success. Depending on the application we are attacking the inputs may be items such as wordlists, or could be pseudorandom input.
Fuzzing has two main uses
Identifying Edge Cases where the System Breaks
The Original use of Fuzzing was to identify inputs that could make a system crash, behave in unexpected ways, or just degrade the user experience.
In this case the Fuzzer supplies a load of potentially invalid, or random inputs to the program.
The whole idea here is to identify edge cases where the input is not handled correctly4.
Example
Consider a Month selection dropdown in a form. If the user enters a valid month the system should behave as expected.
However if the user manipulates the form data and enters:
- Swordfish
- 1
- ¯_(ツ)_/¯
<script>alert(1)</script>
We will either get a crash (and possibly a helpful error message), or invalid data will be accepted by our application, which may cause a security issue later.
Fuzzing is also important in identifying a trust boundary, we know that client side checks are helpful for the user, but useless for security. So if the backend trusts data based on client side verification, we could have a problem. If an attacker can get past the checks made, then they can insert malicious input.
Learning More about how a system handles data
Another use of Fuzzing is to see how the system behaves for a given input. This lets us understand any filtering or sanitisation approaches used, and start to identify possible payloads.
The classic example here is with a buffer overflow. We know we need to identify the point where the overflow occurs, so we can take two5 approaches:
- A Pure Brute force, where we try increasing the number of characters by one until we get a crash.
- Fuzzing via a Binary Search, where we use the "feedback" from the program to help shape our inputs. Here Pick a likely value, then increase or decrease the number of characters in the buffer depending on whether we get a crash or not. This helps us quickly narrow in on the required number of bytes.
Another approach with Fuzzing is to try a set of likely inputs, discarding those that we don't have any success with.
This again helps us to build a picture of how any filters etc work.
Here we might use our input to look at how special characters (such as <, >, #, "
) are handled,
by examining how they are represented when the input is returned to us.
Example
The approach used by SQLMap is a good example of Fuzzing to learn about a system.
SQLmap uses a set of known SQL Injection strings to help it fingerprint the database server and the types of response that get a positive injection. This allows it to reduce the search space, limiting the attempts to only those inputs that are likely to work with a given database engine.
Getting Wordlists for Brute Forcing
There are many well known password lists, such as rockyou included in pen-testing distributions like Kali or Parrot. There are also on-line collections of wordlists and payloads. My personal favourite is Seclists, which has lists for things like:
- Common and Default Passwords
- Website Discovery
- XSS and SQLi payloads
Another useful site is Payloads All of the Things which contains command lists, and tips and tricks for enumeration and vulnerability scanning. Its a little bit brief, so expect to google to tools if you haven't used them before, but its an excellent cheat sheet if you cant remember a command.
Summary
In this article we had an introduction to Fuzzing and Brute force. These approaches give us a way to test inputs to an application, identifying areas of interest in the input.
Brute force approaches make use of a pre-developed list of information, and will work through the list one item at a time This can be useful for cracking password hashes, or trying a large list of possible "bad" inputs in the case of attacks like SQL Injection, or XSS.
Fuzzing often adds an element of intelligence to the pure brute force. Modifying the input strings based on the output we are given to help identify payloads. It is often used to find types of input that are not handled by the application.
In the next article we will look at using brute force to identify "hidden" pages in a website.
-
Its a huge list, but the attacks are build from known approaches. ↩
-
Password Entropy is probably a better fit here, but its a bit harder to explain. ↩
-
Possibly after the heat death of the universe.. ↩
-
Bill Sempf: When your tester walks into a bar ↩
-
Yes I know its three if we use pattern create. But a binary search lets us get in the right ballpark for the pattern. ↩