Let's see, how do we do the screen share on this? Ah, here we go. Okay, there we go. That's looking a lot better. All right, so welcome to Advanced HashCat Training. A quick note about who I am. I am staff here at the DEF CON Password Village. I am a member of the HashCat Dev Team and Team HashCat. I am the founder and CEO of Terrahash. And I'm also a password hashing competition judge. My name is Jeremy Gosney. I go by the Nick episode. All right, so number one, let's talk about entropy. In the password-cracking world, we don't really talk about entropy. We don't express password strength in terms of entropy. You know, in academic settings or when we're talking about, like, symmetric key encryption and such, you know, you'll hear, you know, this key has X bits of entropy or, you know, that password has 32 bits of entropy. We don't give a fuck about that as password crackers. As password crackers, what we care about is keyspace. Keyspace is the total number of combinations for an attack. It is essentially a measure of the level of effort for our attack. To calculate the keyspace for a dictionary attack, it's simply the number of words in a word list. For a dictionary and rule-based attack, it is the number of words in the word list multiplied by the number of rules in the word file. For a combinator attack, you multiply the keyspace of each dictionary, so the number of words in the first dictionary multiplied by the number of words in the second dictionary. And for a mask attack, you multiply the number of possible characters in each mask position together. And we'll get into exactly what that looks like and what that means. Oh, and for hybrid, of course, it's the keyspace of the word list, the number of words in the word list multiplied by the keyspace of the mask. So, keyspace examples. rocku.txt has 14.3 million words. best64.rule has 102 rules in the rule file, which is kind of a misnomer. It's not really best64. It's more like best102. So we multiply 14.3 million by 102 rules, gives us a keyspace of 463 billion. That is the total number of combinations that you need to hash when you combine rocku.txt with best64.rule. Let's say we were to do a combinator attack of rocku.txt plus rocku.txt. That would be 14.34 million words times 14.34 million words equals 205 quadrillion possible combinations for that keyspace. So our second attack, the combinator attack, requires 140,000 times more effort than the first attack. Now let's look at how we calculate keyspace for masks. I said that mask was the total of each character in each position, right? So we have 26 lower letters in all six positions. Our keyspace is 26 to the power of 6. That gives us a keyspace of 8 billion. Now let's look at this mask. We have special digit lower uppercase digit. So there's 33 possible special characters multiplied by 10 digits multiplied by 10 possible lowercase characters multiplied by 26 possible uppercase characters multiplied by 10 digits gives us a keyspace of 2.2 billion. All right, so let's look at using custom character sets. So in our custom character set, we have the lowercase and a digit. So 26 plus 10 is 36 custom characters. And then we have 5 lowercase letters. So 26 to the 5th. And then 2 digits is 10 to the 2. Gives us a total keyspace of 11.8 trillion. Sorry, billion. 11.8 billion. Same thing if you have two custom character sets. Our first custom character set, we have a lower and a digit. Our second custom character, we have a digit and a special. So the math, of course, is very similar. So we have 36 in our custom character set 1 multiplied by 26 to the 5th for our lower digits in our mask multiplied by 10 possible digits and then 43 in our second custom character set for a total of 183 billion possible combinations. So let's kind of shelve that real quick and let's kind of pivot and talk about hash rate. Hash rate is a measure of distance over time and is expressed as a number of hash calculations per second. The hash rate depends on several variables, of course, like the hardware. Are we using CPU? Are we using GPU? Are we using an older GPU? Are we using a newer GPU? The hash algorithm itself plays a big part in the hash rate. Some hashes are stupid fast like MD4 and MD5. Others are brutally slow like Bcrypt and Scrypt. The attack mode also plays a big part in our hash rate. Brute force is going to be faster than a wordless attack, for example. The way the attack is structured, we will get into GPU acceleration a little bit later in the slide deck, but basically the way you structure your attack can negatively or positively impact performance. And, of course, the key space for the attack also plays a part in hash rate. If the key space is too small for GPU acceleration, you will not have a very high hash rate. And also the number of hashes. This has more to do with the amount of RAM or video RAM that you have. If you have an inordinately large number of hashes, it will affect the hash rate. So the best case scenario for HashCat is single hash brute force. With single hash brute force, you will get the absolute highest speed for each algorithm. Once you get into multi-hash brute force, the speed is going to drop by about 25%. Once you start doing single hash dictionary and rules, it's going to be about 50% slower than single hash brute force. Multi-hash dictionary and rules is going to be about 75% of the speed of a single hash brute force attack. So you can see how the attack itself actually plays a large part in the hash rate. Now I mentioned that some hash algorithms are faster than others. Fast hash algorithms like MD4, MD5, SHA1, SHA2, and even DEScrypt now with BitSlice DES on GPU, I would definitely consider to be a fast hash these days. Medium fast hashes would be things like MD5Crypt, Kerberos, and macOS hashes. And then, of course, we have the very slow hash algorithms. A lot of these have custom iteration counts, cost variables. So these can actually be made to be somewhat fast, but most of the time these are going to use settings that are going to be very painfully slow. And here's an example of that. This is a chart that just very quickly will visualize which algorithms we consider to be fast. And then kind of a medium fast here. And then, of course, the really painfully slow ones down here at the bottom. All right, so let's look at how hash rate and keyspace interact with each other because this is really important for when you start structuring advanced attacks. Mainly because we want to know, if we go to run an attack, is this a worthwhile attack to run or is it not? And, of course, Hashcat will tell you, like, yeah, you know, this is going to take a decade to run. But as a password cracker, you should kind of have a sense for what that's going to look like in advance of actually starting your attack. So let's look at the following example. We have a single hash NTLM brute force here. Sorry, the command here doesn't actually say single hash, but let's pretend that there is a single hash there. So four RTX 2080 TIs can pull about 380 billion hashes per second on single hash NTLM brute force. And, of course, our mask here has a keyspace of 95 to the 8th. So the math, 95 to the power of 8 divided by our 380 giga hash a second means that this attack will take us about 17,458 seconds or about 4.77 hours. So this attack will complete in under five hours, which is likely acceptable to you. Now let's add a character to our mask. Keyspace increases to 95 to the 9th at the same speed of 380 giga hash a second. This attack will now take us 1.6 million seconds to complete, which is a little over 19 days. Sorry. So at this point, you understand how to calculate keyspace, you understand fast versus slow hash algorithms, and you understand the relationship between the keyspace and the hash rate. But how do we actually leverage this to our advantage? To do that, let's talk about base and mod. GPU acceleration... Excellent, I skipped a slide there. So to achieve GPU acceleration, we have two concepts in HashScout called the base loop and the mod loop. The base loop gets executed on the host CPU and the mod loop gets executed on the GPU devices. If the mod loop is too small or if it's completely non-existent, you will not gain GPU acceleration on fast hash algorithms. This means that while your GPUs may be capable of doing the 380 billion hashes per second like you saw in the previous examples, they will not do so if the mod loop is too small. You will get no GPU acceleration, your hash rate will be abysmal down in the single digit kilohash a second. And we absolutely want GPU acceleration. That's kind of the entire point of GPU password cracking. So if you do a straight dictionary attack on GPU with no rules, then you have a base loop which is the dictionary, but you have no modifier whatsoever. You will not get GPU acceleration with this attack. It will be abysmally slow. It will actually be faster on CPU than on GPU. The second example here, where we're using the same dictionary, but now we're adding a modifier, rules. The words will be looped over from Rocky.txt on the CPU, but then the rules will be applied in the onGPU rule engine on each of the GPU devices, and that's where our GPU acceleration comes from. So the more rules you have, the more GPU acceleration you're going to gain to a point. I believe the tipping point there is somewhere around... well, last I looked, it was probably 50,000 rules. It may be a little bit higher now with larger VRAM values. But 30,000 to 50,000 rules is kind of the sweet spot for achieving maximum GPU acceleration with a rule-based attack. For a combinator attack, the base loop is going to be the inner dictionary, while the mod loop is going to be the outer dictionary. And then for mask attacks, it's kind of interesting, because the mask itself doesn't have any kind of obvious split like a combinator or rule-based attack does. So what Hashcat actually does internally is it's going to split the mask into two parts. So the first half is going to be the base loop, while the second half of the mask is going to be the mod loop. And then for hybrid attacks, again, it's pretty straightforward because it's actually logically separated in the command itself. The base loop is the dictionary, and the mask is the mod for A6. Then for A7, it's the reverse. The mask is the mod, and the dictionary is the base. So let's look at this in an applied example. So we have the same single hash NTLM brute force command that we had from the previous slides. Hash rate is still, let's say, 380 gigahash a second. Our keyspace is still 95 to the 9th. So per our previous math, this will take 1.6 million seconds to complete, which again is a little bit over 19 days. But let's say we don't want that to take 19 days. Let's say we want this attack to complete in 8 hours. So 8 hours is about 29,000 seconds. So what we're going to do is we say our hash rate is 380 billion hashes per second. And we want to let it run for a little over 29,000 seconds. So we simply multiply that to find out the number of hash calculations that we can make with our 4 2080 TIs in that amount of seconds. And that gives us 11.1 quadrillion guesses in 8 hours with this attack. So now we sit here and we flip it around. We want to find out what we need our base loop to look like to hit that 8 hour target. So right now with the mask of question mark A, the base is 95 for each character set. But if we take this 11.1 quadrillion and we raise it to the 1 over 9th power, we get 60. And what we can do with that is HashCat, for anywhere you're using a mask, actually uses Markov tables to do a probabilistic brute force. Instead of a classic dumb brute force where you're going A, A, A, A, A, etc. all the way through Z, Z, Z, Z. HashCat generates some Markov statistics and will order the search space for each character position probabilistically based on those Markov tables. So we can take our HashCat command and we can append this dash T 60. And what that does is that sets our Markov table threshold to 60. And what that simultaneously does is that lowers our base loop from using the 95s to using 60 instead. So instead of 95 to the 9th, the key space is now only 60 to the 9th, using only the top 60 characters in each mask position. All right. Let's kind of shift gears here and talk about loopback attacks. So by and large, password cracking is mostly just a feedback loop. You know, we crack passwords so that we can learn new passwords, which we then turn around and use to crack future passwords. And this cycle happens over and over for decades. And it holds true for every large password breach we've ever had, right? So starting with probably the most famous in recent history, which would be Roku. Roku.txt, while dated, is still kind of like the de facto example when we're talking about a word list. Even in this slide deck, I've used Roku.txt extensively. So, you know, we have the Roku passwords. That allowed us to identify new passwords by adding rules and, you know, basically mangling up those words to crack new passwords. And then once we got those new passwords, we add those to our word list collection, right? And then we're going to turn around and add rules to those. And we're going to continuously find new passwords based on the previous passwords that we've cracked. So in a loopback attack, which, again, you can do a loopback attack on a single run, right? For whatever run you're working on at that point in time. Or, you know, when you use previously cracked passwords, you're essentially still doing a loopback attack because you're taking the passwords found in your previous runs, even if those runs were a decade ago, and you're iterating on those to discover new passwords in your current run. So to do that, we'll just strip the plaintext passwords out of our hashcat.py file. And then we'll use that as a word list with some rules. Throw some best64 at it, throw some dead1 at it, you know, what have you. Now, we can take that a little bit further with what's called a fingerprint attack. Instead of using the plaintext passwords themselves, we can break each plaintext password down into what are known as fingerprints. A fingerprint would just be like, let's say, the word password. So it's going to split that up into P, P-A, P-A-S, P-A-S-S, P-S-S, P-A-S-S-W, so on and so forth. Basically expanding each word into each, you know, individual cluster of letters of itself. So to do that, we take our cracked passwords, whether it be looped back from your current hashcat.pot or cracked passwords from a previous run, you know, maybe like the RockyLeague or, you know, LinkedIn breach or Ashley Madison, Edmodo, Gizmodo, whatever. Literally dozens and dozens, if not thousands and thousands of public password breaches out there that have all sorts of, you know, plaintext or easy-to-crack passwords. And we use those to generate the fingerprints using expander.bin from hashcatutils. Once we have the fingerprints, we can either run that as a combinator attack or we can use that in a hybrid attack. You can do, you know, any numerous things with them. And you can also add rules to nearly any attack as well. So let's say you're using your fingerprints, right, and you're doing your combinator attack. Let's say you're using RockYou with your fingerprint file. Let's throw some rules on that. So the "-J rule is going to operate on the left-hand side there, the base loop. And in this example, we're deleting the last two characters from every word from the word list. And then we are appending our fingerprints from our loopback attacks to every word in that word list. This is kind of a favorite attack I like to run. I like to do "-J", right bracket, and then "-J", two right brackets, then "-J", three right brackets, so on and so forth. And that's going to enable you to find some pretty interesting new planes as we continue to cut characters off the end of the left dictionary and then continue to append our fingerprints to the right. Same thing with this example here. So like I said, "-J operates on the left-hand side, while "-K operates on the right-hand side. And of course, the C rule means to capitalize the word. So let's say we want to capitalize the rules from RockYou and then capitalize the words from our fingerprints. We can append "-JC", "-KC", to our command line, and that will enable us to capitalize each of the words on each side before combining them. And you can do the same thing with hybrid attacks as well. So let's say we have our fingerprints file, and we want to append double digits to every word in our fingerprints. We can add a "-JC", say we want to remove the last character from each word in our fingerprints, and then capitalize that word before appending the double digits. All right, now let's talk about stemming. It sounds sexual, but it isn't. Stemming is essentially identifying base words from each password. And this is going to be very useful for when you're doing your loopback attacks, whether, again, that's the looping back over passwords you just cracked in a previous run, or you're talking about looping back over passwords you've cracked from anything over the years. And essentially what we're doing in identifying these base words is we're unrolling the rules that people apply when they create passwords. So, you know, most people, when they're told to make a password stronger, they will uppercase the first letter. They'll substitute, like, an A for a four, or an E for a three, etc., and probably put a couple of digits on the end. So when we stem, the first thing we're going to do is we're going to remove any leading and trailing digits and specials. We're going to convert it all to lowercase to normalize it. And any midstream digits and specials, we're going to convert those back to letters. And, of course, there's a lot more you can do here. This is kind of a very basic example of stemming, and there's also multiple tools out there that can do this for you. Like, I have some small scripts on the Hashcat forums that can do this. I think Pack can do this as well. And probably a dozen other tools that people have made on GitHub that can do wordless stemming. But once you have those stemmed words, you have a nice set of base words that you can use to either do fingerprint attack or hybrid attack, or you can use those with, like, rulegen.py from Pack to generate new Hashcat rules off of. So stemming, of course, is very powerful based on the things we can do with it once we have the common base words. All right, here's some more advanced things you can do with Hashcat. temesis.pl, again, from Hashcat Utils. What this is going to do is it's going to basically take fingerprints from each word, and it's going to create rules that will insert that word and fragments of that word throughout the word list that you pick. So let's say we pick rockyu, and we've created our temesis rule from our base words. It's going to go through and take every word from rockyu and insert patterns based on our base words. It's going to interlace those throughout the words in rockyu. And, of course, you can chain rules as well. So when you chain rules, the rules are applied in order. So we're starting with rockyu.txt, and then every word from rockyu is going to be... have the rules from our temesis.rule file applied to it. And then, after we apply temesis rule, it's going to then apply the best64 rules on top of that. So the key space for this can actually get really large really quick because it's going to be the number of words in rockyu times the number of rules in temesis times the number of rules in best64. So when you're performing this attack, it can get really large really quick. But it can also be really powerful. Rule chain like best64 and best64 is usually a good one. Sometimes, depending on your hash rate, you can chain dead1.rule or rockyu30000.rule with best64. But yeah, you can come up with some pretty cool attacks using rule chaining in this fashion. And sometimes it's a necessity if you have, like, a really targeted pattern that you want to hit that you can't just hit with a single rule file. You can create multiple rule files and chain them to try to generate the type of plain text you're after. And then, of course, there's PrinceProcessor, which is also available on hashcat.github. PrinceProcessor is sort of a more advanced combinator attack. It's kind of difficult to describe, but just think of it like a more advanced combinator attack, which you can pipe into hashcat through standardin. And that's it for advanced stuff. There's a lot more fun things that we can do, and we can cover that in a future session. But yeah, that's some of the really cool advanced stuff that you can do with hashcat.