MD5 Brute forcer

This is a multithreaded MD5 brute force program, which I wrote in 2004, yet is still usable over a decade later. It finds passwords that have been encrypted with MD5 by trying every possible combination until it finds a match. Ironically it is a good example of how inefficient this method is. It is a good program to understand how threading works on dual CPU and hyperthreaded computers. With the built in MD5 passwords it can also be used to benchmark a computer's speed.

[Note from 2016: I wrote this program 12 years ago, yet I still occasionally see MD5 used to encrypt passwords nowadays, which even in 2004 wasn't a good security practice. Who encrypts with MD5? Answer: No one, as it's not a form of encryption. These days, using MD5 for encryption is only slightly better than using Base64 or Rot13. Anyone using it for security is demonstrating that they have no idea what they're doing. Although my program still works, it is slow compared to other modern brute forcing software. I still think my program is easier to use than a lot of modern alternatives though. One of the quickest ways to solve MD5s these days is just to Google the hash.]

To try every combination of the (English) lowercase alphabet for words up to 8 letters in length can take over 35 hours on a P4 2.8Ghz HT. To try uppercase letters at the same time would take over a year. This program shows why, when choosing your own passwords, it is a good idea to use a mixture of uppercase and lowercase letters with punctuation. A good password should be more than 8 characters long, contain uppercase and lowercase letters, numbers and punctuation. A bad password such as "apple", which consists of just lowercase letters, will take a fraction of a second to solve. To solve the password "91clBhDY@" would require using uppercase and lowercase letters, numbers and punctuation, and would literally take years to find, by which time it should have been changed anyway. The more character sets a password contains, the harder it is to brute force.

This program was written as a project to try out threading, optimisation and general programming, rather than just as a means to crack MD5 passwords. I could have just as easily got it to work out primes, but MD5 is easier and more interesting. The display part owes a lot to my predictive text program. It is a perpetual beta version - it should do everything it is supposed to do, except the distribution part is inaccurate when using the "1 UC at a time" or ">1 UC at a time" options. It may not be the fastest program, but it rarely crashes.

The MD5 encryption routine this program uses is based on the C source code in RFC1321 by RSA Data Security. (The "RSA Data Security, Inc. MD5 Message-Digest Algorithm").

Download it here (13.4 KB) 32-bit for Windows 98, ME, NT4, 2K, XP, Vista, 7, 10 (and presumably 8?). It will run on any Intel based CPU from Pentium Pro upwards.

Written by me, Tim Warriner, in assembly language 21/02/2004 (except for the MD5 Message-Digest Algorithm which was written by RSA Data Security 1991-2).
Don't use this program for immoral or illegal purposes...

[Note that some antivirus programs (previously Norton and Sophos) think this is a virus, but it isn't. I think they are confused by the fact it was written in assembly language. If it were a virus I wouldn't have put my name on it. Because the program cracks MD5s, which is a practice that is sometimes frowned upon, some antivirus companies flag it anyway when doing scans, even though it is incapable of doing anything malicious.]

The main dialog:

The program whilst working:

The results dialog on completion:

The results dialog when aborted:


It will try every possible permutation of letters, for words up to the size you choose, against one or more MD5 strings.

It lets you choose the character set to make the permutations from.

You can choose to split the work over more than one thread. In this case if you have multiple CPUs or hyperthreading it will complete the work a lot faster. (2 threads may be about 1.5 times faster than 1 thread if you have 2 processors).

If you have several computers you can split the work between them which will speed up the work dramatically. You can split the work between up to 10 computers. (2 identical computers will complete the work twice as fast).

If the program is aborted it provides a key that you can enter to resume from the point it reached.

How to use the basic options:

1: Enter the MD5 codes you want to use by pressing the "Set Codes" button.

2: Enter the maximum string length you want in the "Max string length" box.

3: Choose the number of threads you want to use. If you have only one processor or don't have hyperthreading you should choose 1 here. If you don't know what you've got then choose 1.

4: Choose the character sets you want to use. You can only enter lowercase letters in the "Lowercase" box, but you can enter any characters in the other boxes. You have to tick the one or more character sets you want to use.

5: Press "Start" to start.

Advanced Options:

The "1 UC at a time" switch is the same as using the lowercase character set, but in every word it uses, it will also capitalise each letter once at a time.
e.g. "abc", "Abc", "aBc", "abC"

The ">1 UC at a time" switch is equivalent to using the same letters in both the lowercase and uppercase character sets, although it will work fractionally quicker.
e.g. "abc", "abC", "aBc", "aBC", "Abc", "AbC", "ABc", "ABC"

Resume key: when you abort a session early you will get given a hex number that you can enter in this box to carry on from where you left off. You can also enter here the code you get given from the "distribute" section.

End key: when you use distribute you get given a resume key and an end key - enter the end key in this box.

This lets you split the work between several computers to get it done faster.
1: Set up each copy of the program on each computer with the same settings that you want to use in the project. (The number of threads used can be different).
2: Run each copy of the program for about 1 minute so you can get a good idea of the speed of that computer with the settings you have chosen. When you abort each program you will see a "strings/second for all threads" box.
3: In the distribute part of one program enter the strings/second results for each computer. Remember which str/sec relates to which computer. If you had already started work, or you want to further split the work, you can enter the start and end points of the section you want to do in the "Start From" and "End at" boxes.
4: Press the "Generate" key - the start points (Resume key) and end points (End key) for each computer will be calculated so that the work can be split fairly between them. Faster computers will get assigned more strings to do than the slower computers. Each computer will take the same amount of time to do its share of the work.
5: Note down the numbers, then enter the resume keys and end keys on each computer. (You will have to go back to the main page on the computer that did the calculations).
6: Press "Start" as you would normally.

NOTE: the distribute does not necessarily distribute evenly when you use the "1 UC at a time" or ">1 UC at a time" options. This is something I may fix sometime, but probably won't.

The distribution dialog:


The lowercase box can contain the following letters: "abcdefghijklmnopqrstuvwxyz" and "". These are the characters that have corresponding capital letters. The reason for this is to do with the Uppercase options. [The program was written before I appreciated how non-Latin characters are encoded - Therefore it might work ok with Russian or Central European text, but I doubt that the 1UC tick boxes will do anything useful.]

The maximum string length can only be between 2 and 15.

The total number of characters in the character sets you are using has to be below 254. (There are only 255 ASCII characters anyway, and some of those are control codes so this isn't too bad).

It starts up with a default set of useful characters. The upper and lowercase alphabets are arranged in the order of their frequency in the English language. Therefore if you miss off the last few letters you will significantly decrease the time it takes to complete, whilst only fractionally reducing the probability that the solution you seek is in your chosen character set.

You can have between 1 and 768 MD5 codes entered. (If 768 seems an odd number to choose it's because it's 300h in hex which is a nice round number).

If you choose more threads than you have logical processors for, it doesn't do anything bad but it won't give you any speed increase. If it looks like the program will take hours to complete, it may be sensible to check to see if changing the number of threads being used speeds things up at all.

If you choose options that would result in the program having to test more than 2^63 strings, it will complain and you will have to rethink your options. The first reason for this is that 2^63 is just under what can fit in a qword, and I would have to rewrite the program to take into account such numbers. The second (and more important) reason for this, is that at a typical speed it would take over 32,000 years to complete. If it were possible to run the program for this long, it would still be slightly pointless as faster computers in years to come would complete the work sooner. Apart from everyday life being slightly different in 32,000 years, getting the solution "ZZZZZZZZZZZZZZZ" may not really be that relevant to whoever is there to see it.

If you choose as many threads as you have logical processors, and set the priority in Windows Task Manager to "Realtime" your computer will probably freeze. As a safeguard if you choose 4 threads and set the priority to "Realtime" before you press start, the priority will be returned to "Normal".

It is unlikely that Windows will be able to split the work between the threads identically, therefore for long sessions some threads may finish slightly before others.

The progress bar is normally green in colour, but when you use a resume or end key it will be a nice red colour.

The program won't include any time it spent hibernated in its time statistics. When the computer is hibernated the program makes sure its priority is set to "Normal" to avoid delaying the hibernation.

The results are given in a mixture of hex and decimal. Because the numbers involved can become so big, they are easier to read when represented in hex.


It is quicker to enter more than one MD5 string, than to enter one and run the program many times.

There is little point in distributing the work between more than one computer if it is only going to take a few minutes anyway.

It is fractionally quicker to use the >1uc rather than have just the whole lc alphabet and the whole uc alphabet and nothing else.

Using Hyperthreading with a single processor will increase the speed for 1 thread (but not 2 threads).

Using 2 physical processors is significantly faster than one processor with hyperthreading.