[00:00.000 --> 00:03.080] Which is an email signing protocol. [00:06.240 --> 00:12.020] It's frequently used with weak keys, so I'm going to show you how to break those. [00:13.040 --> 00:16.740] And I'm trying to get my presentation software running. [00:28.950 --> 00:32.170] I swear, this was working fine 15 minutes ago. [01:19.360 --> 01:22.600] So, DKIM is an email signing protocol. [01:24.960 --> 01:31.900] It's different from most signature protocols you may be familiar with, like GPG, PGP, or SMIME. [01:31.920 --> 01:36.500] GPG is a user-based signing protocol. [01:37.160 --> 01:39.260] It's based on the Web of Trust model. [01:39.260 --> 01:44.040] So, user A asserts user B is who they say they are. [01:44.620 --> 01:47.520] And you get a whole bunch more people doing that. [01:48.440 --> 01:50.420] And that's how you validate the signatures. [01:53.080 --> 01:54.580] I'm going to kill my laptop. [01:54.860 --> 01:55.200] I'm sorry. [01:57.840 --> 02:00.480] SMIME is a lot more like SSL. [02:00.700 --> 02:06.320] You have certificate authorities issuing certificates to users. [02:18.500 --> 02:20.300] And... I'm really sorry. [02:21.340 --> 02:23.060] I don't know what happened here. [02:30.270 --> 02:31.790] I don't have my slides on that. [02:36.080 --> 02:36.600] Okay. [02:37.320 --> 02:38.300] DKIM is different. [02:38.620 --> 02:40.940] It's domain level signing. [02:41.220 --> 02:43.880] So, your mail server is doing all of the signing for you. [02:47.100 --> 02:48.840] It's... the goals are very different. [02:49.180 --> 02:51.620] Most of the users are using it for deliverability. [02:52.440 --> 02:58.280] That means they want to make sure their email doesn't get caught by spam filters. [02:59.200 --> 03:05.600] So, consequently, if it works, ship it is exactly what happens with it. [03:07.380 --> 03:16.240] Whereas, stuff like GPG, SMIME, usually it's hard to get it insecure. [03:16.240 --> 03:18.200] The defaults are all sane. [03:24.290 --> 03:24.810] And... [03:30.200 --> 03:31.500] Okay. [03:32.060 --> 03:36.500] These are not my... This [03:40.430 --> 03:40.850] is... [03:40.850 --> 03:41.930] he's a good friend of mine. [03:42.190 --> 03:43.490] Can you get my slides off my desktop? [03:45.070 --> 03:45.590] Okay. [03:46.590 --> 03:51.970] The opinions in this talk are my own and not necessarily those voices in my head or anybody else. [03:51.970 --> 03:53.790] Don't be a jerk. [03:55.110 --> 04:00.250] And... my goal here tonight is to raise awareness and get some problems fixed. [04:05.370 --> 04:06.050] Great. [04:06.830 --> 04:10.050] As everybody knows, email is really easy to forge. [04:10.410 --> 04:17.230] It's on the level of writing a lie in the return address on a postcard. [04:22.390 --> 04:23.750] It's organizational. [04:24.150 --> 04:29.390] So, you don't have individual users claiming responsibility for messages. [04:29.590 --> 04:32.210] You have the organization asserting that they did send it. [04:34.330 --> 04:37.410] And... it's used with white listing techniques. [04:37.650 --> 04:45.830] So, you have reputation tied to instead of your IP address, your domain name in a way that is not trivially forged. [04:46.650 --> 04:47.210] Okay. [04:47.410 --> 04:49.550] Here is the terrible acronyms slide. [04:52.470 --> 04:55.890] I'll let you read that real quick and then move on to interesting things. [04:59.770 --> 05:02.130] I sputtered through most of this part already. [05:02.870 --> 05:06.030] But... the other thing I didn't mention is... [05:07.090 --> 05:15.270] There's SMTPS, which is SMTP with SSL and SMTP with start TLS, which is... [05:15.270 --> 05:20.950] Oh, that's where your communications start plain text and then you upgrade the session to SSL. [05:21.930 --> 05:25.650] Those things are used for encryption over the wire only. [05:25.830 --> 05:29.950] It does not protect the message content from anything other than eavesdropping. [05:33.130 --> 05:34.910] I've already covered this. [05:35.490 --> 05:40.130] Third parties are often trusted with DKIM keys for domain names. [05:40.450 --> 05:43.370] Usually, these are email marketing companies. [05:44.830 --> 05:52.310] The other interesting thing is your email provider may be signing your email for you. [05:55.690 --> 05:58.310] I think... I know Google does it. [06:01.070 --> 06:02.550] Actually, I know some people. [06:02.670 --> 06:08.410] They had a loony harassing them via email and it got to the point where they called the cops. [06:09.750 --> 06:15.870] The court got involved and the guy was claiming, oh, I didn't... you can't prove I sent those emails. [06:16.170 --> 06:19.070] Well, Google signs all of your outgoing email with DKIM. [06:21.530 --> 06:22.470] It's right there. [06:23.890 --> 06:25.570] That's something to be aware of. [06:30.610 --> 06:31.050] Right. [06:31.470 --> 06:36.130] So, if you want to set up DKIM, the first thing you need is an RSA key pair. [06:37.390 --> 06:39.470] Then you choose what's known as a selector. [06:40.330 --> 06:42.030] This is just an arbitrary string. [06:42.170 --> 06:43.130] It's a label for your key. [06:44.830 --> 06:46.750] Then you set up your DNS records. [06:47.630 --> 06:49.750] I'm gonna show you how that works in a few minutes. [06:50.550 --> 06:58.410] You configure the mail server with that selector and private key so that it can properly mark your messages up. [06:58.990 --> 07:04.970] I'm not gonna cover that because it's different for every mail server and it's not really interesting. [07:07.030 --> 07:20.790] And if you're doing large-scale outsourcing with a email marketing company, they will take care of the email server setup for you because it's their mail server and they'll just give you a key that you need to put in your DNS. [07:23.570 --> 07:25.630] Receivers, verification is pretty trivial. [07:25.630 --> 07:30.830] There's a header in the message that you look for, parse it, verify the signature. [07:31.810 --> 07:33.310] Nothing super fancy there. [07:35.810 --> 07:39.350] The header is composed of a series of tags. [07:39.710 --> 07:40.970] They're key value pairs. [07:41.150 --> 07:44.070] You have a version, which is just gonna be one. [07:44.070 --> 07:46.450] You have a signature algorithm. [07:46.670 --> 07:49.450] It's either RSA SHA-1 or RSA-256. [07:50.010 --> 07:51.470] You've got... [07:52.970 --> 08:01.090] There's a hash of the message body in there, which is Base64 encoded along with the raw signature data. [08:03.630 --> 08:09.550] There's your domain name, your selector, and you get to have a list of header fields you require. [08:10.830 --> 08:21.350] So, the standard talks about the selection of the header fields that you include being non-obvious. [08:21.650 --> 08:24.490] The only one that's actually required is the from address. [08:24.690 --> 08:35.770] But if the only one you include is the from address and you're signing your email like that, then somebody can just take that signature header and as long as the from address is the same, the signature remains valid. [08:36.410 --> 08:37.770] Obviously, you don't want that. [08:38.630 --> 08:47.290] So, generally, you want to include your message body, your date, your subject, your two-line miscellaneous other headers. [08:47.510 --> 08:53.590] The other thing you can do is list in your header list headers that are not present. [08:53.890 --> 08:56.390] That asserts absence of that header. [08:56.390 --> 09:09.850] You could do that to, say, ensure that somebody doesn't add an auto-reply suppression header or something like that to your message and resend it. [09:10.090 --> 09:18.710] You can also list the same header more than once in there, which can prevent additional headers from being appended. [09:18.850 --> 09:22.930] If you only include it once, you can add more headers of the same type. [09:23.870 --> 09:25.330] Only the first one will be considered. [09:25.490 --> 09:36.150] But if you have n plus one, your hash will include a value that says, you know, I tried to hash this twice. [09:36.150 --> 09:37.490] The second time was absent. [09:37.490 --> 09:39.350] And there will be no third. [09:42.350 --> 09:44.950] This is an example signature header. [09:46.510 --> 09:54.790] This one covers headers from, to, subject, dates, the MIME headers, and that stuff. [09:55.050 --> 09:58.390] I think it's super interesting there, but that's what one looks like. [10:01.350 --> 10:06.970] The text records, just like the email headers, are tag-based. [10:07.170 --> 10:08.730] You have, again, key value pairs. [10:09.130 --> 10:11.530] Most of them are optional and rarely present. [10:12.990 --> 10:17.810] The really interesting ones are the flags field. [10:18.170 --> 10:24.530] There are some other values that I am not mentioning in there, but nobody really ever uses them. [10:24.630 --> 10:26.010] But the test flag is interesting. [10:26.010 --> 10:29.810] The test flag specifies that you're just testing DKIM. [10:30.130 --> 10:37.690] And anybody processing your mail must not treat those messages differently from unsigned mail. [10:40.390 --> 10:42.110] That'll be interesting here in a minute. [10:42.770 --> 10:46.350] You've got your public key data, obviously, and... [10:47.370 --> 10:48.970] I mean, you can read my slide. [10:49.110 --> 10:51.090] There's nothing else terribly interesting here. [10:54.460 --> 10:56.800] Here's one way to create a key pair. [10:56.800 --> 11:04.520] This is using OpenSSL, which is my preferred tool for doing such things. [11:04.560 --> 11:05.740] There are other tools. [11:06.100 --> 11:09.240] I haven't looked into that in too much detail. [11:10.620 --> 11:16.160] What's out there, what the defaults for them are, but it's that... [11:16.160 --> 11:19.600] There's an example DNS record up there. [11:20.320 --> 11:24.440] That one has the version, the key type, and the public key data. [11:25.940 --> 11:30.880] And once you've done that, you're... you're configuring your mail server with that information. [11:34.590 --> 11:41.870] There is another protocol called Author Domain Signing Practices, which never really got off the ground. [11:41.870 --> 11:50.030] The idea was a domain name could specify what their signing practices are for email using DKIM. [11:50.130 --> 11:53.530] You can say, I don't know if my mail is going to be signed. [11:54.210 --> 11:57.350] You can say, I sign all of my mail. [11:57.630 --> 12:00.770] And you can say, I sign all of my mail. [12:00.770 --> 12:04.710] And not only that, if you see anything I didn't sign, please throw it on the floor. [12:04.710 --> 12:06.090] Dev null it. [12:07.910 --> 12:21.230] The author of the standard now advocates, instead of this standard, you should pass around private lists of email, of domain names that actually know what they're doing. [12:25.550 --> 12:34.430] For example, I found that Yahoo has an ADSP discard record set, which means you should throw away all of their email that's unsigned. [12:34.890 --> 12:37.890] They also use test keys in production. [12:38.750 --> 12:45.450] So, all of their mail is sent out with a key that says, you should not treat this differently from unsigned mail. [12:46.690 --> 12:52.490] And their signing practices policy says that they want everybody to throw all of that email on the floor. [12:52.550 --> 12:57.330] So, if your mail server accepts mail from them and is implementing these standards, it's broken. [13:05.400 --> 13:08.460] Yes, Yahoo was one of the authors of the DKIM standard. [13:08.640 --> 13:13.140] There's one of their engineers is listed in the standards and they still got it wrong. [13:14.300 --> 13:15.840] That will be a theme tonight. [13:22.380 --> 13:27.840] So, there's nothing inherently broken about DKIM, it's just that getting it right is hard. [13:29.800 --> 13:32.060] And getting it right is the exception. [13:32.320 --> 13:39.560] Basically, the only organization that I've seen that I would consider to not be doing anything silly is Facebook. [13:39.900 --> 13:47.200] I'm not really a fan of Facebook, but somebody called them out in their blog about screwing it up and they stopped screwing up. [13:47.580 --> 13:49.680] Yay, Facebook, for something. [13:51.820 --> 14:00.240] Key rotation is something that's specified in the standard because smaller keys are often used. [14:00.620 --> 14:07.460] So, they say, oh, well, it's okay if you use smaller keys because they don't need a long lifetime. [14:07.500 --> 14:10.980] You can just change your key every couple of months. [14:14.540 --> 14:21.460] Yeah, expecting people to do things after they've got something set up and working. [14:23.120 --> 14:25.560] You're gonna lose that every single time. [14:26.440 --> 14:32.080] Third-party mailing services, as I mentioned earlier, often provide keys to customers. [14:32.320 --> 14:34.280] Customers don't audit those keys. [14:34.280 --> 14:42.560] They don't check to see whether that mailing service has used that key at 50 other customers, for example. [14:46.020 --> 14:51.580] And the protocol is described as not particularly security sensitive. [14:51.800 --> 15:07.360] But because it's used for whitelisting and reputation techniques, a lot of trusted domain names, if they're DKIM signed, the spam filters will let anything through as long as it's got a valid DKIM signature. [15:07.940 --> 15:08.860] That's a lot of fun. [15:10.180 --> 15:11.060] Even if... [15:12.160 --> 15:14.460] I don't know if anybody's familiar with SPF. [15:14.880 --> 15:15.320] It's... [15:15.320 --> 15:20.800] It allows you to put a text record in for your domain name that says what IP addresses you're going to use to send mail. [15:21.520 --> 15:25.520] So, you can say, oh, I only use this IP address to send mail. [15:25.640 --> 15:30.380] And if you see anything from a different IP address, it's a forgery and you should drop it on the floor. [15:30.860 --> 15:42.340] But I have seen a couple services which will take a DKIM signature as an override for that and forward the mail along anyway. [15:47.130 --> 15:47.850] I'm sorry? [15:50.750 --> 15:51.350] Right. [15:51.570 --> 15:52.790] But even if the... [15:53.510 --> 15:59.510] Even if the SPF policy is to hard fail, the DKIM will work anyway. [15:59.730 --> 16:01.130] So, how weak are weak keys? [16:01.130 --> 16:03.670] 384-bit keys which... [16:04.550 --> 16:07.370] Anybody who uses those should be punched in the face, really. [16:08.510 --> 16:09.070] Because... [16:11.090 --> 16:17.790] I think the first time somebody broke a 384-bit key was one of the RSA challenge numbers. [16:18.250 --> 16:21.350] RSA, the company who... [16:21.350 --> 16:23.750] It was started by the guys who invented this algorithm. [16:24.730 --> 16:28.150] They released a bunch of challenge numbers to test the security of RSA. [16:28.150 --> 16:29.830] There used to be prize money attached to it. [16:30.090 --> 16:40.570] Back in 1992 or 1994, somebody broke a 384-bit key in a couple of months with a few computers. [16:41.730 --> 16:46.890] That was a big deal at the time, but it's almost two decades later. [16:48.810 --> 16:50.790] Why is anybody still using that? [16:51.210 --> 16:52.690] 512-bit keys. [16:55.130 --> 16:56.590] $1,000 PC. [16:58.470 --> 17:00.070] High-end core i7. [17:00.670 --> 17:03.550] We'll cut through these in three to four weeks. [17:03.810 --> 17:13.290] An interesting thing about the algorithms necessary to break RSA is that the algorithm depends only on the size of the key. [17:13.290 --> 17:17.650] So there's no getting lucky and getting it fast or getting unlucky and getting it slow. [17:18.230 --> 17:22.750] Pretty much every key of the same size will take very close to the same amount of time to break. [17:24.070 --> 17:35.610] 512-bit keys, based on my own back-of-the-envelope calculations on how much it took to break a key on EC2. [17:35.610 --> 17:43.330] I'm guessing you could spend one to two million dollars to break a key in a 768-bit key in EC2. [17:43.550 --> 17:46.210] But there's not a lot of people using these for DKIM. [17:48.330 --> 17:49.610] 1024-bit keys. [17:50.970 --> 17:57.910] One of the guys who invented RSA put out a paper talking about the cost of cracking those in 2003. [17:57.910 --> 18:09.010] He was estimating with custom hardware you could do it for about $10 million in hardware costs plus $20 million in design costs. [18:09.170 --> 18:11.750] But this was almost a decade ago. [18:12.090 --> 18:16.390] A lot has changed in manufacturing since then. [18:19.650 --> 18:31.090] For numbers here, the RSA 768 challenge number, which was cracked I think about two years ago, they spent 15,000 core years on it. [18:33.010 --> 18:37.730] But a large botnet can be 30,000 hosts. [18:41.140 --> 18:43.700] Don't use 768-bit keys either. [18:44.060 --> 18:44.260] Yes? [18:48.400 --> 18:53.700] Yeah, NIST says that you should not be using keys smaller than 2048-bit for anything. [18:56.880 --> 18:57.400] No. [18:59.040 --> 19:01.880] I will get into that on this slide. [19:06.580 --> 19:09.260] So, why would people use these shitty keys? [19:12.120 --> 19:15.420] DNS has been around since the dawn of the Internet pretty much. [19:15.420 --> 19:17.140] It's a 30-year-old protocol. [19:18.060 --> 19:19.780] Dial-up was the norm when it was invented. [19:20.240 --> 19:26.880] And dial-up had a maximum transmission unit of 576 bytes. [19:26.940 --> 19:32.840] So, you had your IP header, your UDP header, and then your DNS response. [19:32.980 --> 19:36.980] And that all had to fit in 576 bytes to work well. [19:36.980 --> 19:39.560] So, they rounded down to 512 bytes. [19:39.760 --> 19:42.980] That's the maximum size of a DNS packet over UDP. [19:45.800 --> 19:58.600] A 2048-bit key, because of the Base64 encoding overhead, the ASN.1 encoding overhead, all of that stuff. [19:58.600 --> 20:04.360] And not only do you have to include the raw modulus, there's also a public exponent you have to include. [20:05.200 --> 20:08.840] You get really close to that limit with even a 2048-bit key. [20:09.100 --> 20:11.420] And a 4096-bit key won't fit. [20:12.360 --> 20:17.500] So, people, when they were writing up the standard, they were worried about that. [20:17.500 --> 20:20.120] That's one of the reasons smaller keys are common. [20:20.300 --> 20:26.180] In fact, the standard does not even require verifiers to support keys larger than 2048-bit. [20:28.300 --> 20:33.440] CAs, I think in the last couple of years, we've given the CAs a lot of shit. [20:33.780 --> 20:39.620] But, at least they keep most people from doing painfully stupid things. [20:40.260 --> 20:41.460] They have some use. [20:47.740 --> 20:49.580] And weak keys are faster. [20:49.800 --> 20:58.220] If you are sending out an email to every single one of your customers, you're kind of annoying. [20:58.420 --> 21:01.140] But you also want that to go fast. [21:01.720 --> 21:03.580] Smaller keys compute faster. [21:07.230 --> 21:09.360] People like fast email delivery. [21:11.990 --> 21:15.160] And, you know, the standard was designed with modest security goals. [21:15.270 --> 21:16.560] Nobody really cares about this. [21:16.560 --> 21:20.230] And as long as my email is going through to all of my customers, I don't care. [21:20.710 --> 21:21.140] Yep. [21:25.480 --> 21:26.940] So, what have we got in the wild? [21:28.540 --> 21:32.820] The blog post I mentioned about Facebook, the link is up there if you want to read it. [21:33.980 --> 21:38.420] This guy spent 70 days trying to crack their 512-bit key. [21:38.620 --> 21:39.060] Gave up. [21:40.180 --> 21:41.560] Posted on his blog about it. [21:42.040 --> 21:42.940] They fixed it. [21:44.980 --> 21:47.640] There was a follow-up blog article from somebody at Cisco. [21:48.780 --> 21:54.700] Cisco bought Ironport Systems a few years back, which is a spam filter appliance company. [21:54.900 --> 21:56.260] So, they've got a bunch of test data. [21:58.300 --> 21:59.380] That's some tests... [21:59.380 --> 22:05.100] That's some in the wild data from the systems they have, but it's two years old. [22:05.100 --> 22:13.320] I unfortunately do not have access to mail servers that process email for thousands of people or tens of thousands of people. [22:13.600 --> 22:15.640] So, my data is not as good. [22:15.800 --> 22:22.540] But I wrote a tool called DKIM scrape, which will connect to an IMAP mailbox and pull all of the DKIM headers out of it. [22:23.340 --> 22:29.400] I did this against my Gmail account and Gmail accounts of a couple of friends. [22:29.920 --> 22:31.820] And I found some interesting things. [22:33.800 --> 22:36.540] Anybody heard of a company called Epsilon Interactive? [22:38.740 --> 22:43.840] Early last year, they were the ones who had a massive email breach. [22:43.840 --> 22:53.240] They had email lists for many customers stolen and those have been actively used for spam. [22:56.000 --> 22:59.580] There were a lot of notifications that went out to affected customers. [22:59.580 --> 23:05.200] Some companies didn't notify their customers because they don't have to. [23:07.380 --> 23:14.200] But, you know, I would wager most of the people in this room are a customer of a company that was affected by this breach. [23:17.900 --> 23:21.740] Currently, they have moved all of their customers to a 1024-bit key. [23:22.040 --> 23:24.800] And I believe it's unique per customer. [23:24.800 --> 23:26.280] I can't recall at the moment. [23:26.400 --> 23:30.740] But the old 384-bit key is still there. [23:31.460 --> 23:33.520] They were notified about this nine months ago. [23:33.520 --> 23:34.720] They didn't fix it. [23:35.480 --> 23:37.360] So, I'm calling them out on that. [23:40.820 --> 23:50.660] Yeah, their customers include several very large banks, several brokerages, luxury hotel chains. [23:52.180 --> 23:56.480] Those are some enticing targets for somebody who wants to run a phishing campaign. [23:58.820 --> 24:07.880] There's also a large dial-up ISP in the United States that uses the same 384-bit key for every ISP's domain name that they've ever bought. [24:08.440 --> 24:10.060] Which is well over a hundred. [24:12.120 --> 24:18.500] I'm not gonna say which one, but I think there's two possibilities left. [24:20.760 --> 24:24.720] eBay and PayPal were some of the ones that were pushing this standard. [24:24.940 --> 24:32.780] Because if you've been on the Internet a while, you'll remember that there was lots of phishing for eBay and PayPal. [24:33.600 --> 24:37.820] Because PayPal accounts, well they had money, they were attached to bank accounts, you could drain them. [24:37.820 --> 24:49.140] And on eBay, you could sell something that you don't actually have, get paid, run off with the money, and by the time anybody gets wise to it, you're long gone. [24:49.380 --> 24:51.940] So, both of them have accounts that are very valuable. [24:55.480 --> 25:06.000] I, through my DKIM Scrape program, found a 512-bit key that they're no longer using, but they have not removed it from DNS. [25:06.300 --> 25:10.040] And I emailed them two months ago to point this out to them. [25:10.260 --> 25:11.300] They didn't remove it. [25:11.460 --> 25:12.140] I cracked it. [25:12.300 --> 25:13.020] It was fun. [25:15.560 --> 25:17.080] So, that key. [25:17.620 --> 25:20.560] The other interesting thing about it is, that was a test key. [25:21.760 --> 25:24.000] I remember what I said earlier about test keys. [25:24.340 --> 25:25.860] They're to be treated at... [25:25.860 --> 25:30.260] Any email signed with a test key is to be treated as if it was unsigned. [25:31.020 --> 25:37.560] eBay and PayPal are about the only companies that are widely actually... [25:39.720 --> 25:44.760] Where the actual practice is to drop any email from them that is unsigned. [25:45.360 --> 25:47.160] So, this happened. [25:50.840 --> 25:54.240] I got that through to my Gmail account. [25:54.980 --> 25:56.140] There's a nice little... [25:56.480 --> 25:57.080] There's a... [25:57.080 --> 26:00.440] In Google Labs, there's an option you can go that will... [26:00.440 --> 26:05.820] Put a nice little key icon next to legitimate email that is signed with DKIM. [26:06.080 --> 26:08.440] This only works for eBay and PayPal right now. [26:08.440 --> 26:09.760] So, it's... [26:09.760 --> 26:10.900] It's really fun that I got it. [26:12.120 --> 26:12.640] And... [26:13.600 --> 26:14.120] That... [26:14.120 --> 26:15.220] That doesn't really... [26:15.220 --> 26:17.780] Does that look like it is actually from eBay to any of you? [26:18.040 --> 26:18.940] Totally legit. [26:19.740 --> 26:20.680] Totally legit. [26:21.680 --> 26:22.200] Okay. [26:22.780 --> 26:25.740] Here's a little more of Gmail's UI. [26:26.840 --> 26:27.680] If you... [26:27.680 --> 26:31.780] If you click the little info button, it'll say signed by eBay.com. [26:32.500 --> 26:35.560] And this went straight into my inbox and was marked as important. [26:36.640 --> 26:37.480] Very important. [26:37.480 --> 26:38.220] It is. [26:38.320 --> 26:40.500] Very important opportunity to... [26:40.500 --> 26:42.640] For natural mail enhancement. [26:43.900 --> 26:44.500] Okay. [26:44.860 --> 26:45.440] So... [26:46.700 --> 26:47.300] That... [26:48.700 --> 26:49.300] That's... [26:49.300 --> 26:50.080] Shown off. [26:50.200 --> 26:50.980] How do we crack keys? [26:52.660 --> 26:53.260] So... [26:53.260 --> 26:56.740] First off, I'm gonna take a few minutes to talk about how RSA works. [26:56.980 --> 26:58.320] This is really basic. [26:59.140 --> 27:03.600] The Wikipedia article has a lot more detail if you're interested in how it works. [27:03.600 --> 27:04.360] But... [27:05.120 --> 27:05.580] The... [27:05.580 --> 27:06.660] Relevant stuff for this talk. [27:07.080 --> 27:09.160] First off, it's an asymmetric algorithm. [27:09.480 --> 27:11.320] Which means there's a public key and a private key. [27:11.560 --> 27:13.180] You can give everybody the public key. [27:13.400 --> 27:14.080] That's cool. [27:14.460 --> 27:16.040] As long as you keep your private key private. [27:16.320 --> 27:18.340] The public key is made up of two numbers. [27:18.340 --> 27:20.620] N, which is called the modulus. [27:21.220 --> 27:23.680] And E, which is the public exponent. [27:24.180 --> 27:27.120] The private key has three additional numbers. [27:27.280 --> 27:34.880] P and Q, which are two large primes that are approximately the square root of the modulus. [27:35.720 --> 27:39.400] The modulus is generated by multiplying those two numbers together. [27:39.660 --> 27:40.520] And D. [27:42.560 --> 27:44.040] There's an equation up there. [27:45.260 --> 27:51.760] D can be derived from E, P and Q if you have those three numbers. [27:53.200 --> 27:59.740] There is an algorithm that will efficiently determine D if you have the rest of the numbers. [27:59.740 --> 28:07.140] I am not going to get into it because OpenSSL has that built in if you want to make a key with custom parameters. [28:09.780 --> 28:15.120] So, that leaves us with P and Q as the two important numbers that we would need to find. [28:16.080 --> 28:18.600] And we can do this by factoring the modulus. [28:20.900 --> 28:24.480] Now, 512 bit keys, that's a 155 digit number. [28:25.000 --> 28:26.780] That is a lot of work to factor. [28:26.780 --> 28:31.000] As I mentioned earlier, it took my PC 22 days to find it. [28:32.240 --> 28:33.500] So, how do we do this? [28:33.660 --> 28:37.060] There is an algorithm called the general number field sieve. [28:39.240 --> 28:43.320] I have to admit here, I don't really understand how it works. [28:43.920 --> 28:47.720] One of my friends told me that I was a math script kitty and he's right. [28:48.060 --> 28:50.320] But that's okay. [28:50.640 --> 28:53.180] I think everybody was a script kitty at something one day. [28:54.700 --> 28:55.960] And I'm trying to learn more. [28:56.700 --> 29:01.100] There's a bunch of open-source tools that do bits and pieces of this algorithm. [29:01.480 --> 29:03.460] There's a bunch of stages to it. [29:03.600 --> 29:04.660] It's really complicated. [29:05.900 --> 29:06.900] Some people... [29:06.900 --> 29:09.560] There was a Perl script that was written a while ago. [29:09.820 --> 29:11.100] It mostly worked. [29:11.580 --> 29:13.200] Somebody wrote a better Python script. [29:13.560 --> 29:17.740] It automates running all of the tools necessary to perform the algorithm. [29:18.800 --> 29:20.460] Key conversion is still tedious. [29:21.180 --> 29:26.540] Going from an RSA public key, getting the modulus out of it takes a bit of work. [29:29.260 --> 29:35.060] The open SSL tools that you can use to pull the modulus out of the public key give you hex. [29:35.320 --> 29:38.180] You have to feed it to these tools in decimal. [29:40.520 --> 29:45.140] And then even more tedious is to turn the factors into a private key. [29:45.240 --> 29:47.340] I could not actually find a program to do this. [29:47.880 --> 29:50.380] I wrote a very small Perl script to do it. [29:51.320 --> 29:52.560] I will show you that in a bit. [29:54.180 --> 30:01.220] If you want to try FactMciv, there's a great tutorial on using the Python script. [30:02.560 --> 30:05.340] There's a bunch of dependencies to set up. [30:05.500 --> 30:10.840] But if you can follow a how-to and you have a Linux box, it's pretty easy. [30:11.220 --> 30:14.220] I think there's even pre-built Windows binaries if you want to do that. [30:16.540 --> 30:22.880] That is how you would convert a DKIM text record to a modulus, except for the step where you turn it into decimal. [30:24.880 --> 30:26.000] Does that look fun to you? [30:26.260 --> 30:26.680] No. [30:27.520 --> 30:28.440] I don't think so. [30:32.240 --> 30:36.880] When I was testing this out, I ran some commands like that. [30:37.240 --> 30:46.100] I popped the modulus into Python in hex, which happens to do a great job of converting large hexadecimal numbers into regular decimal numbers. [30:46.880 --> 30:47.840] Yay, Python. [30:48.520 --> 30:51.380] You save it to a file called foo.n. [30:51.900 --> 30:53.380] And you run... [30:53.380 --> 30:55.220] Oh, there's a typo in my slide. [30:55.400 --> 30:55.580] Okay. [30:55.580 --> 31:05.200] You run fact msive with the root of the file name as a parameter, and off it goes. [31:05.500 --> 31:06.320] And then you wait a while. [31:10.260 --> 31:20.300] I played around with doing this on EC2, because I had another key that I wanted to crack for this presentation, and it wasn't going to finish in time. [31:23.480 --> 31:25.720] The setup for that is fairly simple. [31:26.820 --> 31:30.720] You can run the polynomial selection phase of the algorithm. [31:31.000 --> 31:32.660] That's the first phase. [31:32.800 --> 31:50.240] There's polynomial selection, the sieve phase, then there's some post-processing where you build up a huge matrix of relations found in the sieve phase, and then you run a solver on that. [31:53.320 --> 32:02.340] So, ran that on my PC, uploaded the polynomial that came out of that phase to an EC2 instance. [32:03.680 --> 32:06.540] Started up a bunch of cluster compute spot instances. [32:08.480 --> 32:11.020] I don't know how familiar people are with EC2. [32:11.100 --> 32:27.260] They have a system where you can bid on spare capacity in the system, which will let you get a resource that normally costs $2.50 an hour for $0.25 an hour, as long as you don't mind having it shut down unannounced if somebody wants to pay more than you. [32:28.660 --> 32:30.040] For this, that's fine. [32:31.940 --> 32:37.900] So, you've got one node that'll be a master for the computation and a bunch of slave nodes. [32:38.040 --> 32:39.480] I did this with 16 instances. [32:40.240 --> 32:44.460] The sieve phase took about six hours and cost me about $100. [32:47.200 --> 32:50.760] $100 is totally worth it if you're going to be doing a phishing campaign. [32:53.940 --> 32:55.660] You do have to kind of baby it. [32:55.860 --> 33:06.380] I didn't see a way to get it to automatically stop my extra instances, and since those were costing me several dollars an hour, I just waited around and shut them off. [33:07.020 --> 33:09.360] And then you've got your post-processing. [33:11.420 --> 33:16.020] That takes a while, but at least at that point. [33:16.200 --> 33:18.640] The post-processing only runs on one computer. [33:18.920 --> 33:21.740] I couldn't find a way to make it run on multiple computers faster. [33:22.740 --> 33:24.720] I think that's a limitation of the tools. [33:28.240 --> 33:33.820] So, I wrote a few programs to do stuff. [33:34.740 --> 33:43.680] The first one I wrote was a program that will take a factorization and convert it to a private key given the public key. [33:44.560 --> 33:48.460] You can also easily extract the public key from a certificate. [33:48.820 --> 33:56.580] If you're, say, I, there was the TI calculator signing keys that were cracked a while ago. [33:56.720 --> 33:58.800] That was a certificate, not a raw public key. [33:59.220 --> 34:00.960] Public key is easy enough to extract. [34:02.700 --> 34:10.160] So, you give this tool either the log file from fact mciv or the raw factor. [34:10.780 --> 34:15.380] You, just one of the factors is fine because you just divide the modules by the factor and you get the other one. [34:15.600 --> 34:17.980] It generates a valid private key file that you can use. [34:19.000 --> 34:27.820] I wrote a program called DKIMScan, which is almost to the level of being a denial of service tool. [34:27.820 --> 34:40.220] But I took the list of selectors I saw from scraping a few male spools and compiled a word list with a bunch of rules. [34:42.100 --> 34:45.320] I've got some example rules up there. [34:46.060 --> 34:54.220] Essentially what it does is it can take a word, a plain word list and scan all of those entries. [34:54.680 --> 34:57.340] But there's also a couple of expansions that you can do. [34:57.900 --> 35:02.980] There's a numeric range expansion which can be used either with or without leading zeros. [35:04.760 --> 35:11.000] There, and because I wrote it in Perl, the numeric range expansion operator also works on letters. [35:15.890 --> 35:16.450] Really? [35:16.690 --> 35:17.150] Okay. [35:19.190 --> 35:22.410] Oh, that's a typo not a spelling error. [35:27.080 --> 35:35.660] Anyway, the other fun thing is there's an expansion rule that will take the domain name that you're currently looking at and slice and dice the parts of that. [35:36.560 --> 35:42.180] I saw a fair number of domains that just use their domain name again as the selector. [35:42.580 --> 35:43.500] That'll find that. [35:44.180 --> 35:52.460] We've got DKIM dump which given a domain name and a selector will give you data about the public key that's up there. [35:53.220 --> 35:55.720] This is a test that I set up. [35:56.840 --> 35:58.980] This is a 256-bit key. [35:59.240 --> 36:02.580] I have not seen any keys that small actually used in the wild. [36:03.540 --> 36:04.720] But that would be terrible. [36:08.320 --> 36:09.880] This is flagged as a test key. [36:10.000 --> 36:11.880] This is a slightly older version of my tool. [36:11.880 --> 36:16.740] The current one will actually list out whether it's flagged as test or if it's ready for production. [36:17.580 --> 36:19.500] That's what the public key looks like. [36:20.920 --> 36:25.740] I've also got a fingerprint field there which is a SHA-1 of the public key. [36:26.260 --> 36:34.000] You can use that to tell which domain names are using the same public keys. [36:34.220 --> 36:41.400] If, for example, they're using the same marketing company or they're a bunch of domain names owned by the same company and they don't care. [36:43.240 --> 36:45.620] Then we have DKIM crack which is lots of fun. [36:47.980 --> 36:56.020] Once you've got fact msiv set up, all you have to do is give DKIM crack the domain name and the selector and it does everything. [36:57.080 --> 37:10.440] It will pull the public key out of DNS, extract the modulus, save it to a config file for fact msiv, run fact msiv, give you a vague estimate of how long it's going to take and automatically construct the private key. [37:11.800 --> 37:14.840] I have a demo of that tonight in fact. [37:15.340 --> 37:22.600] And then there's DKIM spoof which will take that private key and a well formatted email message. [37:23.620 --> 37:32.720] And it will add the DKIM header to that email message so that you can use it without setting up your mail server to send it. [37:32.840 --> 37:33.080] Okay. [37:33.380 --> 37:35.800] Let's see if my laptop still hates me. [37:46.110 --> 37:46.790] All right. [39:00.900 --> 39:01.960] Okay, that's too big. [39:15.170 --> 39:16.450] Can everybody read that? [39:16.730 --> 39:17.150] Yeah. [39:25.720 --> 39:27.720] So here's that test domain I showed you. [39:47.570 --> 39:48.690] Oh, crap. [39:53.380 --> 39:54.500] I can fix that. [40:28.640 --> 40:32.300] That's what I get for not testing this part of the demo. [41:30.320 --> 41:34.800] One benefit of VC2 is that their package mirrors are very, very fast. [41:39.910 --> 41:40.510] Okay. [41:40.510 --> 41:44.350] Let's see if I forgot any other dependencies. [41:44.730 --> 41:45.490] I did. [41:57.650 --> 41:58.490] Thank you. [41:59.970 --> 42:00.750] I'm sorry. [42:00.870 --> 42:02.810] I'm an absolutely terrible typist. [42:08.520 --> 42:09.120] Okay. [42:09.340 --> 42:11.260] I will do a different demo then. [42:22.730 --> 42:26.130] I get up on stage and I make every single typo possible. [42:26.790 --> 42:30.770] And my computer spends the first ten minutes not working. [42:32.750 --> 42:33.330] Okay. [42:40.150 --> 42:40.910] That one. [43:07.120 --> 43:07.700] Okay. [43:07.920 --> 43:08.880] Let's see if it works. [43:13.140 --> 43:17.800] I'll try this one more time and then I will do another demo that actually works. [43:19.340 --> 43:19.810] Okay. [43:21.110 --> 43:21.600] Great. [43:21.770 --> 43:34.850] So what this would do if I hadn't been too stupid to set up all of the dependencies ahead of time, because I had been testing this on a different system, is it will run msiv. [43:34.850 --> 43:42.880] This key is kind of a rig demo because 256-bit key takes about three minutes to crack. [43:44.590 --> 43:46.390] But it'll output the private key. [43:47.460 --> 43:51.180] So I did already do a key. [43:52.340 --> 43:55.340] Anybody familiar with the Black Hat Security Conference? [43:55.350 --> 43:57.080] It's in Vegas in about a week. [44:00.300 --> 44:04.940] They use an outsource provider to handle sending out their marketing messages. [44:05.270 --> 44:06.840] And they use a 512-bit key. [44:07.500 --> 44:10.890] And this was the key that I cracked on EC2 in about eight days. [44:28.670 --> 44:29.450] There we go. [44:30.010 --> 44:36.530] If you've already cracked it, it will just pull the factors out of the log file and give you the private key directly. [44:36.530 --> 44:38.490] So there we have a private key. [44:43.080 --> 44:43.680] Okay. [44:43.680 --> 44:46.180] Let's see if I am logged into my Gmail account. [44:51.490 --> 44:52.090] Excellent. [45:12.810 --> 45:13.410] Okay. [45:13.630 --> 45:16.410] This is sending it without a signature. [45:18.330 --> 45:20.870] And this should go to my spam folder. [45:24.750 --> 45:25.610] There we go. [45:25.610 --> 45:29.850] So this went to my spam folder because I'll show you here in a second. [45:32.350 --> 45:33.390] SPF failed. [45:33.910 --> 45:35.330] In fact, it hard failed. [45:35.670 --> 45:42.510] Because they specify if they don't whitelist the white IP address, it's fake. [45:45.690 --> 45:46.290] So... [46:09.590 --> 46:10.590] Herp derp. [46:24.010 --> 46:25.670] And that one made it to my inbox. [46:29.070 --> 46:29.670] And... [46:30.750 --> 46:31.670] There we go. [46:41.840 --> 46:43.600] What was the difference in what you did? [46:44.080 --> 46:48.680] The second time I used DKIM spoof with that private... [46:48.680 --> 46:49.280] What? [46:53.790 --> 46:54.710] Oh, I'm sorry. [46:54.830 --> 46:56.110] I didn't show original on this. [46:56.330 --> 46:56.630] You're right. [47:06.340 --> 47:06.780] Authentication. [47:07.180 --> 47:14.700] So it's got a valid DKIM signature here somewhere in there which I can't see right now because reasons... [47:15.060 --> 47:16.300] It says the DKIM... [47:16.300 --> 47:19.420] It should say in there somewhere that the DKIM signature is valid. [47:19.680 --> 47:19.920] I don't... [47:22.980 --> 47:23.420] Okay. [47:23.700 --> 47:24.060] Thank you. [47:24.180 --> 47:25.060] I still can't see it. [47:25.140 --> 47:25.720] I don't know why. [47:26.660 --> 47:27.120] Um... [47:27.120 --> 47:30.600] I'm sorry that I had some technical difficulties with my talk. [47:30.800 --> 47:32.000] I have a few minutes for questions. [47:32.940 --> 47:35.380] Why does the message still go through? [47:35.640 --> 47:37.300] Do you want an SPF decision for a fail? [47:37.480 --> 47:39.440] Because DKIM is safe and trusted. [47:39.700 --> 47:40.800] And you should trust it. [47:43.140 --> 47:43.660] Um... [47:43.660 --> 47:45.760] Also because SPF is not the best way forward. [47:46.020 --> 47:46.320] Yeah. [47:46.620 --> 47:48.740] People screw up SPF all the freaking time. [47:50.300 --> 47:51.340] So, uh... [47:51.340 --> 47:54.540] Quickly, a few other things that I'd like to do. [47:54.540 --> 47:55.180] Uh... [47:55.180 --> 47:55.620] I've... [47:55.620 --> 48:01.020] Been working on some tools to track key usage over time by monitoring mail spools. [48:01.360 --> 48:04.980] See when people rotate their keys, when they change key sizes, stuff like that. [48:05.680 --> 48:06.060] Uh... [48:06.060 --> 48:07.820] Add some database support to my tools. [48:08.820 --> 48:14.860] Integrate DNS service with email servers so that you have idiot-proof key rotation. [48:16.700 --> 48:17.180] And... [48:17.180 --> 48:20.020] As to how not to screw this up, uh... [48:20.620 --> 48:23.220] Use 2048-bit keys if possible. [48:23.540 --> 48:30.880] If you can't because they won't fit, 1536 rotated quarterly should be safe. [48:31.960 --> 48:32.440] Uh... [48:32.440 --> 48:34.320] If you get screwed doing that, it's not my fault though. [48:35.440 --> 48:35.920] Uh... [48:35.920 --> 48:37.200] Make sure you delete the old keys. [48:37.500 --> 48:40.360] Make sure you check to see what your third-party mailer is doing. [48:42.140 --> 48:42.620] And... [48:42.620 --> 48:53.760] If you've got a third-party mailer, you can CNAME the DKIM record so that if they need to rotate it for whatever reason or it gets compromised, they can just delete it. [48:53.880 --> 48:53.980] Okay. [48:54.060 --> 48:55.760] I have time for maybe one more question. [48:56.000 --> 48:59.540] How much did it cost for you to run and write the key in the EC2 cloud? [48:59.760 --> 49:00.960] Oh, um... [49:00.960 --> 49:03.120] If I didn't say that, it was about $120. [49:06.040 --> 49:07.800] Are you publishing your tools at all? [49:07.980 --> 49:08.420] Uh... [49:08.420 --> 49:08.580] Yeah. [49:08.820 --> 49:13.400] They will be up on my GitHub account, which... [49:14.640 --> 49:15.360] Is... [49:16.560 --> 49:17.240] It's... https://github.com/quber7/dkimpwn [49:23.720 --> 49:24.440] Uh... [49:24.440 --> 49:25.200] Do I need to repeat that? [49:25.700 --> 49:26.300] Yes. [49:26.960 --> 49:27.680] Uh... [49:27.680 --> 49:28.200] Again, it's... https://github.com/quber7/dkimpwn [49:35.100 --> 49:35.120] There he goes. [49:35.120 --> 49:35.380] A penaltyyw's Now in 2006, has divorced onto the macroospine and SNES. [49:35.380 --> 49:36.060] Or... does this impact of this water when the input from everyone has been to the nosso