Hardware Hacking Village. Welcome to Boston's Hacking Underground. Quite literally we are in my basement. Socially distant greetings from down here. Hopefully I managed to secure the location as in there is not going to be any noise and we get a reasonable recording. And that's it. Let's get started. I'm going to take the mask off since you're sufficiently far away. And while I certainly wanted to wear a fork bomb on a mask for a long time, I cannot go for a full hour doing that. So we have 45 or odd slides and the demo. So let's get going. Now, as a way of introduction, I had the privilege of spending my entire career in free and open source software. I am the product management director for Red Hat Ceph. And I was previously Ubuntu server PM at Canonical. And if you go back a decade, I was the dreaded systems management tsar at SUSE. The talk has nothing to do with my job. Well, I guess it is storage after all. I'm a manager these days. So as a former embedded developer, this is my definition of fun. The obligatory disclaimer is that we will most likely break some hardware playing with this. And it will come out of your pocket. No liability if you follow our instructions and stub your toe or bring about the end of the world. Or break your device, which is far more likely. So you have been warned. Let's get going. We have a lot of slides in the demo. We need to hustle a bit. Here is the idea. A processor is found in an SD card. Hackaday featured somebody's blog. Pretty much went viral in a word of web process. Virally blooming once Linux was noticed on the device. And Hackaday made it famous. Lots of blogs. SD card sized. Almost a raspberry pi. Can we repurpose the device? The word of web process really got going once Linux was noticed on the device. And so I noticed all this was going on. And I wanted a project for Christmas. That was five years and a bit more ago. So you could say that it has taken me for quite a ride. Let me repeat that as there is always someone who has no idea what I'm talking about. Here is the concept. A Wi-Fi enabled SD card. Automatically downloads your pictures. Several models exist. We're after the embedded system in there. In the card. The CPU of the card itself. It's like the Intel Edison they originally promised us, but for real this time. Copious amounts of Google Translate were used in the making of this talk. Really international effort. I saw blogs in French, Japanese, German, Korean, and of course English. Some Russian too. And I believe some Spanish. So copious use of Google Translate and in singularity of course. We explored the limits of machine translation, but it usually comes across clear enough to work with. So we're looking at the Trescend Wi-Fi SD line here. It comes in size from 8 gigabytes to 32 gigabytes. I prefer them as they are more open, even without hacking, as there are no attempts at platform strategies made by adding any middling cloud services that we do not want by some clever MBA that had a platforms class. There is no stepping stone service that may make things easier to set up. And doesn't. And adds yet another place your pictures are potentially in. The software on the Trescend card is simple and not perfect, but that is an asset for us as we will see. So where do we get these cards? You can go to Amazon. You could also try eBay. And they're going to be between $40 and $60 depending on capacity, about the price of Raspberry Pi and up. There are others like the PQi AirCard that are functionally the same. The PQi AirCard is interesting because it is actually an adapter card. You can put any storage you want in microSD format in there, and the adapter actually has the embedded system. Toshiba makes another one, and there is also the Flu card. And you can carry binaries through them. As a matter of fact, when you log into the system, you may notice that there is a command buzz in there. But there is no piezoelectric transducer here, so what is that for? But looking at another one of the card designs, that has a piezo. So you can learn things on one card that applies to another. But we're getting a little bit sidetracked here, so let's go back to where we should be. When the postman arrives, here is what you get. Inside the package, let's unbox one here, a card and an adapter. The inevitable legal disclaimer. I don't think this conference has a legal track, otherwise I would blame the lawyers. And a microscopic bit of a manual, which is actually not bad. The adapter is there because you can write to the SD card directly by mounting it on your Mac, for example, or over the radio. And when you have file systems mounted two places, and you are writing from two places, bad things happen. The adapter signals to the card to disable the radio, and prevents simultaneous writes from the air and local mount. Of course, that is exactly what we want to do. But we think before we do. We only want to use the radio, so we'll assemble it so it is actually not turned off. So just what is in there? This is an SDHC class 10 card. 16 gigabytes in the case of the ones I used. Half and double the size exists. This is a full-size SD card. Pictured is model TS16GWSDHC10. You will have the slides at the end, so if you want to search for the cards, you'll have all the models. There is no need to take notes or any of that. So physically breaking the device voids the warranty. I bet you did not see that one coming. Exacto-knifing our way to success, we slice the card in two and find four large chips. Interesting. The parts on the left are the case. Nothing strange there. It may help guide your dissection if you need to open one, but that's about it. Incidentally, do you see the yellow tab in the center? That is the write-protect switch cards have. Interesting technical detail. There is nothing on the device reading the state of that toggle. The reason for this is that SD cards work like floppy drives. And in floppy drives, if you still remember those devices, write-protect is implemented by the drive. If the drive sends a write, the card will take it. If the card doesn't know and doesn't have to, the drive will not send a write if the toggle is in the protect position. So let's do a bit of overview of the components from the top left. We have a trace antenna, definitely not a 3 dB antenna and not 100 milliwatts of broadcasting power as the whole card consumes less than that. So Wi-Fi range will not be as per the Wi-Fi specs maximum. But that's okay because we're still beating the pants off Bluetooth. There is no antenna connector. You could try your hand at adding one if you're a master at soldering. But assuming you don't, you're not going to get the full Wi-Fi range. And I'm okay with that. Then we have the Wi-Fi radio chip. The SoC with the ARM CPU we are after is underneath it. 16 gigs of flash in the big chip. And the flash controller is the last thing on the right. And up top we see the notch where the read-write tab rests that I was mentioning. And there is no actual board sensing of any kind as I said. The card is just making room for the tab to fit in that space. Flip side. Besides the standard SD leads, some of the smaller pads are TX and RX for a 3.3 volt 38400 baud serial. Annoyingly, really annoyingly, they are not labeled. They labeled resistors we don't really give a hoot about instead for who knows what reason. On the PQI air card, the TX and RX serial pads are labeled. So bonus points to those guys for that. If you do wired serial, you get access to a well-configured U-boot console. U-boot is the bootloader of choice for embedded Linux devices for those of you coming from Windows. A very handy tool to have. Better than the kernel that is in here as it has been stripped to the bone. Incidentally, I have been collecting all these details for a survey article. If you hack the card and blog the details, let me know. Send me the link. And you prefer going... if you prefer going the lazy way, you will get a how-to from me soon. Hopefully. I've been saying this for a while, but it's almost done. What's in there are these four chips. CPU, Wi-Fi module, flash controller, and storage. The SoC's 32 megabytes of RAM is the weakest spot of the board but very suitable for embedded use. Fear not those of you who are used to gigabytes of RAM. Besides, you have lots of storage. You could expand this with swap. If the kernel was built with support for swap. In the SoC, 8 megabytes of NOR flash are used for system including a stripped down kernel and compressed initramfs. Interesting compromises were made there. And of course, massive amounts of storage. So you could boot with a small system loop mount a larger image and shroot into it. If you had loop mount in this kernel, I start seeing a pattern here. But not all is lost. We can add it. Dimitri Greenberg has documented how to rebuild the kernel. So we have the instructions and the steps on how to do this already worked out. Let's look at the CPU. It's a 200 megahertz CPU. Some report 400 megahertz and they are wrong. They are confused by the 426 bogomips it sports. It's an ARM 926 EJS core. An ARM 9 processor. This is not a Cortex A9, but an older ARM 9. A low cost CPU. ARM 5 TEJ architecture with more than 5 billion with the B manufactured to date. Interesting extensions for Java, but the Giselle runtime requires talking to ARM as it was not shipped with the system. And anyway, who wants to do Java these days? So interesting core. The extensions. E stands for DSP, Digital Signal Processing Enhancements, because this processor used to be used for making feature phones. J for Java extensions or the Giselle JVM. Java extensions make byte codes directly usable by the CPU, which is really cool. The CPU instruction BJX branch to Java instruction, which switches the silicon to Giselle state. The JVM still handles errors. The OS handles the traps. But between 134 and 149 byte codes of the 203 in the JVM spec are handled in silicon. I don't know why the variation there. Why not a fixed number? But a large chunk of the byte code is running in hardware. Now, the original Raspberry Pi is a Broadcom BCM2835 processor. An ARM11 76JZF-S. This is an ARM6K architecture. It's closer to this processor than it is to a Cortex ARM. So the idea is that instead of the chip in the Pi, you would use the chip in the card. With different trade-offs. You get built-in radio, lose all the interfaces. The price stays just about the same. The radio is a Fortune chip. AFN31GL Wi-Fi controller. It comes with an Atheros AR6003 Wi-Fi core, which was marketed as the smallest Wi-Fi silicon design you could buy at the time. I don't know if they still have the record, but it was a pretty impressive claim five years ago. The bit we care about is that it does Wi-Fi B, G, and N with really low power draw. Do not plan to saturate the Wi-Fi Ethernet link with this device. You won't go much beyond one megabyte per second. Incidentally, if you feel like going turtles all the way down, there is a CPU to control the baseband radio. An Extensa MIPS core backed by 256 kilobytes of RAM and 256 kilobytes of ROM. I didn't go in there. Maybe it could be the next project for one of you. Also, this chip does not do Bluetooth, by the way. Not that we care. Then we have 16 gigs of NAND flash. You will not be wanting for storage. That's for sure. That is definitely not the problem the system has. The flash controller is a Silicon Motion 26... I can just read the slide. 2683EN. Thank you, picture. Nothing of interest here except there was a bit of annoyance in the community at the lack of redistributed sources for some system components. Transcend resolved this. It's no longer an issue. But one of the modules is proprietary. The one that supports the flash controller. If you're familiar with IP restrictions for source code of video drivers, that is probably a similar reason. There is some secret sauce that the vendors of flash want to keep to themselves and not share with one another. We don't know what it is. But it's not really a concern for us unless you are an open source legal purist and you want everything in the open out of principle. The sources... I mean the sources for some of the modules are available. The binaries for all three modules are available. So if we recompile the kernel we can just drop the modules back in and go on from there. It's not like we're going to modify our interface to the flash to the flash chip anyway. We're not interested in that. Now, this card clocks between 0.9 and 1.1 watts while idle in my office. It peaks at 1.5 with wireless clients connected. This is a 110 volt power supply of course. An Apple switched power supply. Efficient but still power conversion is a factor. Presumably higher if you push the CPU to 100% while writing to flash. You could also try to push consumption by simultaneously pegging the CPU and massively writing to flash. I got my numbers by exercising the radio only. I didn't do a full suite of benchmarks at different types of load. This is a relatively lightweight system so I didn't see the need to push the envelope that far. Interestingly, I checked to see if we would get better efficiency through eliminating the power conversion step. And we hardly see a difference. 220 milliamps is about 1.1 watts at 5 volts. Same as we measured at 120 for idle. It closely matches the other one. Apple really knows what they're doing. That iPhone switched power supply is really efficient. Good for them. Let's start looking at the software side. I'm going to walk you through what we do to make it work first and how we hack it second so it's not hanging in the void and confusing in as to how we got there. How does this all work? First you set up the app on your phone. Then it gives you access to basic setup and core functionality. Setting up network mode, names, password. Shoot and view here means putting the phone in a monitor mode of sorts where any picture shot by the camera is automatically downloaded and presented on the screen with no intervention. This will be important later. It also offers you to upgrade the firmware. Usually this is a concern as that precious security hole used for routing may disappear. But it's not so in this case. It does not matter what version of the firmware you have, you're going to get around it. So do not worry about it. The latest version is as open as the first. It is both good and bad, I guess. I say it is good. It lets us hack the card. Security issues we bring about are not in the hacking of the binary support package. But we'll get to that later. By default, the system wants to be its own access point. Great, very convenient for development. But not so for photo download. Think of it, you want to switch APs on your handheld device every time to sync pictures. The seamless internet AP client mode is a great strength of this card for ease of use compared to others that make it needlessly more complex by putting their service in the middle. You just choose the mode you want and you get it. So when it is up, it shows here from another machine in the same room. Your SD card has now become its own access point. Okay, what's next? Well, now we can connect to it just like you would anywhere else. And now we can ping it just like any other host. Now let's look at how it works before we get into it. Think about it. The app needs to find where the heck the card is. It is out there on the AP, but at what IP address? The card broadcasts on UDP 55777. I'm here, I'm here, I'm here. Other cards are even more aggressive. They ARP the entire slash 24 subnet, found out where every node is, then send HTTP requests to everyone until it finds the card. Then maybe it stops. Most of the time it does anyway. Don't worry, we can fix this. It's just funny to me. The tools are only needed for initial IP discovery and password setup. If you do not want to use them, the card comes with a default user admin with a password of 1, 2, 3, 4, 5, 6, 7, 8. But that's not the part that will make you laugh. We port scan the card to see what's going on here. Here we see Telnet because I already cracked this one. The HTTP server, the pictures are published there. The app just HTTP gets them. Services are offered as CGI scripts out of the web server. That's how the app commands the card to do things. The additional port 5566 broadcasts new entries in shoot and view mode. If you're connected there, you get a new URL message for every picture. That's how shoot and view works. You get one line with URL of new pictures when they're generated. Very simple architecture. Not bad. A few quirks. It downloads pictures twice. A bit suboptimal that way, but in this way it doesn't have to spend CPU power to generate thumbnails on board. Trades a little of bandwidth for not having to spend CPU and power. It also assumes that you're not downloading multiple pictures at once, which you're not. So simplicity prevails. I'm a fan of that type of design. We can browse the card's HTTP server directly. It's a boa web server. It exposes directory listings. In theory, it should show you only the directory listings of the data. And simple CGI bin scripts to set configuration. These are in Perl. App simply downloads the files via HTTP and calls CGI scripts to configure the system. And these scripts are way in. That's how the card was broken into. So this story starts with Pablo, who thinks there must be a CPU in these Wi-Fi enabled cards and turns out that he is right. Pablo went out and started poking at the software, looking for security holes. Find several the size of a small barn. Found dot dot slash dot dot slash backpats breaking out of the allowed inspection area. He extracts the source files for the CGI bin, exploits a Perl script, and in he goes. And I went that way myself the first time. But there is a better way. A file called autorun.sh. I think you know where this is going. Write a file to the SD card named autorun.sh. The system will read it and execute it. With root privilege. At boot. So all I have to do is just go, telnet please, and telnet arrives. So much nicer. Now, the security freaks among you will be horrified. But in terms of actually working with the card, this is fabulous. It makes it so nice. There is another aspect to this that is humorously named. I know what you're thinking. But that's not it. It stands for firmware update. It's a clever mechanism. You supply autorun.sh and three files. The kernel, the program bin. The system starts program bin. Turns out this is a copy of the cards you boot with the default script payload. The script loads the new system onto the old and then reboots. It's a nice way to prevent breaking. It also resets all configuration to the defaults, which may be handy if you screwed up. It is a really nice way to revert breaking and also gives you a way back to the defaults. But obviously you can only undo software breaking. You can still break the hardware. It's time to try and do this live. I usually unbox one of these. But in a virtual setting it doesn't really make it very useful. And you have seen the pictures, so you've seen most of what there is to see in an unboxing. I had to find... so let's set it up. I had to find an SD adapter that does not switch off the radio. So I went to my local computer megastore and bought every single adapter in existence, tested them all, returned 9 out of 10. And now we have the right thing. And this thing boots really fast. So much so that if I connected over the serial, it would be up before I can connect to it. You would not see boot messages. It will just be there already. So... and we got the advertisement. And we are connected. We got a connection. Now I was connected to that card recently, so let's just do it this way. And see? It got there way before me. What are we going to see here? Let's start from version text. So the KeyASIC Wi-Fi SD is the ODM design that all these vendors purchase to make their own products. And you can see that it confirms the 802.11n Wi-Fi. The Linux kernel is 263228, one of our most popular Linux kernels ever. This one was in RHEL 6. It was in SUSE Linux Enterprise 11 SP1 in a breaking of continuity from 11 kernel rebase. And I believe it was in Ubuntu Server 10.04, although that one wasn't mine, so don't quote me on that, but I'm pretty sure. This is the kind of kernel that you would want to run when you have only 32 megs of RAM, so it's a very, very good choice. It will not be expecting gigs of RAM either in this form or in userland. What else? Well, let's see what's around here. We want to see something else, actually. This is the actual VFAT system of the SD card. And you can see that I plugged it into a Nikon digital camera that left its own fingerprint there and a few files that I've been poking around with. BusyBox is notable here. We could run that BusyBox and have a much more futureful shell environment, but I want to show you here how the card is rather than how we are going to make it. The making part we can defer to a writeup. But yeah, very easy to replace the shell by just downloading a BusyBox and executing it. Incidentally, once you have a new BusyBox, you can run the NTP module and not be in 2012 anymore, which is great because then you can do proper secure connectivity, not plain text telnet. And now that your certificates are not coming from the future, crypto will actually work. What do we have on the storage side? So you see the JFFS2 file system that is the 8 megabyte partition that the system boots from. That is the reason why things have been stripped down so much. It is tiny. Now I'm not an embedded developer anymore. In my time, JFFS2 was the most popular file system for embedded Linux devices. This device is about 7 years old in design, so I don't know if that has changed. But it's nice to see familiar things. Let's see what's in in mtd. Oh yeah, you can see the labels. So mtd0 then spi-flash-nor, that's the 8 megabytes. Okay, then we have Perl. 5.14, not bad. Not an ancient single digit version. So that makes this potentially a system that you can develop on out of the box. Let's see what is running on it. We have the Telnet that we started. And we have two of the UDP-SVD processes. These are the ones that do the the broadcasting process that I described earlier. We have the Boa web server that's providing HTTP support. And we have a dynamic DNS advertisement. We have a DHCP server because in access point mode we have to serve out DHCP addresses to clients. The bodyguard process is the one that disables the radio when you plug the card into an SD card slot so that there is no double write. And that's about it. Let's see what do we have here. We already discussed the kernel version. We can see that it was compiled with sorcery on an Ubuntu machine. It's funny what kind of details you leak out. What else? What else? What else? We're gonna skip the message. It's too messy. So we discussed pretty much the CPU extensively already. You see that I got the CPU series right. And yeah, the 421 Bogomips that I was mentioning before. Not 400 megahertz. Just delay cycle is 421. We can also look in here. This is the one that makes me cry. So here we could really use some loop mount and some swap. But we can put them back in. So no crying. One last thing. We can list the network interfaces of an SD card just because it seems so wrong that we can pass up the opportunity to do it. And we discover absolutely nothing, but it's kind of fun to say that you have done it. So why not? Now... Okay. Back to the slides. Now be careful. The system mounts the flash partition under mount SD. And accessing the file system from the card's own Linux, while an external host is doing the same, could easily corrupt the file system. Two live systems writing to the same host. No good. You can easily fix it by rebuilding the file system. But you need to be aware of the problem so that you don't do it in production. Development is just fun and games. But in production, that's not the way to go. So what software do we have to play with here? In version 1.7 firmware, we have a kernel 2.6.32. The modules, the kernel modules are for the SoC, the Atheros 6003 radio, and the SDHC interface, which, as we discussed, is proprietary. Your services that you can have out of the box are basically a very stripped-down busybox that has Telnet, FTP, and DHCP. Busybox is a little bit crippled, but once you replace it, you can set up SSH as soon as you can set up time properly. And this is very easy to do. It's just one execution away. So, easy fix. On the kernel side, the kernel is extremely thin due to the need to fit in the 8 megabyte NOR flash in the SoC. But we can load components from the larger storage once we have a system running. Ideally, loop mount a file in FAT32 to avoid corruption. Add swap to work around RAM. Truth to pivot into loop mount. We need a new kernel to do this, and Robert figured out how to unpack the install files. And then Dimitri rebuilt the kernel by looking at KSIMs. Since the .configure file is not exposed in PROC, some people could think it's secrecy, but I think it's, again, saving space. So, how this would work. Would create on the live partition as a single file a system image. Would loop mount this and truth into it. Now, somebody took this to the extreme. Why do people always do this? So, they downloaded an Ubuntu 9.x image. The last version of Ubuntu compatible with ARM5 architecture. Put the image in there on the SD card. Loop mounted. Truthed. Forwarded X. Started Firefox. And then complained that it was slow. Okay. Well, it's not that interesting to run Ubuntu from 10 years ago. But it's pretty cool that one can take it that far. It's nice to see that the bits actually work and can be stretched. But we don't need to do things that crazy. Where there is Perl, there is everything, I like to say. Maybe Perl is not your cup of tea, but it's better than not having it. This is ARM. You can cross compile. You can build on the system. You can use IPackage. You can bring your own language. You can steal packages from another device of the same architecture since there are five billion of them. But if you want to be lazy, Perl is a perfectly viable option. And this is also a reasonably recent Perl. It's not Perl of the ancients like a Perl 5.6. It's 5.14. Big question for embedded devices is how we find them. Where is my device? And we need to make it safe for the internets. You cannot use this device if you cannot tell what IP it's at. So there are three approaches that are common to work this problem. One is a known configuration. Always be at the same address. This is what I just did. When the card is in AP mode, it is always at the same address. 11.254. I know where it is. I do not need to find it. Then there is what the card does natively. Broadcast. It advertises where it is. Besides the horror I described earlier, there are proper advertisement protocols like MDNS. Multicast DNS is a perfectly fine way to discover things on the local network. The third one is to announce, which is the device itself, once it has a valid network configuration, sends out an announcement. My favorite is to send out an XMPP announcement, meaning a Jabber protocol announcement. But you can use any protocol you want. And you know this is a unicast announcement, not a broadcast one like the horror I was describing earlier. It is going to a single endpoint and it's a fair game. No messing up of the network. I'm not going to go through all of these. There is an article I wrote for Linux Journal in 2009, I believe. Search for my name and Linux Journal. And there are scripts. They are implementing all of these for this architecture, in fact. You can go and just grab the scripts. They are in the article. You can also do this right. If you're a standards person, like some people rightly are, and in this case doing it right means implementing DNS update as specified in RFC 2136, which I suffered through implementing a few years ago, actually. Contact me by a fixed DNS name. I will update that DNS record when I boot so that it's always correct for my current device location. This is also implemented in my Linux Journal article. You can do it in 15 lines of Perl or less. So Perl may be hard to read sometimes, but it's very, very expressive and it's very nice for this purpose because there are modules to do anything. So let's go back to the security aspect. We were joking about the fact that it was easy to break in, but realistically we have physical access. We have the card and we can do things to it. We can also do it over Wi-Fi. Fine, that is less kosher, but that hardly matters. What matters is that this brings the lost USB key attack to a new level. In a military base, people are trained to shoot on sight when they see a lost USB key. But in an industrial setting, people are more lax. So picture this out of a Tom Clancy book. You need to break into somebody's network, you lose a USB key in their parking lot, and some good Samaritan-fool will take it inside the office and plug it into the wrong machine. I don't think I need to tell this audience this. So what's new here is the Wi-Fi aspect, of course. Although there are a few devices that do this, like HAC-5 has some devices that do exactly this. But in this case, it's in SD card format with a radio in it, which is interesting. Countermeasures are no different from the rogue access point ones. From radio jamming or your network actively nacking connection requests very cleverly for unknown access points in a broadcast range. Or if you have a security policy against lost USB keys by locking down or pouring glue into USB and other ports, you can pour glue into SD ports just fine and prevent people from sticking things into ports they are not supposed to use. Neither approach is new. Sure, the card is not super secured, but remember your security posture needs to be commensurate to your threat assessment. You are not a nuclear reactor. If you were, you need to account for this. But if the question is the security of your Instagram pictures, do people want them that badly? So your mileage may vary. What is on the opportunity side is that this is a low power system with vast amounts of storage and wireless connectivity. And really low power, as in you could power it with a solar panel and put it up a tree. This is the ideal pirate box data exchange. A pirate box being the term of art for anonymous data exchange, where people drop and retrieve files over Wi-Fi anonymously. I don't think it's as popular as it used to be once as a concept. This is in practice a spy's dead drop, if you want to use the Intel community's comparison, if you want to continue that line of thought. Less ominously, you can make a solar-powered geocache. But seriously, you can now realistically put a server in your wallet or even make a server throwaway or a Beowulf cluster in a shoebox, although I would recommend you do not do that. You could put it in the SD slot of your car radio, if you have one of those old ones, and make it download music whenever you park at home. There is one limitation. SD cards are supposed to have SPI interfaces, and that would be awesome, because SPI means Arduino. But sadly, this is not viable with this card. That won't work. Somebody tried the integrated system. It was bigger than the card itself. I mean, the support for SPI to access Arduino was bigger than the card itself. Not practical. But this is nonetheless a very interesting platform to experiment with. Cross-compiling is an option, but you can take the lazy way out and prototype with Perl. I solved the discovery problem for you. You have all the scripts. And this is a very low cost. Same cost as the original Raspberry Pi. So you have to decide if you want to trade RAM for very low power and small format, or the other way around. And it's a fair question. It's a very niche hacking platform. Trascend has been very nice to the community. Sorry, it's a very nice hacking platform. Trascend has been very nice to the community. We broke this years ago and they haven't complained. They haven't sued anybody. They haven't shut us out or done anything untoward. We get hardware to play with. They sell more hardware. It's great for everyone. The mechanism we used is part of the SDK, but the SDK is not public. So we had to discover it the hard way. We need a better distro image than the crap you have seen. I've worked on too many Linux distributions to stand for that. But that is relatively easy to do and there are some tools out there that are workable already. I think we can do better, but it's adequate to at least experiment. So if you come up with new ideas on how to use it, please send them to me. Here is my contact info. You can find me on Twitter or send me email. Or you can find me in the Discord channel and ask me questions there. Remember that speakers are Pavlovian devices, so if you like the talk, please let us know. Rate the talk, send us comments, submit feedback, all of those things as you see fit. If you do something with it, let us know what you did so we can spread the news. Slides will be available and I'm available for questions if you have any. Thank you and stay safe. Happy hacking!