Well, Daniel Crowley is about to give an awesome talk on black box smart cards. So take it away. Hi, everybody. So I am the head of the research program at X Force Red, and that's about as much bio as I'll give. I think I have a fun bio in the DEF CON handout if you care to read it. But let's just get right into this topic. So smart cards are a part of our lives in many ways, some of them that you wouldn't expect. So credit cards and debit cards, you might recognize those immediately as smart cards. But then SIM cards, SIM cards are one that is also in the realm of smart cards. And things like transit fare cards or electronic passports are also examples. And, interestingly, all of the cards listed here, and Amiibos, by the way, those little statuettes that you can buy and put on your Nintendo Switch to unlock characters in different games, also smart cards, interestingly enough. So they are absolutely everywhere. And in many cases, unlike the Amiibos, they handle very important things like money or they control physical access to spaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . they're cryptographic keys, they're supposed to never come off. So they handle some very important things in our lives. And they're everywhere. So I thought that they were worth taking a look at. Now, all of the cards I'm talking about today are based on, they all kind of come back to the same standard of ISO 7816. And ISO 7816 defines a couple of things. It's specifically for contact cards. And it defined, in addition to the physical format of the connector and the pinout and everything like that, so you can actually make an electrical connection to the card, power it, and then communicate with the card. It defines voltages and things like that that I haven't really touched. But it also defines a sort of command format and a certain command set, a certain set of standard commands referred to as APDU is the format. It's Application Protocol Data Unit. We'll get a little bit more into that later. What it doesn't define, interestingly, is which commands must be implemented. So the standard defines something like... It says 20 or 30 different commands. But it says you don't really have to implement these. If you do, here's what you should do. But, you know, if you don't, you know, whatever, have a beer or something. I don't know. It's fine, I guess. And so, like, sometimes... And the other thing is the particulars of the implementation aren't defined. So, for instance, with a lot of cards, there is this challenge response. There's this challenge response mechanism where you tell the card, I need some random data. The card gives you some random data and you do something with it. Whether that's sign it with a cryptographic key or encrypt it with, you know, some sort of secret key that you share with the card. And then you send the processed version of this challenge back. And the card can tell if you have the right key material cryptographically, somehow. somehow, some magic that is not defined in ISO 7816. So there's potential for problems there. Then there's ISO 14443, which is a standard for contactless cards. Now this builds on top of ISO 7816, so ISO 14443 cards, NFC cards are an example of 14443. These built on 7816 and use the same APDU format, use some of the commands from this established command set from 7816. So ISO 7816 standard is really important to how all these smart cards function. Now, how well do these cards actually follow the standards? That's, you know, you can make a standard, but how well things actually follow it is, it depends. . As far as the physical connectors and stuff like that, as you would imagine, they follow the standard pretty well there because they kind of have to work. It's just not going to work at all. And then there's certain commands such as select file and verify. Select file is like what you would expect. It's like, hey, there's a file on the file system here. Although the file system is weird. We'll get to that. And then there's verify, which is kind of like you just give a password or a PIN or something like that to the card, and depending on whether it's correct or not, it will or won't unlock features of the card. The error codes in the 7816 documentation in the standard are pretty granular. They're saying, like, you know, this byte is wrong, that byte is wrong. Something. Some of the cards just use really whatever error codes they feel like. They'll use different error codes for, like, the same or similar situation. So it can be very frustrating if you're expecting certain error codes. So let's talk about APDU and what that looks like. So the way that a command looks on the wire with smart cards is like this. So this is the APDU for... Select file by dedicated file name. First occurrence named ABC. So let's break this down piece by piece. So the first byte is the CLA or class byte. And the class byte defines what category of instruction to execute. There's a convention where if the CLA byte begins with zero, it follows the ISO 7816 standard and is to be interpreted according to a series of bit flags. And if it begins with a one bit, so anything hex 8-0 or above, that is going to be interpreted according to a proprietary standard, which is, you know, outside the scope of 7816. And then it also says FF is invalid, can't use that. But there's another standard called PCF. PCFC, which is used by things like SIM cards, NFC tags, that, like, they do use... Like, you will actually see FF used in real smart cards. So it's kind of like, well, we just ignore that part of the standard because everybody else has. The INS byte, which is the next one, is what instruction or command to execute. And so for this one, A4 is select file. So this one is really well supported. You can sort it across the cards for reasons you might imagine. A lot of cards have reason to do things with files. We'll see why it's especially important for them to support file selection because there's this whole context thing and file system is kind of weird. We'll talk more about that shortly. The next two bytes, P1 and P2, are parameter bytes. So this says, you know, we've got our application class. We've picked out a command from that application class. These are two byte parameters to it. So this is mostly like, well, what variant of this command do you want to run or what, you know, data do you want to feed to this? So in this case, 4 for P1, the first parameter, means, you know, give me a name. There's a couple different ways to select files. But in this case, we're going, you know, first occurrence, which is P2 is 0. And don't worry if this doesn't make sense. This is just what they put in the standard, right? I'm just trying to break down, like, what's in what position. And then finally here, we have a single byte length followed by data of that length, which is meant to be like an argument to it. So in this case, this is the file name that we're actually requesting on the card, starting with ABC. Now, with this particular command, you can actually just request the first couple of bytes. But again, I'm getting ahead of myself. So there is also an optional field after this of the length expected, or LE. Now, we're not expecting any response here. And we can omit this, so we just don't have that. So that's, you know, the same goes for the data field. Like, if you don't have any data to append, you can just stop after 4 bytes and that's it. So this is what APDU commands look like. So let's look at the response. Responses are way simpler. They're just two status bytes. The first one defines sort of like the major response type, and the second one is the minor, like the subtype. So, for instance, hex 9 0, that's success. Yay, you did it. It worked. And 0 is the only subtype of that, right, at least in the standard. And the response can also include data. Or it can say, I have data for you. To be returned. But I'm not going to give it to you right now. If you really want to see it, you can use the get response command. Now, here's an error response. 6c means you didn't ask for the right length. You told me you wanted one length, or you didn't tell me what your expected response length is. Here is the expected response length. So this is one of those really, really helpful errors that's like, if you don't know what you're doing, this is great, because it's like, oh, thank you for giving me the right answer. But there's no data sent with this response, right? So here's some more response code samples. Some of these get pretty specific. And you can kind of see how if you are working with a smart card that you don't really understand, like, you know, it's not some specification that you're familiar with. Or it's some proprietary specification. Or something like that. Or you don't want to follow a higher level specification. You want to map out the entirety of a card, not just what follows the expected specification. You get error codes that say wrong CLA. Wrong INS. All this stuff. So when you're trying to figure out what's a good CLA, what's a good INS, and so on and so forth, you have all these wonderful error codes that sometimes are not used correctly. That said, they are there. Sometimes they work. So let's talk about how easy or how feasible it is to take just any old smart card, whether that's debit card, SIM card, anything that follows this 7816 standard, and figure out what are valid CLAs, valid INSs, all that. So with the CLA, if it's in following the 7816 standard. If it starts with a zero bit, then it follows a convention that we know about. So we only really need to try zero and then 80 through FF. So that's one plus 128 for 129 possible values. So we can try all of those and just get wrong CLA. And 129 values is a very short amount to have to brute force through. So that's very feasible. We can totally do that. INS values. There's only 256 possible codes. It's only one byte long. Now, ISO 7816 forbids anything that starts with six, like hex six whatever or nine whatever. In reality, there's a ton of commands that actually use this. So we just kind of, again, ignore this part of the standard because everybody else does. But even still. We're talking about 256 values. Right? And if we just look at a lot of different standards, like we look at EMV, we look at global platform, we look at VSDC, and see all the commands that they have, you know, standardized on. We can try just those if we want to cut it down. But again, 256 values does not take a long time to brute force through. So INS, we can totally do that. There are times. There are times when you get just generic errors and you have to brute force through both CLI and INS for, you know, can't do the math in my head right this second. But 256 times 129. Still, you know, in the tens of thousands of requests, you're talking a couple minutes. So that's, again, that's feasible. P1 and P2, that's two bytes. Brute forcing them at the same time. 650. 65,536 values. Totally feasible to brute force. So, so far, we can brute force through and find, like, whatever commands are available and what parameter values are accepted. Now, if we are trying every INS value, there are some potential pitfalls. Like, there is a terminate card usage. Slash, blow fuse. Which just means, like, fucking brick this card. You don't want to try that in most cases. Like, if you're really desperate, I guess you could. But there's some pitfalls to be avoided. So that is a consideration that you have to make when doing this. But also, the speed of a card might not matter. If you have a couple of the same type of card. Like, you have several debit cards from the same issuer, same bank, whatever. You can parallelize this across several readers. So, if you had a particularly slow card, but you had access to a bunch of them, you could parallelize this effort. Now, worst case scenario, you have generic error messages. Whenever anything goes wrong whatsoever. When the card doesn't like anything. Anything about what you're doing. It gives you the same error message. That means a lot of brute forcing. Right? If you have a slow card on top of that, that only supports ten commands per second. Which is pretty slow, but I can't imagine anything slower than that. We're talking about six years to try all the combinations. So that's not great. But luckily, we're not in this situation often. I haven't seen a smart card that is this worst case scenario. And I have, like, this stack that I've been playing with over the last couple of months. So, it's rare. Best case scenario, we're done very, very quickly. And actually, I have a sort of best case scenario card that I'm going to show you in a minute. So, when we're trying to identify files, which is another step. Right? We have a file system. Or a way of... Sort of a file system. Yeah, I guess it's a file system. On a smart card. We can brute force through file names. There's this concept... There's what's called right truncation, which is supported by a lot of cards. Which means if you have the file ABCDEFGH, you can ask for ABC. And the card will often say, good enough. Yeah. Here you go. I'll give you the file. That's enough of the file name. There's often a minimum amount of bytes that you must provide before it will go, okay, yeah, that's good enough. Usually that's five bytes. But then there's these things, registered identifiers. A lot of file names will start with a byte sequence that corresponds to a card manufacturer. These card manufacturers are supposed to get one of these five byte registered identifiers and make it public. There are public lists of it. There's like 600... Yeah, 652 in a public list that I found. So you can just brute force through all of those. That's pretty quick. That works extremely well. Extremely well. However, there's also the possibility that you have a card that just accepts one byte. So you can just brute force through one, two, three, four. All the way up to FF. And then, you know, if you have a card that just accepts one byte. So if you get a hit on A, and you get a hit on one, three, you can try A1, A2, A3, and so on and so forth until you've enumerated all files on the card. So that's another option, right? But sometimes cards also describe themselves to you, right? They have the opportunity to do so. One, through what's called the answer to reset. So when you hook up a card, the first thing that you do is you reset the card. You say, you know, let's reset and start a new session here. And that can come with a response that has some information about how the card works. It might tell you, hey, here's the first command that I expect from you. Which is really nice. And this is part of what's called the historical bytes. So sometimes the historical bytes are sent along with the ATR. And sometimes the ATR says, yeah, just go look in the usual place. And there's a standardized usual place, which is like a standard file identifier, right? And there you can find what issuer gave out this card, which may give you more information for documentation to look up. It may give you an indication of what application is implicitly selected. So sometimes when you hook up a card, it may give you more information for documentation to look up. So sometimes when you reset a smart card, upon reset, it selects a file for you. You don't have to select a file. It just says, I'm going to do this, right? And that's important because files are also applications sometimes. We'll talk more about the file structure. I probably should have put that earlier in the presentation. But we'll get there. So it will tell you this card has support for file or application selection by ID number. Or by name. Or by path. We'll talk about those in a second. But it can also tell you, hey, there's also a directory file. Because that's a thing as well. You can have a file that is a directory of all the files on the smart card. Which means that brute forcing files is unnecessary. What that also unfortunately means is that most smart cards do not have such a directory. There is no way. Without just knowing in advance what files are supposed to be there to just map out the file system. You can't just say, hey, what's in root? What's below that? What's in this and that? Right? You can't do that without brute force unless something like EF.dir exists. So I think, yeah, these two slides are redundant. Let's move on. So EF.dir just provides a directory. It's a directory of all the files. Now let's talk about the file system structure. So this diagram is maybe a little bit confusing. But if you want to blame somebody for it, it's not me. This is from the 7816 standard. So you have this thing called an MF or master file. This represents the root of the file system in the sort of file systems that you're used to from Linux, Windows, whatever. You have a master file. And under that is one or more EFs and DFs. Now, a DF is a dedicated file. That can contain data. That can be an application. That can be a directory. It can be all of those. So that's fun. Not every DF is an application. But every application has a DF. Right? And then EFs are just files, elementary files that just have some data attached to them. So files are also contexts. So one thing that's really important to know is that the commands that are supported by a smart card are dependent not only on the smart card just like the smart card but also the state of the smart card. Right? Like what file has been selected. So you might have four different commands that are available with the file that's implicitly selected when you reset the smart card. And then you may get access to ten or more commands when you select some file on the smart card. Because you're changing the context. Right? So this is important, too, because now we have to select a file and then brute force all the parameters of the file. So this is important for our enumeration efforts as well. I already covered this. The one thing I didn't cover from this slide is that there is a national ID. So we talked about registered identifiers just briefly, the five-byte identifiers. Every nation has a first byte. So if you know that a card comes from a certain country, you can try brute forcing just the second through the fifth byte of the file name and just rely on that country byte being correct. But that's small change. Now, there are other ways to select files other than a name that I've alluded to so far. You have implementation. You have implicit file selection, for instance. Which is where the cards select the file for you. But then there's also a two-byte identifier. Which, only two bytes, that's not so bad. We can brute force through that pretty quickly. And then there's paths, which are about the closest thing to a file path that you'll see. Like you would see on a traditional file system. And you have these two-byte identifiers that start with the root. And then you have just two bytes. And every two bytes defines, like, another path down. So when we go back to this, the MF is always 3F00 in this scheme. And so you might have a DF underneath that that is 0002. And a DF under that that's 1415. Or something like that. And so the path to that would be 3F00 0002 1415. Right? Just sort of, they're kind of like a file path, but without any slashes. There's no delimiter to separate the elements of the path. It's just based on the fields by byte position. Right? They're fixed length. And then with those DFs selected, there are elementary files underneath them that can be read out, that have data in them. And that can be through a couple of different, confusingly, a couple of different commands. Right? So read record and read binary are both about reading out elementary files attached to data files. And then get data reads files, reads data attached to the DF directly. So there is a potential for sensitive data exposure here on a card that you might be assessing. So as you look through the card, as you pull the data out, look at that data and make sure that there's nothing that should be exposed before authentication. Right? Or possibly after authentication. Right? So if you find the private key material on like an HSM smart card through just browsing, you know, through trying get data commands and stuff like that, that's not very good. So authentication on a smart card. We alluded to that a little bit. The simplest one, the one that's supported frequently is verify. And this, you just provide input. In plain text, a pin or password. And you just hope that you're either using an encrypted communication channel with the card, which is supported, but not frequently. It is at least part of the standard. I don't see a lot of cards that support it. But that said, you provide a pin or password. It goes across in the clear. And it's compared directly to whatever secret is on the card. And this is usually like a pin to unlock. A SIM card, for instance. If you do have somebody observing this transaction, they can see this authenticator. Right? So that is just an inherent problem with verify. And if it's like a, if this smart card is supposed to be used for something sensitive, that probably shouldn't be what's used. There's also other problems. You know, there's been some research in doing timing attacks. For instance. Because if you have a, if the way that you validate the pin is to check each character, character by character, through the whole password or pin, and then bail out once you reach an incorrect character, then you can time how long it takes to check, you know, given pins. And when one takes longer than another, you know you've got more of the leading bytes correct. Right? So this is something that's been done before. But it's definitely worth, it's definitely worth mentioning. Eavesdropping. That's, you know, we mentioned that. There's also the fact that some smart cards will enforce an upper limit on how many times you can try and get it wrong. That said, there is also a command reset retry counter, which if that's not authenticated. Like, if you can hit that without authenticating, then that's a problem, too, because that basically means that you have unlimited tries. And then the alternative is a challenge response. Which, again, is not, the details of that are up to the implementer. You can kind of do whatever you want. And that's interesting. And there's also no, there's nothing that mandates a particular type of random number generator. Right? So in theory, you could use a really crappy pseudo random number generator and seed it or seed it poorly. One of the big problems with IOT devices that has been a constant problem, a very hard to solve problem for a long time, is how to generate high quality random numbers. Because even if you have, like, a good algorithm, if you're starting from the same place, right, if you start with the same seed, or if your card, if your device just hasn't been up long enough to collect enough entropy to make good random numbers, it might be possible to just, you know, first thing you do, ask for a challenge as soon as you reset the card, you know, immediately. And then there's a very low set of states that it could be in. And so it may be possible to predict. The random number generators that will come out of a card. Just because of a low entropy situation. So the cryptography might be entirely broken. I found one card that did not enforce a minimum challenge length. So you could ask for a one-byte challenge, which is not great. You know, and especially if you can sit in between a card and a terminal and get the one-byte challenge to be issued. Then you can try and get that same challenge again and then authenticate to the card later. Right? So and just replay the response for that one byte. Because you have a 1 in 256 chance at random, if it is truly random, of getting that same challenge and being able to reuse that response. So fun stuff there. Something that exists that I have not had a chance to look at on a real smart card is S6. It is called SQL. Smart cards actually have their own sort of SQL variant. And it is in practice, it doesn't look a lot like SQL. There is an analog to all the different like, you know, insert, delete, update, whatever. This was the slide that I had planned to use for this. But as of yesterday, I actually ran into somebody. And got talking with them. And ran my tool that I'm going to release on one of their smart cards. And it happened to release, it happened to support SQL. But that was yesterday. So I didn't have time to really figure out how to use SQL. But I will be publishing information on that soon. Because finally I have a card that does that. So awesome. So let's talk about some things to look for. You know, we talked about unauthenticated sensitive commands. Reset retry counter, we mentioned that one. If you can reset the retry counter, you get infinite tries. One interesting thing is the Java card platform. The Java card platform is exactly what it sounds like. It is a Java virtual machine that runs on a smart card. And there is a load applet command. Now, ideally, this command would be disabled once the card goes to production. And as we all know, all application developers disable anything that's for debugging once something goes to production. Right? Everybody knows that? They don't do that. They don't do that. Disable verification requirement. That's just, it does exactly what it says on the TIN. If that's unauthenticated, that's a problem. Sometimes you may have undocumented applications or instructions. That are left on a card for debugging purposes. Maybe you didn't lock down load applet or something like that. Sometimes you have default keys or passwords that are on a card. And the verify is just something that's used to prove that you're the right kind of card reader. Right? So, a company that makes physical access cards, for instance, might have a key that they keep secret. That if you disassemble the device and pull the firmware and dig through it, you can find the key and be the right kind of card reader to access it. And do whatever you like with the card. Reprogram it. Give it a new whatever. There's also a classic problem with my fare cards. If anybody is staying. At Harrah's or Flamingo. Your cards are my fare 1K classics. And they are actually using default keys for several of the sectors. Which is interesting. There is, there are a lot of cards that have a verify code of four zeros. Just on, in their normal state. So, that could be an issue. But then. You also have to think about, like, smart cards are miniature computers. They are running code. APDUs are the way of accessing an API. Right? We are issuing commands and giving data. One really interesting thing is that you have this TLV, this TLV format. Which is tag length value. So, the way that a lot of data is expressed in smart card communications. Is you have one byte. Sometimes you can have multiple byte tags. But one byte that says this is the type of data that I'm about to give to you. Then you have a one byte or it's a fixed field. Sometimes it's one byte. Sometimes it's two. In smart card world, it's like I've only ever seen one byte. So, you have a one byte value that says here's the length of the data that I'm about to give you. So, one byte to determine what kind of data. One byte to determine the length. And then you just have the raw data. That should match the length. Now, that data can itself be TLV values. So, you can have, you know, that value has a tag length value structure as well. And when you're trying to parse these nested structures, there's a lot of opportunities for buffer mismanagement. Especially when these length values or tag values are malformed. So, there's a lot of potential problems here with buffer overflows. Maybe not so much when you're using Java card. But there's plenty of parser issues that are potentially a problem. There's plenty of just generic application security bugs that could be present in the various commands. So, anything to do with just your generic application security bugs could be a problem here. How the card is built, how the card is programmed, what libraries it uses to achieve its function and all that. There may be cryptographic flaws. We talked about the one byte challenge. There is the ISO 7816 standard is a little bit old. And some of the recommendations that it makes for things that cards might support are a little lax. Like one of the things I've seen is a recommendation on RSA with no padding. Which, if you're a cryptographer, you just winced. Because RSA with no padding is terrible. So, that's one of the things that comes up in the standard is a possibility for what you could do with your card. So, somebody has probably implemented that. So, what did I find on real smart cards? Historical bytes are pretty common. They will often tell you at least one application ID that you can work off of. And it's usually fruitful to brute force based off of the couple bytes at the start of that application identifier. It often describes how you're supposed to select files from a card. I have never seen a card support EF.dirt. That I haven't seen yet. Most cards want you to select text. Files by DF name. I've seen one card that supports selection by identifier. The whole DF name thing, like, there's cards that don't require a minimum number of bytes. But most of them require around five bytes. I found a card that supports the one byte challenge, as I mentioned earlier. I'm still talking with the vendor. So, I can't tell you what. What type of card it was, unfortunately. But now let me show you my tool that I built. So, it's called Wubblegum. It currently will enumerate through CLA values, files, INS commands. And then will dump any records or data attached to the files that it finds. And it will tell you for any command that it discovers. If that byte corresponds to, like, a well-known standard. And what byte and what that command byte does. Right? So, let's take a look at that. I have an old expired debit card here. And we'll just see this in action. Let me just make sure that I've got the right reader. And, by the way, the YubiKey is kind of like a combination smart card and smart card reader. Which is why it's showing up in the list here. So, I'm going to want to adjust which reader I'm using here. So, I'm using the options to enumerate class, files by name, INS, data. And I'm using the RID, the public RID list brute force technique that I discussed earlier. This card is pretty good about its error responses. Which is why I wanted to show you this one. So, it gets through the CLA brute force really, really fast. Like, I didn't even get a chance to do that. I just wanted to, you know, explain what it was going to do before it did it. Now, cards are a little bit weird about how they respond. So, I built in a thing where you can prune responses based on their response code. So, it gives you, like, it parses the response code and tells you in, like, plain English, like, what happened here. What is this complaining about? So, oh, that's... I got the wrong card. My bad. That was the YubiKey. I didn't want to do that. Let's switch to the right card. So, this takes slightly longer. This is a little slower. But here we go. So, this is saying, you know, you see, like, category three there, incorrect application, which is incorrect CLA. So, we're going to say delete that. And then we have 36 responses that say, you know, this logical channel is not supported. Which essentially means, like, yeah, this is, like, you've got the right prefix on this, but the bit flags aren't quite right. But logical channel support not supported means it's not going to work no matter what we do. So, we're going to want to just say, yeah, no. So, we'll delete that as well. So, now we have incorrect parameters, which is, like, great. We got a CLA and an incorrect at the same time. And then we got other responses as well. So, these are all good. We're going to accept that and move on. Now it's going to brute force through these five-byte registered identifiers and find whichever ones are available. So, since this is a credit card, debit card, like, it supports credit card and debit card, it's going to have applications for both of those usages on it corresponding to Visa, which it is. So, like, if you look up A0003. That's going to be ‑‑ you're going to find Visa, right? And so, it found a couple of different commands under this application identifier. And under this other one, we have, you know, a lot more complicated stuff of, like, we have verify and we have this get challenge and authenticate. And we have read records. So, we have a bunch of records and data that are on this card. So, we see, you know, we're dumping data from this application and from that application. And some of this is actually readable. So, like, when we take this data and we ‑‑ when we hex decode that, enhance. So, there's that. This is my name. So, we can pull some data from this. I don't believe there is any sensitive data exposed by this card without authentication, which is why I'm, you know, happy to show you my expired credit card. Also, it's expired. So, like, if you can manage to steal my credit card from this, then, like, sorry, it's already expired. Unless you can manage to get around that, in which case, I don't know, I mean, good for you, I guess. I guess I'll be impressed and we should talk. But, yeah. So, I already know that this card, it's going to brute force through a whole bunch of, you know, potential record IDs and not find anything more here. So, I'm going to cut this a little short. I've done, you know, proven that it works. So, that's the tool. This will be made available, by the way, on the Xforce Red GitHub account shortly after I get home from Vegas. So, expect it in the next couple of days. And there will probably be some bug fixes that come along, some new features added over time. This is still very much a work in progress. There's still, you know, there's plenty we talked about today that hasn't been implemented in the tool yet. So, right now, it's just sort of like a primitive port scanner, but for smart cards. And I'll build some basic vulnerability checks and things like that on top of it. But if you have any questions, I'm happy to answer them. If you have a smart card reader, like, you know, I can recommend the HID Omni key. No, I don't work for them. No, I'm not being sponsored by them. It's not terribly expensive if you want a smart card reader to start playing with your cards and with this tool. There's some future work to be done, like I said. I would like to be able to enumerate things from... Oh, I screwed up this slide. I was supposed to say additional enumeration support. Yeah. So, I want to be able to attack these things using a card, right? So, that's a big thing would be card to terminal fuzzing would be very interesting. Like I said, vulnerability checks. But it would be very cool to, for instance, pop a card into an ATM and have a jackpot because it exploits some sort of parsing error in the parser that takes in the response from the card. So, with that, I've got to wrap it up. I want to thank Ludovic Rousseau for all of his work on smart cards in the past. I want to thank Foundation for giving me a smattering of smart cards to play with. Jean Daniel Assault wrote the Python library that my tool is based on. Christopher Beauchemin gave me... He was the guy I met yesterday who... Really nice dude. Chief has this great list of APDU commands from a bunch of different things. I don't know who the guy is, but he's a legend. And also shoutouts to Alaska and the Hack the Site crew and Xforce. And that's it. I think I'm... I'm flat out of time, so I will take questions elsewhere. Yeah, I'll take questions over there. There it is. Thank you. Thank you.