[00:01.360 --> 00:04.660] This is PrivacyNotIncluded, one of your Password Village leads, and I want to [00:04.660 --> 00:07.740] welcome you to our first year running the Password Village. [00:07.740 --> 00:10.840] We wanted to start off getting you up and running with Hashcat [00:10.840 --> 00:14.660] on an NVIDIA GPU and then cover some basic attacks. [00:14.660 --> 00:18.700] The goal here is to start building a foundation that other talks throughout [00:18.700 --> 00:22.740] the village and DEF CON will expand on. So ideally [00:22.740 --> 00:25.400] you're going to have a GTX model NVIDIA card [00:26.140 --> 00:30.400] and be running Linux. The box we're on here is an AWS instance [00:30.400 --> 00:37.000] running the stock Ubuntu 20.04 AMI, and it has a Tesla T4, which isn't [00:37.000 --> 00:40.560] the greatest card for cracking, but it's going to work for our purposes. [00:41.460 --> 00:44.800] So Hashcat supports two modes of operation. You have [00:44.800 --> 00:48.000] OpenCL, which is a standard language, meaning that [00:48.000 --> 00:54.580] it's going to run on any card or CPU that supports OpenCL. That can be [00:54.580 --> 00:58.240] Intel, that can be AMD, that can be NVIDIA, [00:58.240 --> 01:00.960] and that can be AMD video cards. [01:02.720 --> 01:06.320] And then there's CUDA, which is specific to NVIDIA, [01:06.320 --> 01:11.160] which will allow us to eek just a bit more performance out of the card [01:11.160 --> 01:15.980] and get us some faster crack rates. Since we have an NVIDIA card on this box, [01:15.980 --> 01:19.960] we're going to go with the CUDA driver. Now we don't want to use the repo [01:19.960 --> 01:22.660] drivers. We don't want to use the repo drivers [01:22.660 --> 01:24.620] because the [01:26.460 --> 01:32.080] Ubuntu maintainers will include patches to those drivers that may fix a bug [01:32.080 --> 01:38.220] for a desktop environment, for instance, but it breaks the [01:38.220 --> 01:42.440] compatibility with the CUDA runtime and therefore [01:42.440 --> 01:45.940] breaks Hashcat. And we don't want that to happen. So [01:45.940 --> 01:50.980] we're going to use the driver that's supplied by NVIDIA, [01:50.980 --> 01:55.560] and we're going to use the CUDA toolkit version. So we are on Linux, [01:55.560 --> 02:02.960] we're on x86-64, so 64-bit processor, our 64-bit system, we're running Ubuntu, [02:02.960 --> 02:07.120] we're running version 20.04, and then we have a couple of options here. [02:07.120 --> 02:09.860] So we have a run file, which is a local install, [02:10.220 --> 02:13.520] a local Debian install, which will create a [02:13.520 --> 02:16.820] Debian archive on your, or sorry, a Debian repo [02:16.820 --> 02:19.320] on your local box, and then you have the network install. [02:19.880 --> 02:25.400] Because we want to maintain compatibility between the CUDA [02:25.400 --> 02:30.540] version and the Hashcat release, we don't want to upgrade [02:31.160 --> 02:34.920] CUDA as part of a system upgrade on accident and break it. [02:34.920 --> 02:37.540] So we're going to go with the local run file. [02:38.100 --> 02:42.720] So we're going to copy this wget line here, [02:45.430 --> 02:56.680] paste that in, and then we're going to go ahead and grab [02:56.680 --> 03:09.310] our Hashcat binaries, and we also want the [03:10.170 --> 03:13.790] PGP signature so that we can verify that it's legit. [03:20.040 --> 03:23.300] And then we're going to want to grab the Hashcat key. [03:23.300 --> 03:29.020] So we see here we've got the fingerprint, scroll over here a bit, so we've got the [03:29.020 --> 03:32.840] fingerprint here, and it says that it is on the PGP key [03:32.840 --> 03:37.900] servers, so we can use GPG to go ahead and [03:37.900 --> 03:46.530] import that key. Okay, now we've got our key, [03:47.350 --> 03:51.750] and then let's verify that our download is actually [03:53.510 --> 04:00.940] signed and correct. Okay, so there we go, we've got a good [04:00.940 --> 04:01.900] signature. [04:03.900 --> 04:07.820] So we are good there. So we're also going to grab [04:08.380 --> 04:12.780] a word list, and we're going to grab that from Skull Security, [04:12.780 --> 04:17.360] and we're going to be using Rocky, which is kind of an old list, but it's [04:17.360 --> 04:23.880] also still really good. So let's grab that guy. [04:32.030 --> 04:44.550] Let's grab it incredibly slowly. So the next part, we'll go ahead and [04:44.550 --> 04:47.990] install the CUDA SDK, and it's going to [04:50.330 --> 04:53.350] fail the first time we run it, because we're [04:53.350 --> 04:57.130] on a brand new box that has no [04:57.130 --> 05:01.230] dependencies installed at all. So there are [05:01.230 --> 05:05.110] some things that the SDK is going to do, like build the [05:05.110 --> 05:08.230] NVIDIA driver, and it's going to need to have [05:08.230 --> 05:12.390] things like GCC and other libraries that it requires in order to do that. [05:12.390 --> 05:16.950] So what we're actually going to do is kind of walk through the steps on [05:16.950 --> 05:20.050] how we can make sure that we get all of those, [05:21.170 --> 05:24.510] now that that's done. So we're going to do a search for [05:24.510 --> 05:29.970] an Aptcache search for the NVIDIA driver, and we can see that there are a bunch of [05:29.970 --> 05:35.470] them. So let's just say this guy right here, [05:35.470 --> 05:39.750] and it's the latest release that it seems that Ubuntu has. [05:39.970 --> 05:42.330] And then we are going to apt-get [05:43.930 --> 05:49.930] build-dep NVIDIA driver 440. So we want to [05:49.930 --> 05:54.310] get all the dependencies that NVIDIA driver 440 requires. [05:56.330 --> 06:03.210] So we don't have any source listings for non-binary pulls in our [06:03.210 --> 06:17.650] our app config, so let's go ahead and make that happen. Let's make sure we get [06:17.650 --> 06:24.890] the editor in there as well. So we're going to uncomment this, and [06:24.890 --> 06:28.270] we're going to uncomment this, and that's all we need. [06:31.560 --> 06:48.520] Do a quick update, and let's try that again. [06:50.480 --> 06:54.960] Okay, so we're going to go ahead and let all of that install, so this will [06:54.960 --> 06:57.680] allow us to build our driver. [07:00.060 --> 07:01.720] Oh, we also need to grab one more thing. [07:01.720 --> 07:04.860] Because HashCat is packaged in the 7-zip format, we'll need to grab [07:04.860 --> 07:40.200] p7-zip. Any day now. Hello? [07:41.900 --> 08:04.420] AWS? So we'll grab p7-zip as well. Thankfully that didn't take as long. [08:06.240 --> 08:11.260] And we're going to bypass some of this. [08:11.420 --> 08:17.720] So if you run the CUDA SDK installer, it has a kind of menu-driven [08:17.720 --> 08:22.620] interface. We don't want that. So we're going to run it in silent mode, [08:22.620 --> 08:30.720] and we want to install the driver and the toolkit. And this is going to [08:30.720 --> 08:36.160] take a minute. Okay, now there's one other step that if [08:36.160 --> 08:40.680] we had used the menu-driven method, it would tell us that we need to [08:40.680 --> 08:45.580] add some stuff to our path. So if we look at [08:51.120 --> 08:56.620] ldsoconf.conf.d... So it already wrote our CUDA library [08:56.620 --> 09:01.420] path, so that's good. But it did not write the [09:01.420 --> 09:07.500] path update for our profile. So we need to go ahead and add that in. [09:07.500 --> 09:15.120] So we'll do a sudo vi slash etc profile.d [09:15.560 --> 09:18.440] and we'll call this cuda.sh. [09:20.920 --> 09:24.260] And then in here, we're basically just adding [09:24.260 --> 09:31.220] the path to the CUDA binaries to our system path. And then this is [09:31.220 --> 09:35.900] going to load every time a new instance is spawned. So we'll go [09:35.900 --> 09:39.340] ahead and source except profile so we get the [09:39.340 --> 09:47.870] update. Okay, and then we also need to [09:47.870 --> 09:52.390] run ldconfig so that it updates the library path. [09:54.820 --> 10:02.220] Okay, and then let's check NVIDIA SMI and make sure that it [10:02.220 --> 10:06.560] sees our card. And it does. So we've got our Tesla T4 [10:07.220 --> 10:10.960] and it is running on the driver version that was supplied with [10:10.960 --> 10:16.920] the CUDA SDK, which is 450.51.05. It's right here. [10:17.240 --> 10:21.620] And we can see we're on CUDA version 11. So that's good. [10:22.240 --> 10:28.860] So next, let's unpack Hashcat. So we're gonna 7-zip extract [10:29.620 --> 10:35.040] hashcat.7zip. And while we're at it, let's go ahead and [10:35.040 --> 10:38.740] bunzip to rocky.txt. [10:44.940 --> 10:49.720] All right. So let's make sure that Hashcat sees [10:49.720 --> 10:57.270] our video card now. And it does. And it sees that it can [10:57.270 --> 11:02.990] run in either CUDA or OpenCL mode. It's going to default to the CUDA [11:02.990 --> 11:06.590] version here, so we don't need to worry about the [11:06.590 --> 11:10.710] OpenCL info below us. And then let's just do a quick [11:10.710 --> 11:12.510] benchmark to make sure that [11:14.550 --> 11:20.070] we actually get running. Okay, so we can see that it selected our [11:20.070 --> 11:24.710] device. It skipped the OpenCL part of that [11:24.710 --> 11:29.310] because it has the CUDA API. And there we go. [11:32.550 --> 11:38.890] So let's move into doing some simple attacks with Hashcat. [11:42.570 --> 11:45.950] So we're going to go back to the Password Village site, which is at [11:45.950 --> 11:51.630] passwordvillage.org, and we're going to grab some NT hashes. [11:53.410 --> 11:56.250] So we've got our Hashcat examples here. [11:57.870 --> 12:01.090] You can copy and paste these off the site and [12:01.090 --> 12:07.370] follow along if you are set up to do so. Actually, let's get rid of this. [12:09.310 --> 12:16.900] And we'll call this nt.hash. We'll paste those guys in using [12:16.900 --> 12:19.460] whatever editor you desire. [12:21.360 --> 12:27.300] And then we used Hashmode1000 here because I know that 1000 [12:27.300 --> 12:29.340] is NTLM. [12:31.120 --> 12:36.000] But if you needed to find it, you could do a Hashcat help [12:36.000 --> 12:41.360] and then grep. We'll do a dash i so we do a [12:41.360 --> 12:45.760] case insensitive search and look for NTLM. [12:45.760 --> 12:50.140] And we can see right here NTLM is Mode1000. [12:50.140 --> 12:54.320] NetNTLM v1 and v2 are different hash types. [12:54.320 --> 12:58.320] Typically you see those coming out of Responder, which [12:58.320 --> 13:01.980] I believe EvilMog is going to do a talk on [13:01.980 --> 13:04.840] later in the day that will quickly cover those. [13:04.840 --> 13:11.020] So we want Hashcat.tacm1000 for mode. [13:11.240 --> 13:16.400] We want our nt.hash file and then we want to run this against RockView. [13:22.420 --> 13:25.760] So it's going to initialize the device there. It's going to load the dictionary [13:25.760 --> 13:31.440] and then it cracked all our hashes. It cracked all our hashes because these [13:31.440 --> 13:36.320] hashes were generated from RockView. So you would expect to [13:36.320 --> 13:40.300] to get all of those. If you were pulling hashes from the wild, [13:40.300 --> 13:44.800] you know, RockView may crack one of them, it may crack none of them, or it may [13:44.800 --> 13:47.540] crack all of them depending on how good the password policy [13:47.540 --> 13:51.640] of the the company or the site that was [13:51.640 --> 13:54.120] compromised and the hashes were leaked from. [13:55.040 --> 13:58.000] So to kind of walk through this a little bit, there's a lot going on on the [13:58.000 --> 13:59.660] screen here. So we have our hashes up here [14:00.040 --> 14:03.460] and we have the associated plain text on the opposite side. So you've got [14:03.940 --> 14:10.960] this is a hash, we've got a separator, and then we have the plain text of this [14:10.960 --> 14:15.380] hash. And then we've got 10 of those. So we had [14:15.480 --> 14:20.000] a session name of HashCat. If we were doing [14:20.720 --> 14:24.860] some session stuff where maybe we wanted to stop this and resume it later, [14:24.860 --> 14:29.000] this name is important. We're not going to cover that here. The status would [14:29.000 --> 14:32.620] normally be running, but since we only had a small sample and we knew [14:32.620 --> 14:36.120] the plain text for all of those, it cracked them all pretty quick. [14:36.480 --> 14:43.920] We were running against NTLMs. Our hash target was the hash file that [14:43.920 --> 14:49.780] we supplied called nt.hash. The guest base, meaning the candidate [14:49.780 --> 14:54.460] words that we were selecting from, came from a file called rocky.txt. [14:54.840 --> 14:58.240] The speed of our device, which is actually pretty slow [14:58.240 --> 15:03.520] compared to what we saw up here in the benchmark, because [15:04.240 --> 15:08.120] it never got fully up to speed. Where are we at here? [15:17.420 --> 15:19.500] So we can see here we were going at about [15:24.080 --> 15:28.520] 35.7 billion. It's pretty quick. [15:28.720 --> 15:33.540] But down here we were only going at about 7.7 million. [15:33.540 --> 15:38.620] So that's mainly because we didn't have [15:38.620 --> 15:42.300] enough work to supply the GPU, but also because [15:42.300 --> 15:45.680] we cracked all the hashes so quickly that it never got [15:46.240 --> 15:50.900] a chance to get up to full speed. So we recovered all 10 of our hashes, so we had [15:50.900 --> 15:55.320] 10 digests. A hash is also called a digest. It [15:55.320 --> 15:59.360] ran through the entire list of words, so we had 14.3 million [15:59.360 --> 16:04.780] possible candidates, and we exhausted that entire space. [16:04.800 --> 16:07.840] It rejected none of them, and a rejection can come from [16:09.100 --> 16:14.000] a word that's too long. We had a restore point, which we didn't use because we're [16:14.000 --> 16:17.620] not doing a restore. And then we had the candidates down [16:17.620 --> 16:20.560] here. Now in a long run, this is going to show [16:23.600 --> 16:26.640] a sample of what words are currently being [16:26.640 --> 16:31.780] tried against the hashes. And here we have [16:31.780 --> 16:35.420] some hex representation, and this is probably because we have [16:38.260 --> 16:43.120] a colon, which is a separator that HashCat uses [16:43.120 --> 16:46.680] internally. So it's going to put that into a hex [16:46.680 --> 16:48.600] representation so that it doesn't accidentally [16:48.600 --> 16:52.140] cut your hash or your plain text in the wrong spot. [16:52.140 --> 16:56.240] And then we have our hardware monitor, which was telling us some statistics [16:56.240 --> 17:00.740] about the card. So it was running at 59 degrees celsius, it was at 75% [17:00.740 --> 17:03.880] utilization, and then our core speed, the memory [17:03.880 --> 17:07.960] speed, and the bus workload. [17:10.040 --> 17:13.720] So that's a very simple dictionary attack. [17:14.720 --> 17:25.470] So let's try doing a combinator attack. [17:25.470 --> 17:32.470] Now a combinator attack is when you take two word lists and HashCat is [17:32.470 --> 17:35.550] going to take one word from one word list and one [17:35.550 --> 17:39.290] word from the other word list and smash them together and try that as a [17:39.290 --> 17:41.930] candidate. And it's going to do that for each one. [17:41.930 --> 17:47.770] So in very large runs, this is not really the best [17:48.830 --> 17:53.650] attack to do because it can take years to complete. So if we were to use Rocky [17:53.650 --> 18:00.190] with Rocky, for instance, we're doing 14.3 million to the 14.3 million, which [18:00.190 --> 18:02.250] ends up being some ridiculous number that [18:02.250 --> 18:04.730] we're probably never going to exhaust. [18:06.010 --> 18:09.990] The example dictionaries here are actually reasonably small and [18:09.990 --> 18:14.310] it's a really good baseline for showing how the attack works. So [18:15.710 --> 18:23.850] we can copy this. So we're going to use A1, which is the [18:23.850 --> 18:28.410] attack mode for combinator. These hashes are MD5, so we're going to [18:28.410 --> 18:33.310] say M0. M0 is the mode identifier for MD5. [18:33.570 --> 18:37.130] HashCat provides an example list of hashes, so this is [18:37.130 --> 18:41.390] going to be the list of MD5 hashes. And then the two example dictionaries, [18:41.390 --> 18:44.990] which are actually the same dictionary, so we're just going to specify it twice. [18:44.990 --> 18:48.450] You could do this with two different dictionaries. So if you had [18:48.450 --> 18:52.690] example.dict and then example1.dict that has some different word [18:52.690 --> 18:56.710] set in it, that will work. And you could even reverse submit. [18:58.350 --> 19:00.530] So let's go ahead and run this. [19:02.190 --> 19:04.990] Go ahead and run this with the right name. [19:12.620 --> 19:17.680] And yeah, that's a lot. So we had, if we go back to [19:18.460 --> 19:24.520] our status output here, we know all this. We had a file which was example.dict [19:24.520 --> 19:27.820] on the left side, and a file which was example.dict on the [19:27.820 --> 19:32.000] right side. So if you think about it this way, you have [19:32.880 --> 19:33.960] example.dict [19:33.960 --> 19:38.960] and then example.dict. [19:39.260 --> 19:43.000] So this is going to be the left side. This is going to be [19:43.000 --> 19:46.820] the right side. And then again, Hashcat just [19:46.820 --> 19:52.020] combined left and right, made a single word out of it, [19:52.020 --> 19:55.040] hashed it, and then checked it against the list of hashes. [19:55.760 --> 19:59.820] So we can see here that we went quite a bit faster this time. So we went [19:59.820 --> 20:05.240] at 5.8 billion candidates per second. [20:05.240 --> 20:12.720] We recovered 2,906 of 6,494 digests, so just under [20:13.240 --> 20:19.860] 45 percent. And we have 3,588 hashes remaining. [20:22.080 --> 20:23.660] So the next one we'll do [20:29.720 --> 20:34.960] is a brute force. Now, this is going to be a very simple [20:35.840 --> 20:39.760] example of a mask attack, and we'll talk about mask attacks later. [20:40.620 --> 20:43.960] Brute forcing is when we take [20:47.880 --> 20:52.520] a string and then increment it by either a number or a letter [20:53.120 --> 20:56.620] to exhaust a full keyspace. So in this case, [20:56.620 --> 21:03.280] we're doing 1, 2, 3, let's see, 1, 2, 3, 4, [21:03.280 --> 21:09.500] 5, 6 spaces of all characters. So that's numbers, [21:09.500 --> 21:15.980] letters, lowercase and uppercase, and then specials. This is again going [21:15.980 --> 21:20.660] to be MD5. We're going to use the same example [21:20.660 --> 21:25.800] hash set that we used before. A3 is to specify a mask attack or a [21:25.800 --> 21:31.640] brute force attack, and then get this right the first time. [21:37.040 --> 21:40.180] And then we let it run. So you'll see here that [21:40.180 --> 21:44.380] we're only going to crack six-character passwords because we only specified [21:44.920 --> 21:48.220] for Hashcat to crack six-character passwords. [21:48.920 --> 21:52.440] And we can see we've got some lowercase, we had some numbers, now we've got an [21:52.440 --> 21:57.360] uppercase here, there's an uppercase there, some stuff [21:57.360 --> 22:02.220] starting with numbers, so lowercase. [22:03.840 --> 22:04.600] Okay. [22:06.300 --> 22:12.100] So what Hashcat was doing in that mode, so we had this mask specified. [22:13.040 --> 22:16.660] We said we want to try all possible combinations of all [22:17.640 --> 22:21.140] printable ASCII characters on a standard keyboard. [22:21.140 --> 22:25.780] So we have 95 of those. So for each one of these positions, it's going to try [22:26.300 --> 22:32.760] all 95 possibilities. So if we look at it this way, let's say it [22:32.760 --> 22:37.040] starts at 1, 2, 3, 4, 5, 6 A's. [22:38.400 --> 22:46.300] And then it tries 1, 2, 3, 4, 5, 6 with a B. And then it tries 1, 2, 3, 4, [22:46.300 --> 22:49.980] 5 with a C. And it continues to increment [22:49.980 --> 22:55.880] until C gets to Z, and then it shifts by 1. [22:57.000 --> 23:02.020] So then we have 1, 2, 3, 4, B, A. [23:03.340 --> 23:07.640] 1, 2, 3, 4, B, B, and so on and so forth. But [23:07.640 --> 23:11.360] since we're going so fast, the [23:12.460 --> 23:17.100] incrementing of the characters goes ridiculously fast. [23:18.500 --> 23:23.980] So that is your basic rundown of the three [23:23.980 --> 23:27.240] very basic attack modes that HashCat does. [23:28.140 --> 23:34.680] You can go back and take a look at the standard attacks that are specified [23:34.680 --> 23:38.100] on the Password Village website, if you need help understanding what was [23:38.100 --> 23:42.620] going on. And also some examples of how to use the [23:42.620 --> 23:45.000] commands for a given attack mode. [23:47.340 --> 23:50.780] So that's all we've got for now, and hope you [23:50.780 --> 23:52.380] join us for the next talk!