[00:11.570 --> 00:17.470] Okay, so today we've got Christopher Wade presenting on [00:18.350 --> 00:24.050] BeyondRoot custom firmware for embedded mobile chipsets. So thank you for joining us, Christopher, [00:24.050 --> 00:28.770] and I'll let you do any opening remarks, and then we'll go right into the questions. [00:32.080 --> 00:36.400] Excellent. Hello, everyone. Thank you for coming to my talk. [00:38.300 --> 00:40.540] Yeah, that's pretty much all I can say. Thanks very much. It's [00:41.060 --> 00:41.500] definitely... [00:43.400 --> 00:48.860] Could you tell us a little bit about yourself and just like a quick intro summary for your talk? [00:50.360 --> 00:56.000] Yep, so quick introduction. This talk is mainly about custom firmware for embedded mobile chipsets. [00:56.060 --> 01:00.680] This is essentially me hacking chips inside my phone, which aren't the core ARM chip used to [01:00.680 --> 01:04.140] run the thing, in order to make it do different things in the hardware. In particular for this [01:04.140 --> 01:09.060] talk, it's going to be NFC chips. So I reverse-engineer the firmware of an NFC chip, [01:09.060 --> 01:12.060] break the signature checking, and then implement my own firmware onto it. [01:13.920 --> 01:18.220] Excellent. Great. So we have one question already queued up. [01:18.540 --> 01:22.080] So how did Samsung react to the disclosure of vulnerabilities? [01:23.120 --> 01:27.800] Yeah, so Samsung reacted very positively. So I submitted it to their mobile security team [01:27.800 --> 01:32.600] initially, and they accepted it, even though it was technically part of their Samsung [01:32.600 --> 01:38.120] team. So I sent them the disclosure, and they delayed with their interdepartmental [01:38.840 --> 01:43.500] systems or whichever. And initially, because I submitted the Samsung S6 vulnerability, [01:43.500 --> 01:46.580] they said that this wasn't really something they were going to remediate, just because it was out [01:46.580 --> 01:52.440] of scope. The Samsung S6 is no longer supported. But when I submitted the Samsung S9, they happily [01:52.440 --> 01:55.560] took it and started the remediation process, which was pretty good. [01:56.600 --> 02:01.620] And chips that have been manufactured, I believe you said, after April aren't vulnerable to this? [02:01.620 --> 02:05.940] Yes. So what they have done is essentially, while they can't really patch the bootloaders [02:05.940 --> 02:10.100] of existing chips once they've already been manufactured, as outlined in the talk, [02:10.100 --> 02:15.040] what I have done is discussed with them about how they're going to remediate this. And what [02:15.040 --> 02:19.340] they said was they're going to remediate all of the chipsets of the current versions [02:19.340 --> 02:23.760] in the manufacturing plant. So all of the bootloaders can be patched as chips go out [02:23.760 --> 02:29.420] from now onwards. However, all historical chips will still be affected. So that's why I decided [02:29.420 --> 02:33.420] to make a custom firmware for them. They'll still have the vulnerable bootloader. [02:33.420 --> 02:36.540] Yes, exactly. Which is very useful. [02:36.900 --> 02:41.980] So near the end of the talk, there was a problem with a parity bit. Did you ever get that worked [02:41.980 --> 02:44.700] out? Yes, so the parity bit was an interesting [02:44.700 --> 02:50.280] one. What they tended to do in the initial firmware or the firmware reverse engineering [02:50.280 --> 02:55.860] is load all their 8-bit buffers as they should into the 8-bit buffer in the hardware registers. [02:55.860 --> 03:00.220] This is done because that way the hardware itself can pick up the slack with the set [03:00.220 --> 03:04.220] and unset bits, which is done to sort of calculate parity between each set of bytes [03:04.220 --> 03:09.480] that are sent. What I did was find a very specific hardware address and a very specific [03:09.480 --> 03:13.580] bit in that hardware address set, which let me essentially control that parity bit. What [03:13.580 --> 03:18.100] this meant was I set up 9-bit values, so that includes the 8 bits of the byte followed by [03:18.100 --> 03:22.120] the 1-bit parity bit, which need to be encrypted, and that's the start of the process. [03:22.120 --> 03:27.220] I had to sort of bit shift everything around by one on each part, because the buffer was [03:27.220 --> 03:31.300] 8 bits, but I had 9 bits of base to shove, so essentially I just had to bit shift that [03:31.300 --> 03:34.460] around, which was a bit strange, but it did work. [03:35.100 --> 03:43.300] Did you get NFC tag cloning working? Yes, so what I ended up doing in the end [03:43.300 --> 03:48.780] was literally being able to read an NFC tag using the standard reader application that [03:48.780 --> 03:54.080] existed, and use my tool to upload binary data through the I2C interface that I had, [03:54.080 --> 03:59.880] so I could set each block of the data of the NFC tag as I wanted it, including the UID, [03:59.880 --> 04:04.000] the write and read bits, etc, all parts that I could upload and download as needed, and [04:04.000 --> 04:09.160] I also hooked into the I2C interface, so that every time some reader wrote to the tag as [04:09.160 --> 04:13.860] well and authenticated it properly, it would then also write that via I2C, so I could modify [04:13.860 --> 04:19.440] the binary file I had, this would mean things like access control systems and things, I [04:19.440 --> 04:23.760] would be able to keep a check of what was going on, so some access control systems had [04:23.760 --> 04:27.480] logs for how many things had been read, and some other imperative information to make [04:27.480 --> 04:34.260] sure that no tags had been cloned or reused, and I basically did that so that I could clone [04:34.260 --> 04:38.040] the tags while also allowing the data to be modified persistently, even if I stopped running [04:38.040 --> 04:41.360] the resource, and this was quite slow in the end. [04:41.920 --> 04:46.080] So do you have any questions? [04:46.100 --> 04:57.540] Yeah, so not on the track yet, but I did notice that your talk was mostly a tutorial on reverse [04:57.540 --> 05:02.060] engineering, and I think it seemed like you were starting out because you were curious [05:02.060 --> 05:11.000] about the NFC firmware and wanted to take a whack at customising it, is that, am I [05:11.000 --> 05:12.280] catching your motive correctly? [05:12.900 --> 05:17.900] Yeah, so that is essentially how I started, what really started this off was I had an [05:17.900 --> 05:21.920] old Samsung S6 that we started with at the start of the talk, which I was essentially [05:21.920 --> 05:26.420] using to just mess around with different custom ROMs on, and one of the things I did was port [05:26.420 --> 05:30.480] Debian to this, so I scraped up all of the Android operating system and shoved the Debian [05:30.480 --> 05:33.860] root file system into place, so instead of having it as a shroof as I outlined in the [05:33.860 --> 05:37.640] talk, it was more of a full operating system on the device. [05:37.640 --> 05:40.800] Now, this afforded quite a lot of functionality, but also meant that things like the screen [05:40.800 --> 05:41.960] didn't work so well. [05:42.220 --> 05:45.380] I quite enjoyed this because I was going to add some sort of hacking tools, modify the [05:45.380 --> 05:49.680] USB interface and things, so that I could use GadgetFS, et cetera, but I thought it [05:49.680 --> 05:52.500] would be interesting to see where I could push things like the NFC side. [05:52.500 --> 05:57.680] So I redeployed LineageOS to the Samsung S6 phone, which is a very standard custom ROM, [05:58.200 --> 06:01.260] and then started looking at the NFC chip, and that's sort of where the project sprung [06:01.260 --> 06:01.940] off from there. [06:01.940 --> 06:05.540] So it started off as more of a standard custom ROM project, then it started off as a standard [06:05.540 --> 06:09.100] reverse engineering project, but because I like reverse engineering, it sort of went [06:09.100 --> 06:09.760] on from there. [06:09.760 --> 06:11.480] It just sort of slid into it. [06:11.480 --> 06:12.600] Yeah, that happens. [06:14.820 --> 06:17.120] So have you looked at any other chips inside of phones? [06:17.120 --> 06:22.500] This seems like a really deep and hyper-specific long chain that you went through to patch [06:22.500 --> 06:23.500] in this functionality. [06:24.040 --> 06:25.580] Um, yes. [06:25.900 --> 06:30.300] Unfortunately, due to responsible disclosure, I can't discuss those at the moment. [06:30.300 --> 06:31.020] Fair enough. [06:31.020 --> 06:32.680] I'm very sorry about that. [06:32.680 --> 06:36.800] So maybe I'll sort of ask around this. [06:36.800 --> 06:42.440] Was this the first one, and you've just been able to successfully, responsibly disclose [06:42.440 --> 06:43.280] this one? [06:43.360 --> 06:48.700] Or what has your experience in the past led you, that brought you to this kind of point? [06:49.780 --> 06:51.560] Yeah, so this is definitely the first one. [06:52.420 --> 06:56.320] Unlike most of us, we have a habit of routing our last phone that we're using, not our current [06:56.320 --> 06:59.340] phone, because walking around with a routed phone is not the best idea. [06:59.640 --> 07:04.220] So I'd had a lot of older phones, and then I'd got a Samsung S6 for a few years, and [07:04.220 --> 07:06.880] then replaced it with a new phone, and just had it lying around. [07:06.880 --> 07:09.540] So the first thing I did was route it, and then start looking at seeing what I've been [07:09.540 --> 07:10.080] doing. [07:10.120 --> 07:12.460] I also looked at a few older phones at the same time. [07:12.460 --> 07:17.600] So for instance, I had a very old Samsung Galaxy Mini, which has FM radio capabilities [07:17.600 --> 07:19.320] based on a Broadcom chipset. [07:19.440 --> 07:20.340] Now, that was very interesting. [07:20.860 --> 07:24.840] Because it didn't seem to have any code signing with some of the binary files on there. [07:25.780 --> 07:29.420] It looked like it wasn't just an FM radio receiver, but also a transceiver. [07:29.420 --> 07:32.900] So I wanted to see if I could push it into doing FM transceiving. [07:32.980 --> 07:37.420] Sadly, that didn't really go anywhere, because quite frankly, working on old Android versions [07:37.420 --> 07:39.280] like that is incredibly tedious. [07:39.300 --> 07:43.140] They don't always use device file appropriately, and they often route their circuitry around [07:43.140 --> 07:44.200] in ways that just... [07:44.200 --> 07:48.160] It doesn't work very well by comparison to more modern phones, where everything's laid [07:48.160 --> 07:51.240] out, everything's documented, everything's open source in really nice ways. [07:51.560 --> 07:52.560] That's super unfortunate. [07:52.560 --> 07:58.370] I do remember some really old phone hacks that they were... [07:59.520 --> 08:03.840] I think they were actually MP3 player hacks that you could turn them into FM transmitters. [08:05.320 --> 08:07.520] Yeah, that would be cool to get your phone to do it too. [08:09.260 --> 08:12.360] Sadly, I'm stuck with a Raspberry Pi with a wire sticking out of one of the pins at [08:12.360 --> 08:14.560] the moment, which is good enough for now. [08:15.240 --> 08:16.260] Fair enough. [08:23.180 --> 08:27.860] Is there any other active projects that you're working on that you can talk about? [08:28.900 --> 08:31.560] Yeah, so I'm still looking at different phone chipsets. [08:31.560 --> 08:33.900] I've been looking around to see what other NFC chips that are used. [08:33.900 --> 08:37.260] There's only a handful of manufacturers, and that's something I'm looking into. [08:37.260 --> 08:41.860] But the big problem there is obviously price point, because phones are expensive things, [08:41.860 --> 08:43.840] and it's not something you want to buy randomly. [08:43.880 --> 08:47.040] The key thing I've been looking at is downloading custom ROMs for random phones that I thought [08:47.040 --> 08:50.600] would be interesting, not just for NFC chips, but other firmware binaries. [08:50.600 --> 08:55.020] Because if you download the ROMs and unpack them, then you can find quite a lot of information [08:55.020 --> 08:58.040] about the hardware that you wouldn't be able to get just from a teardown, for instance. [08:58.060 --> 09:01.800] For instance, if you go in the vendor partition, there's all sorts of firmware blobs for things [09:01.800 --> 09:03.600] like Wi-Fi chipsets, etc. [09:03.640 --> 09:07.740] And that's where it led me to things like... so I've got a Xiaomi Mi Note 3, which is an [09:07.740 --> 09:08.520] old phone. [09:08.700 --> 09:13.040] And while this isn't necessarily a firmware hack, being able to echo a single number into [09:13.040 --> 09:17.580] the sys files and turn that into a monitor mode phone is very powerful. [09:17.780 --> 09:21.500] Like full-on passive monitor mode, no injection, but still full-on monitor mode that works [09:21.500 --> 09:22.500] really effectively. [09:22.500 --> 09:25.000] Things like that is just something I keep looking through and looking through as much [09:25.000 --> 09:28.340] as I can, because it's quite fun to mess around with phones in that way. [09:28.340 --> 09:29.220] That's awesome. [09:29.260 --> 09:35.520] So part of your project, you used... I believe it was called the Unicorn Engine for hardware [09:35.520 --> 09:36.440] emulation. [09:36.600 --> 09:39.980] What level of emulation is actually happening there? [09:39.980 --> 09:41.640] Is it just like the CPU? [09:41.640 --> 09:44.200] How does it handle peripherals and stuff? [09:44.440 --> 09:45.000] Okay, yeah. [09:45.000 --> 09:47.420] So the Unicorn Engine is a really powerful tool. [09:47.420 --> 09:50.100] And I've seen a few talks on this by the people who've actually developed it. [09:50.100 --> 09:51.780] I'm sure it was at Defcon as well. [09:53.360 --> 09:56.640] As it's a library that's purely used for loading into other things. [09:56.640 --> 09:59.160] Now, I always write my stuff in C, so I load it into C. [09:59.940 --> 10:02.680] All it does is emulate the core architecture you want to go for. [10:02.680 --> 10:04.120] So in my case, it was ARM sum. [10:04.260 --> 10:06.560] Then it lets you map out memory mapping as you want. [10:06.560 --> 10:09.640] So in order to write and read memory to start things up. [10:09.640 --> 10:14.840] And then you can hook both operations and reads and writes of memory. [10:14.840 --> 10:17.420] So when you hook into operations, you can make them act in weird ways. [10:17.420 --> 10:21.540] For instance, one of the problems I had with my hardware was it would sometimes hit the [10:21.540 --> 10:25.840] wait for interrupt operation, which wasn't supported by Unicorn. [10:25.840 --> 10:29.060] And I could override that just to a standard NOP because I didn't need to think about it. [10:29.520 --> 10:33.220] But hooking into the memory reads and writes was what was really key for me. [10:33.260 --> 10:37.240] Because I can map out to say there's actually hardware addresses at certain points. [10:37.240 --> 10:41.800] I could then just put an if statement, a switch statement, just saying if it hits this address, [10:41.800 --> 10:42.640] mess with it in this way. [10:42.640 --> 10:46.640] For instance, in the I2C interface, it was when it hits the I2C status buffer, [10:46.640 --> 10:47.940] I want it to return random data. [10:47.940 --> 10:51.220] So it eventually hits the OK status or sometimes the busy status. [10:51.440 --> 10:56.180] And then when it hits the read and writes, I wanted it to read in data that I was writing [10:56.180 --> 10:59.880] to it as if it was the physical chip and then write data back when it was the physical chip, [10:59.880 --> 11:01.660] which is how I got that initial fuzzing working. [11:01.660 --> 11:03.420] So it's really powerful for that. [11:03.420 --> 11:06.540] But it has no integration for actual realistic hardware, [11:06.540 --> 11:08.700] just the processing as it's going along. [11:08.700 --> 11:11.520] So just the core operations, which is really cool. [11:11.520 --> 11:16.520] But you can write basically functions that are at those memory addresses [11:16.520 --> 11:18.560] just to pretend to be that hardware, right? [11:18.560 --> 11:22.220] Yeah, so you can literally set R0, R1, R2, you know, the command. [11:22.420 --> 11:25.140] And then the program counter will say go into this. [11:25.160 --> 11:26.920] And you can also set the address to tell it to finish. [11:26.920 --> 11:28.880] They can stick that at the end of the function. [11:29.020 --> 11:32.100] And that way you'll run through the function, call the functions it needs to, [11:32.100 --> 11:34.560] but also then stop when it's ready. [11:34.600 --> 11:36.620] And you'll then be able to read out memories you want. [11:36.740 --> 11:39.220] So for instance, what I wanted to do before I started up, [11:39.220 --> 11:41.620] part of the project I didn't really mention was I start off [11:41.620 --> 11:45.880] emulating the actual firmware binary that I had rather than the bootloader. [11:46.020 --> 11:49.200] And what I did was load that in and let it run so that I could set up [11:49.200 --> 11:50.580] all the hardware addresses I needed. [11:50.580 --> 11:53.960] So RAM, et cetera, to see how that was laid out, to see if I could see anything. [11:53.960 --> 11:56.360] Because you can let it start and then let it stop [11:56.360 --> 11:59.980] and then dump the memory out as you need to without really any problems. [11:59.980 --> 12:03.860] Oh, cool. That's actually really, really slick. [12:03.900 --> 12:05.640] It's really powerful, yeah. [12:05.640 --> 12:10.260] Yeah. So how do you go about making the jump from these [12:11.260 --> 12:15.300] accessing a particular hardware address to saying, [12:15.300 --> 12:19.440] okay, this is an I2C chip, external peripheral. [12:19.960 --> 12:22.200] How do you make that inference? [12:22.420 --> 12:23.860] Well, it was definitely inference. [12:23.860 --> 12:26.160] I was pretty much guessing when it came down to it. [12:26.640 --> 12:29.600] So what I was doing was when it hit that first... [12:29.600 --> 12:31.000] I'll go step-by-step with what I did, [12:31.000 --> 12:33.020] because it was pretty much as I outlined in the talk. [12:33.020 --> 12:35.340] It hit that first address and would just keep looping and reading [12:35.340 --> 12:38.100] and doing a few other operations before jumping back to the start [12:38.100 --> 12:39.540] where it read that address again. [12:39.680 --> 12:41.720] And I already knew that that was the correct hardware address [12:41.720 --> 12:45.700] because it was at 400000, which is where the hardware addresses are. [12:46.000 --> 12:48.660] So as it was reading, it was literally bit shifting. [12:48.660 --> 12:53.200] What some code can pass to often is shifting values down [12:53.200 --> 12:55.260] to hit a certain bit to check them. [12:55.460 --> 12:58.000] And I thought, okay, so it's probably checking for certain bits [12:58.000 --> 12:59.140] in some sort of order. [12:59.660 --> 13:01.220] And so I just randomized that. [13:01.540 --> 13:03.160] And then it started trying to read in bytes. [13:03.160 --> 13:04.760] I was loading them into a buffer in RAM. [13:04.760 --> 13:06.620] And I could see this in the emulation. [13:06.620 --> 13:09.740] And I thought, what happens if I start writing my code into it? [13:09.740 --> 13:12.000] So I started writing different operations in. [13:12.000 --> 13:13.120] And there was sort of a staggered approach [13:13.120 --> 13:15.920] because I didn't have interrupts, I think. [13:15.920 --> 13:17.560] But for some reason, it wouldn't response right away. [13:17.560 --> 13:19.820] So I gave it a whole list of commands I wanted to run. [13:19.820 --> 13:21.540] And then it had like three of them. [13:21.540 --> 13:23.260] And then it would start pumping out the responses. [13:23.480 --> 13:25.060] So eventually that worked really nicely. [13:25.060 --> 13:26.760] So it was quite cool in the end. [13:27.660 --> 13:29.560] That is really what it looks like. [13:29.860 --> 13:31.600] Yeah, but it's all assumption, essentially. [13:31.600 --> 13:32.280] It's all guessing. [13:32.280 --> 13:33.000] It's all guesswork. [13:33.000 --> 13:34.300] And eventually it gets there. [13:34.480 --> 13:37.280] And I imagine that interacting with those pieces of hardware [13:37.280 --> 13:41.180] might allow you to say, okay, this is clearly a memory buffer [13:41.180 --> 13:43.000] that's being shared with something else. [13:43.000 --> 13:45.860] That kind of thing, just experience, will just help you with that kind of thing. [13:45.980 --> 13:48.020] Yeah, and I sort of stepped through some of the parts of the code. [13:48.020 --> 13:50.280] So I stepped through because there was that infinite loop that started, [13:50.280 --> 13:51.860] which was constantly reading. [13:51.880 --> 13:53.540] And I jumped into there and a few functions in. [13:53.540 --> 13:56.660] And that's where I found the state machine command 0, 1, 2, and 6. [13:56.760 --> 14:02.580] Which were the first commands that the chip would see at the start of a firmware update. [14:02.580 --> 14:03.940] So 0 was a reset. [14:03.940 --> 14:05.780] 1 was get some version information. [14:05.780 --> 14:10.440] And 2 was start sending the SHA-1 hash and the signature. [14:10.460 --> 14:12.000] And then command 6 was the secret one, [14:12.000 --> 14:14.520] which dumped any memory I wanted, which was correct. [14:14.520 --> 14:17.900] But the fact that that existed was quite surprising. [14:20.760 --> 14:22.300] Yeah, but I mean, it worked out. [14:22.300 --> 14:23.920] It's like being able to find that. [14:23.960 --> 14:26.260] So if you didn't have that command, [14:26.260 --> 14:29.260] you briefly mentioned about doing that kind of reversing blind. [14:29.260 --> 14:31.380] You already had the previous version. [14:31.380 --> 14:36.040] You were able to use the knowledge you gained from that first stage to attack later on chip. [14:36.340 --> 14:40.300] If you wanted to go about doing something like this blind, [14:40.300 --> 14:40.700] could you? [14:40.700 --> 14:43.260] Would it just be just an enormous amount more effort? [14:43.260 --> 14:45.160] Or is it just not possible? [14:45.580 --> 14:48.380] It probably would have been an enormous amount more effort, yes. [14:48.380 --> 14:50.100] Because I had that bootloader to emulate, [14:50.100 --> 14:53.460] and I could make assumptions about the two size values that made it a lot simpler. [14:53.460 --> 14:57.160] It wasn't the full process, but it was helpful enough. [14:58.180 --> 15:00.220] The blind part was very simple in the end, [15:00.220 --> 15:04.020] because the bootloader had changed just enough that I could guess anyway. [15:04.020 --> 15:07.160] So I could make inferences about where I'd overwritten the stack [15:07.160 --> 15:08.380] and where I'd overwritten the memory, [15:08.380 --> 15:11.520] which would have different kinds of responses over the I2C bus. [15:11.520 --> 15:13.920] Because I could get the size of the stack, [15:13.920 --> 15:16.900] I could overwrite it all with whatever addresses I wanted, [15:16.900 --> 15:18.960] because eventually one of those would be the link register. [15:19.200 --> 15:22.060] And when it jumped in, I literally just would have jumped through them in the same way, [15:22.060 --> 15:22.740] essentially. [15:22.740 --> 15:26.560] But it would have been a lot more difficult to find the initial vulnerability, I think. [15:27.300 --> 15:28.020] Fair enough. [15:28.660 --> 15:34.300] So you could potentially use your custom firmware function [15:34.300 --> 15:37.900] to re-implement that kind of memory dumping, though, [15:37.900 --> 15:41.440] by jumping into that and then dumping everything back out [15:41.440 --> 15:42.920] to get the updated firmware version? [15:44.240 --> 15:46.140] Yes, so that's exactly what I did in the end. [15:46.140 --> 15:48.780] So that was my first port of call when I started making the custom firmware, [15:48.780 --> 15:52.100] was adding arbitrary reads to the core firmware. [15:52.100 --> 15:53.320] Instead of it being in a bootloader, [15:53.320 --> 15:55.620] I made my own custom firmware capable of doing that. [15:56.240 --> 16:00.720] It was a few steps, so I had to essentially find an I2C function [16:00.720 --> 16:03.200] I wanted to mess with that worked via NCI, [16:03.200 --> 16:06.900] and then modify that so I could send NCI responses with whatever I wanted [16:06.900 --> 16:08.300] and override those functions. [16:08.300 --> 16:10.400] So it was a good jumping off point, [16:10.400 --> 16:14.160] and then I could modify my exploit to not load data from random addresses [16:14.160 --> 16:16.660] to start off the exploit, which was a bit scary [16:16.660 --> 16:20.200] when I actually saw what was working in the exploit in the live version. [16:21.540 --> 16:23.440] So we got a question from the channel. [16:23.780 --> 16:27.360] When starting your research, weren't you afraid to find old vulnerabilities [16:27.360 --> 16:31.100] on your chip that were already patched since you started on an old phone? [16:31.360 --> 16:34.400] Yes, so I thought it would have been patched, to be honest. [16:34.800 --> 16:37.520] So I started with the Assumption S6, [16:37.520 --> 16:40.280] and I wasn't really doing it from a security perspective, [16:40.280 --> 16:42.700] which is more of a reverse engineering thing that's fun. [16:42.840 --> 16:44.940] But because they told me they weren't going to patch it [16:44.940 --> 16:46.440] because it was so old, which was valid, [16:46.440 --> 16:49.020] I thought, I don't think anyone's ever bothered [16:49.020 --> 16:52.440] looking at something so innocuous as an NFC chip on a phone. [16:52.620 --> 16:56.200] So I thought, if I bought a later phone, [16:56.200 --> 16:58.480] which I was in the market for at the time anyway, [16:58.480 --> 17:00.260] I'd be able to find something just the same, [17:00.260 --> 17:02.000] and I did, which was excellent. [17:02.000 --> 17:05.380] And it meant that, because there was firmware, [17:05.380 --> 17:07.700] there were different chip versions between the two as well, [17:07.700 --> 17:09.180] so this is just the latest version, [17:09.180 --> 17:10.480] it was likely that all the ones in between [17:10.480 --> 17:12.960] were also vulnerable to the same thing. [17:12.960 --> 17:16.100] It wasn't just a one-to-one comparison, which was quite cool. [17:16.100 --> 17:17.700] Do you know if Samsung took the approach [17:17.700 --> 17:21.700] that all those middle versions were likely vulnerable as well, [17:21.700 --> 17:24.880] and they're only going to be releasing the updated version at this point? [17:25.020 --> 17:26.100] I don't know a huge amount, [17:26.100 --> 17:27.900] but I do know which chips are in which phones, [17:27.900 --> 17:30.400] so I can assume the ones that are supported by them [17:30.400 --> 17:32.520] are going to be updated more than anything, [17:32.520 --> 17:34.720] because they do seem very good about updating these things. [17:34.740 --> 17:39.540] Cool. So we got sort of a comment from someone in the channel. [17:39.980 --> 17:43.080] I really want to understand firmware and boot much more in depth. [17:43.080 --> 17:46.140] Looking for the more established projects can be somewhat overwhelming. [17:46.140 --> 17:50.460] Should I just grab a Pine phone or Pine Time and tinker around old Thinkpads? [17:50.460 --> 17:53.480] What kind of more entry-level paths might you suggest to learn more? [17:53.520 --> 17:54.660] Okay, yeah, excellent. [17:54.660 --> 17:56.920] So it very much depends on which path you want to go through. [17:56.920 --> 18:00.380] If you want to learn into custom ROMs and things on phones [18:00.380 --> 18:02.780] and modifying phones in that manner, [18:02.780 --> 18:05.900] then yes, something more like a standard Android device, [18:05.900 --> 18:07.320] like a Pixel or something, [18:07.320 --> 18:10.200] which has the capabilities with custom ROMs and OEM unlocking, [18:10.200 --> 18:11.520] is the best port of call. [18:11.520 --> 18:14.100] You can mess with the operating system as you want, learn a lot. [18:14.100 --> 18:17.360] There's a lot of tutorials that people have for things like compiling, [18:17.360 --> 18:18.440] things like Lineage OS, [18:20.380 --> 18:22.320] which can be modified in certain ways. [18:22.320 --> 18:26.540] For instance, you can unpack the zip files of some of the custom ROMs [18:26.540 --> 18:28.880] and then just modify the boot script and things as you want, [18:28.880 --> 18:31.360] or add your own things into the system image. [18:31.360 --> 18:32.300] You can add these things. [18:32.300 --> 18:35.200] That's sort of... it's kind of a big question on that side. [18:35.200 --> 18:37.200] If you're looking at learning how to reverse engineer [18:37.200 --> 18:39.900] much smaller chips, things like the NFC chip, [18:39.900 --> 18:43.220] you should start looking at chipsets like the STM32. [18:43.680 --> 18:50.120] These are probably the most used Cortex-M and ARM-embedded chipsets around. [18:50.120 --> 18:53.160] There's huge numbers of very cheap development boards for them. [18:53.160 --> 18:55.280] And you can write code for them using free tools. [18:55.280 --> 18:57.740] There's also tools like the STM32 Cube, [18:57.740 --> 19:00.640] which allows you to set specific pins and configurations. [19:00.640 --> 19:02.620] You can create your own USB device, [19:02.620 --> 19:05.680] access the mouse, whatever, in minutes using some of these tools, [19:05.680 --> 19:07.160] and just deploy them to the phone. [19:07.160 --> 19:08.860] And that's where you would go if you wanted to start learning [19:08.860 --> 19:10.800] about how to develop firmware for these things. [19:10.800 --> 19:11.820] To reverse engineer them, [19:11.820 --> 19:13.120] all you need to do is take those binaries [19:13.120 --> 19:15.020] and look at how they work more than anything. [19:15.020 --> 19:17.040] Chuck them in EIDR or RADAR or, you know, [19:17.040 --> 19:20.160] Ghidra, whichever one you like, and start looking around them. [19:20.180 --> 19:22.600] There's a huge number of really good tutorials about how to do this, [19:22.600 --> 19:25.320] but mostly all I can say is just dive in and try things. [19:25.320 --> 19:26.700] And if you get frustrated too much, [19:26.700 --> 19:28.500] then you're probably going the right way with it. [19:33.720 --> 19:36.400] I mean, I don't want to tell you how hard it was [19:36.400 --> 19:38.380] to find all the addresses and things in the firmware [19:38.380 --> 19:40.380] that I reverse engineered for this project. [19:40.380 --> 19:43.120] It took days and days and days for some of them, [19:43.120 --> 19:43.900] especially when it came to things [19:43.900 --> 19:47.040] like a lot of the functionality was based on interrupts. [19:47.040 --> 19:48.680] And I didn't even know which interrupts were where [19:48.680 --> 19:50.340] because there's no documentation for this chip [19:50.340 --> 19:52.340] and everything is completely custom to Samsung. [19:52.440 --> 19:54.020] These are really difficult things to come up with, [19:54.020 --> 19:55.980] but you can start adding to your knowledge [19:55.980 --> 19:58.040] just by doing the most frustrating things you can. [19:58.040 --> 20:00.680] But if you're starting with embedded firmware in that style, [20:00.680 --> 20:02.360] start with an STM32 dev board. [20:02.360 --> 20:03.360] You can start with a Raspberry Pi [20:03.360 --> 20:04.700] and just start looking at bare metal stuff [20:04.700 --> 20:06.160] if you have one available. [20:06.400 --> 20:08.400] There's all sorts of ways to go into it, really. [20:08.960 --> 20:09.780] That's awesome. [20:09.780 --> 20:11.760] That's a great and very thorough answer. [20:11.760 --> 20:12.820] I appreciate that. [20:13.620 --> 20:15.860] Do you believe that Samsung will eventually start [20:15.860 --> 20:18.600] using signature verification for downloadable firmware? [20:19.460 --> 20:23.480] So the chip did use signature verification in this instance. [20:23.520 --> 20:25.040] What they should be adding to that [20:25.040 --> 20:27.740] rather than modifying the signature verification [20:27.740 --> 20:29.640] is encryption on top of that. [20:29.640 --> 20:32.180] So at the moment, you could take the firmware [20:32.180 --> 20:34.220] that they've deployed and analyze it in IDA with no problems [20:34.220 --> 20:36.420] because there's no encryption whatsoever. [20:36.420 --> 20:39.000] Now, different chips from different manufacturers, [20:39.000 --> 20:42.760] even NFC chip ones, are encrypted and signed. [20:42.760 --> 20:44.160] That means you can't reverse engineer them [20:44.160 --> 20:45.380] to find any exploits. [20:45.380 --> 20:47.660] You also can't deploy modifications to those firmware. [20:47.660 --> 20:48.900] And that's sort of the way they should be going [20:48.900 --> 20:50.360] more than anything. [20:50.900 --> 20:53.380] Do you think that that's actually a good way [20:53.380 --> 20:55.320] making it harder for reverse engineers [20:55.320 --> 20:58.060] to inspect the actual firmware? [20:58.360 --> 21:00.960] It's kind of a catch-22 on that point, isn't it? [21:00.960 --> 21:02.660] I see where you're coming from. [21:02.660 --> 21:04.980] The problem is, I think, [21:04.980 --> 21:06.500] especially with a threat model such as this [21:06.500 --> 21:09.340] where the only real reason [21:09.340 --> 21:10.440] someone would reverse engineer this [21:10.440 --> 21:12.180] is to make a cool NFC hacking tool [21:12.180 --> 21:14.420] rather than to damage other people, [21:14.420 --> 21:16.880] is that if you really wanted to stop people doing this, [21:16.880 --> 21:18.920] which I don't agree with on a moral level, [21:18.920 --> 21:20.680] but I would say encrypting it [21:20.680 --> 21:21.660] and preventing them from doing that [21:21.660 --> 21:22.560] is the best way to go. [21:22.560 --> 21:23.860] Because then what they'll have to go for [21:23.860 --> 21:27.320] is both guessing how the bootloader works [21:27.320 --> 21:29.340] and also guessing what things [21:29.340 --> 21:31.780] like secret vendor NCI functions are available, [21:31.780 --> 21:34.080] which aren't necessarily all vulnerable to things, [21:34.080 --> 21:36.900] but are available and people can brute force through them. [21:39.100 --> 21:41.300] How much time did you spend on this project? [21:42.060 --> 21:43.220] A lot. [21:44.240 --> 21:47.180] I feel like my boss has probably asked me that in the chat. [21:47.460 --> 21:50.080] So the project started off [21:50.640 --> 21:52.660] at the end of the last DEF CON, actually, [21:52.660 --> 21:55.120] which is when I was sitting in my hotel room [21:55.120 --> 21:56.680] looking at the original firmware. [21:56.740 --> 21:58.980] And then I just did it in little bits over time more than anything. [21:58.980 --> 22:00.640] It wasn't a solid amount of time. [22:00.640 --> 22:02.660] When it got to the point where I had a signature bypass [22:02.660 --> 22:03.520] on the Samsung S9 [22:03.520 --> 22:06.200] is when I really started focusing quite a lot of time away. [22:06.200 --> 22:08.120] So it took me about three weeks, [22:08.120 --> 22:09.540] not every day, but three weeks in total, [22:09.540 --> 22:10.840] to go through everything [22:10.840 --> 22:13.920] and start implementing every single part of that firmware. [22:13.920 --> 22:15.320] Because I was having to look through the entirety [22:15.320 --> 22:18.020] of the firmware image, [22:18.020 --> 22:20.000] which had no documentation whatsoever, [22:20.000 --> 22:22.360] nothing to work with, no strings at all, [22:22.360 --> 22:24.220] no function references that you'd get in that. [22:24.220 --> 22:25.540] It's literally just raw code. [22:25.540 --> 22:27.000] It's all guesswork. [22:27.180 --> 22:28.800] And that's sort of why it takes [22:28.800 --> 22:29.820] such a long-winded amount of time [22:29.820 --> 22:33.780] compared to some more desktop-level projects [22:33.780 --> 22:35.100] where you can reverse engineer, [22:35.100 --> 22:38.260] say, an application quite a lot more easily, I'd say. [22:41.120 --> 22:43.500] So other than the challenge of doing the reverse engineering [22:43.500 --> 22:44.660] and figuring things out, [22:44.660 --> 22:47.560] did you have a particular use case for the end product? [22:47.660 --> 22:51.520] Like a sneaky version of the Proxmark or something? [22:51.560 --> 22:53.920] A sneaky version of the Proxmark is exactly right. [22:53.920 --> 22:55.540] Yes, that's very true. [22:55.540 --> 22:57.840] I do have Proxmarks and I really like them. [22:57.840 --> 22:58.980] So I've got one right next to me, [22:58.980 --> 23:00.200] which I actually use for the reverse engineering [23:00.200 --> 23:02.660] of this project really heavily for the NFC side. [23:02.760 --> 23:07.280] Because it's so lax on things like the bit verification, [23:07.280 --> 23:08.560] the parity checking, [23:08.560 --> 23:09.880] it meant that I could build up the project [23:09.880 --> 23:10.840] really simply from that. [23:10.840 --> 23:12.500] Now, essentially, yes, [23:12.500 --> 23:14.140] I was trying to make a fakie Proxmark. [23:14.140 --> 23:17.300] And part of that was passive NFC sniffing. [23:17.300 --> 23:20.780] So one of the tools on a Proxmark is this thing [23:20.780 --> 23:25.500] where you can sniff high-frequency communication [23:25.500 --> 23:27.120] between the reader and a tag. [23:27.120 --> 23:29.700] This is used for breaking authentication and things. [23:29.700 --> 23:30.420] I wanted to add that in [23:30.420 --> 23:31.660] so you could go up someone with a phone [23:32.080 --> 23:33.140] and stick it over them [23:33.140 --> 23:34.880] as they're trying to open a door or something by accident [23:34.880 --> 23:36.900] and pick up the communication. [23:37.420 --> 23:39.580] Now, that feature is almost done, [23:39.580 --> 23:40.640] but it's quite complicated now [23:40.640 --> 23:43.340] because you have to switch between hardware registers. [23:43.340 --> 23:44.880] Now, there's one block of hardware registers [23:44.880 --> 23:45.860] that I mentioned in the talk, [23:45.860 --> 23:48.060] and that handles every single aspect of NFC. [23:48.060 --> 23:48.840] So that's the reader part [23:48.840 --> 23:51.420] and the acting like a tag part. [23:51.420 --> 23:53.080] So you have to switch between these constantly [23:53.080 --> 23:53.860] in order to get that data. [23:53.860 --> 23:55.220] And it sort of works, [23:55.220 --> 23:57.340] but until I've got that full functionality in place, [23:57.340 --> 23:59.260] it's really not replacement for the Proxmark. [24:00.000 --> 24:01.780] That was the goal, yes. [24:02.020 --> 24:04.600] Yes. That's really sneaky. [24:04.600 --> 24:05.700] I really like it. [24:08.960 --> 24:12.780] Why do you think so little has been done for... [24:12.780 --> 24:15.080] Why do you think so little has been reverse-engineered [24:15.080 --> 24:17.360] from a Qualcomm baseband? [24:17.360 --> 24:18.480] Is it more challenging? [24:19.420 --> 24:20.160] I'd say yes. [24:20.160 --> 24:22.160] I've looked at some aspects of Qualcomm as well, [24:22.160 --> 24:24.380] just from interest. [24:24.800 --> 24:27.280] I've looked at several different aspects of things, [24:27.280 --> 24:28.300] like how their bootloaders work, [24:28.300 --> 24:30.860] how they have the Qualcomm emergency download mode [24:30.860 --> 24:32.240] and all these sorts of features. [24:32.240 --> 24:34.640] They've also got the baseband, which is highly complex. [24:34.800 --> 24:36.680] The problem is you start looking into them [24:36.680 --> 24:39.100] and then you realize how much of a can of worms [24:39.100 --> 24:40.760] you've opened with reverse engineering. [24:40.760 --> 24:43.360] This project, by comparison to something like a Qualcomm chip, [24:43.900 --> 24:45.440] is very simplistic. [24:45.440 --> 24:48.900] It's one very small 12K firmware to look through. [24:48.900 --> 24:50.300] Whereas when you get to the Qualcomm baseband, [24:50.300 --> 24:52.040] which is going to be hugely complex, [24:52.040 --> 24:53.040] it's just a huge project. [24:53.040 --> 24:55.660] It's better suited to a multi-person team [24:55.660 --> 24:57.320] rather than just me on my own. [24:57.540 --> 25:00.960] Is it largely the size of the firmware on Qualcomm chips [25:00.960 --> 25:03.140] that is the limiting factor? [25:05.100 --> 25:08.460] Is the Snapdragon still a natural ARM core [25:08.460 --> 25:10.960] or is it something Qualcomm specific? [25:11.080 --> 25:13.300] It's an ARM64 core, I believe, at the moment. [25:15.660 --> 25:17.720] I know there's been quite a lot of research [25:17.720 --> 25:19.360] on Qualcomm in general on their chipsets [25:19.360 --> 25:21.340] because it is the focus of the phone. [25:21.340 --> 25:25.880] That's why I chose a chipset that was a side aspect of a phone [25:25.880 --> 25:27.980] because I thought no one would bother to look at them. [25:27.980 --> 25:29.420] And they haven't with this one, [25:29.420 --> 25:30.800] so I feel like the vulnerability I found [25:30.800 --> 25:32.220] would probably be found quite quickly. [25:32.440 --> 25:35.820] But yes, when it comes to the Qualcomm side of things, [25:35.820 --> 25:38.420] it's just such a hugely complex chipset. [25:38.420 --> 25:39.440] There's so much to look at [25:39.440 --> 25:41.960] and so many potentials for bugs in different places [25:41.960 --> 25:44.720] that, like any chipset of that complexity, [25:44.720 --> 25:46.580] it would take a team and quite a lot of time [25:46.580 --> 25:47.960] to find something, I think. [25:47.960 --> 25:49.620] Yeah, fair enough. [25:51.800 --> 25:55.680] It looks like we got some potential questions coming back in. [25:56.480 --> 26:01.220] Yeah, is there any part of the talk that you omitted [26:01.220 --> 26:03.720] because you just ran out of time? [26:04.820 --> 26:06.240] Yes, quite a lot. [26:06.240 --> 26:08.260] So I wanted to get into more details [26:08.260 --> 26:09.600] about the reverse engineering side, [26:09.600 --> 26:11.800] which was, considering it was only half the talk, [26:11.800 --> 26:14.160] was the most time-consuming part of the topic. [26:14.180 --> 26:16.620] But I found that it was quite dull to talk about [26:16.620 --> 26:18.500] because it's literally me going, [26:18.500 --> 26:19.860] oh, I thought this might be this. [26:19.860 --> 26:20.920] I thought this might be this. [26:20.920 --> 26:23.100] For instance, I mentioned interrupts earlier [26:23.100 --> 26:26.300] and how these work on Cortex-M chips. [26:26.300 --> 26:28.260] There's a big table at the start of the firmware, [26:28.260 --> 26:29.640] which includes the reset vector, [26:29.640 --> 26:31.100] which is where the chip starts from, [26:31.100 --> 26:32.140] the start of the stack. [26:32.140 --> 26:33.060] And then it has a bunch of interrupts [26:33.060 --> 26:34.380] for things like the hardware and stuff. [26:34.380 --> 26:35.960] Now, on top of this, it also has interrupts [26:35.960 --> 26:38.540] for more complex hardware, like the NFC. [26:38.660 --> 26:42.040] So one thing was all the NFC tag mode stuff [26:42.040 --> 26:43.760] ran off one single interrupt. [26:43.760 --> 26:45.520] So it hit that interrupt and would jump to some code. [26:45.520 --> 26:48.340] That meant the code wasn't directly referenced by anything [26:48.340 --> 26:50.060] and actually didn't disassemble [26:50.060 --> 26:51.900] when I first looked at the firmware. [26:52.160 --> 26:55.720] What this meant was what I started off doing [26:55.720 --> 26:57.460] was overriding that interrupt in the first place, [26:57.460 --> 26:58.680] but I had to know where it was. [26:58.740 --> 27:02.780] So I found the select function that I mentioned in the talk [27:02.780 --> 27:03.840] and then went back from there, [27:03.840 --> 27:05.440] found that it had no function reference, [27:05.440 --> 27:06.880] thought maybe it's an interrupt, [27:06.880 --> 27:08.340] and then searched that value, [27:08.340 --> 27:10.300] which was then found in a table, things like that. [27:10.300 --> 27:11.660] These are things that are very valuable [27:11.660 --> 27:13.500] from a reverse engineering perspective, [27:13.500 --> 27:16.020] but they're very boring to talk about in a talk, I think, [27:16.020 --> 27:16.640] which is probably bad [27:16.640 --> 27:18.740] because I just spoke about them for about three minutes. [27:18.760 --> 27:20.100] No, no, no, no, it's fine. [27:20.100 --> 27:21.640] We've got time and people are... [27:21.640 --> 27:22.660] Like, I'm interested. [27:22.660 --> 27:25.420] I didn't know that things pointed exclusively [27:25.420 --> 27:28.600] by the interrupt table wouldn't normally decompile. [27:29.460 --> 27:30.320] Not unless it... [27:30.320 --> 27:32.360] Well, Kahidra is quite good at this, I've found, [27:32.360 --> 27:34.100] because it understands Cortex-M, [27:34.100 --> 27:36.100] whereas Ida sort of is quite hands-off [27:36.100 --> 27:38.520] when it comes to things like Cortex-M chips. [27:38.520 --> 27:40.760] It allows you to work it out for yourself, essentially, [27:40.880 --> 27:41.700] a lot of the time. [27:41.700 --> 27:43.060] Fair enough. [27:43.400 --> 27:46.540] Which would you say are other interesting targets, [27:46.540 --> 27:49.220] like not-complex-and-wildly-used chips? [27:50.880 --> 27:52.340] What I would recommend is something [27:52.340 --> 27:53.700] that I work with quite heavily, [27:53.700 --> 27:57.100] which is embedded IoT chips, [27:57.100 --> 28:00.240] which are not custom chipsets in the first place. [28:00.240 --> 28:02.920] They're usually STM cores or EFM cores [28:02.920 --> 28:04.060] and these sort of things. [28:04.260 --> 28:05.440] Why these are interesting [28:05.440 --> 28:07.280] is they're a good jumping-off point to learn these things [28:07.280 --> 28:08.400] because you're not guessing, [28:08.400 --> 28:10.040] you've got documentation in place. [28:10.040 --> 28:12.500] But also people implement bootloaders and things, [28:12.500 --> 28:15.180] which you can then try and break. [28:15.180 --> 28:17.880] Now, I did a talk at 44Con a while ago, [28:17.880 --> 28:19.460] which is about breaking one of these bootloaders [28:19.460 --> 28:22.800] by breaking the encryption mechanisms on the firmware update [28:22.800 --> 28:25.040] by dumping RAM off an STM32 chip [28:25.040 --> 28:26.400] as it was doing the firmware update. [28:26.400 --> 28:28.640] Things like this are things you shouldn't start looking at [28:28.640 --> 28:31.220] because there's millions of these IoT devices out there [28:31.220 --> 28:32.800] with all sorts of different chipsets, [28:32.800 --> 28:34.200] and they're the really fun targets. [28:34.200 --> 28:36.380] When it comes to custom chips like this, [28:36.380 --> 28:38.920] you're really not going to find much information online about them [28:38.920 --> 28:40.660] just because they're hidden away. [28:40.660 --> 28:41.860] There's about two links [28:41.860 --> 28:44.020] if you search for some of these Samsung chips online, [28:44.020 --> 28:47.120] apart from their accreditations from the NFC forum. [28:47.240 --> 28:48.700] So, finding these chips in the first place [28:48.700 --> 28:49.800] is probably your greatest goal [28:49.800 --> 28:51.720] when you're starting off something like this, [28:51.720 --> 28:52.720] more than anything. [28:53.660 --> 28:56.560] Cool. And someone wants to know [28:56.560 --> 28:58.920] if the firmware was based on an RTOS [28:58.920 --> 29:00.520] or more along those lines, [29:00.520 --> 29:04.460] which is like a standard raw microcontroller target. [29:04.620 --> 29:05.840] Yep, great question. [29:05.840 --> 29:08.800] So, you often find embedded projects like this [29:08.800 --> 29:11.560] using RTOS like VxWorks or FreeRTOS [29:11.560 --> 29:13.580] or Ecos and these sorts of things. [29:13.740 --> 29:15.360] Now, they weren't [29:15.360 --> 29:18.120] because it was literally a straight firmware [29:18.120 --> 29:18.860] that they had compiled. [29:18.860 --> 29:19.620] They had their own tool. [29:19.800 --> 29:22.080] Presumably, they had their own tool chains at Samsung. [29:22.080 --> 29:23.120] They compiled it up. [29:23.120 --> 29:28.120] They had to have everything sorted as they wanted to [29:28.960 --> 29:30.220] and laid out as they wanted to [29:30.220 --> 29:33.600] because they had their firmware as they wanted. [29:33.600 --> 29:35.180] And RTOSs are usually built for certain chipsets [29:35.180 --> 29:38.240] or certain families of chipsets or certain styles. [29:38.240 --> 29:40.880] It just wasn't really meant to be on that point. [29:40.880 --> 29:42.860] Often, these RTOSs have a lot of overhead as well, [29:42.860 --> 29:44.520] like they include debug strings, for instance. [29:44.940 --> 29:46.920] VxWorks are the table that's, I think, [29:46.920 --> 29:47.720] can be compiled out, [29:47.720 --> 29:49.400] but it's at the end of pretty much all their firmware, [29:49.400 --> 29:51.180] which includes all the function names, [29:51.180 --> 29:52.180] which you can then reference back [29:52.180 --> 29:53.620] to all the functions in the firmware, [29:53.620 --> 29:55.280] which saves you a lot of time reverse engineering, [29:55.280 --> 29:58.880] but it's also, from a security perspective, quite bad. [29:59.300 --> 30:00.280] It didn't use an RTOS. [30:00.280 --> 30:01.640] It was just a straight running firmware. [30:01.640 --> 30:02.800] They'd put their own function calls in [30:02.800 --> 30:03.800] and all that sort of thing. [30:04.380 --> 30:06.580] Other chipsets I've looked at that are similar or custom [30:06.580 --> 30:09.280] often implement their own custom RTOSs for this. [30:09.280 --> 30:10.480] But in this case, there was none used. [30:10.480 --> 30:11.940] It was literally just running as it needed to [30:11.940 --> 30:14.560] and relying on interrupts more than threads. [30:16.280 --> 30:18.580] Awesome. That was a great answer, by the way. [30:18.580 --> 30:19.340] Thank you. [30:21.960 --> 30:25.300] Well, it looks like we are running out of questions [30:25.300 --> 30:27.900] and we're just about the end of our time anyways. [30:28.400 --> 30:31.260] Is there any additional links you want to share [30:31.260 --> 30:33.100] or code or anything like that [30:33.100 --> 30:35.860] that you want to get out there? [30:35.860 --> 30:40.200] Yeah, so if we're doing links and that sort of thing, [30:40.200 --> 30:43.560] you can follow me at Twitter at Iscuri1. [30:43.560 --> 30:46.000] So that's my username and then one at the end [30:46.000 --> 30:48.600] because I didn't get the one without the number first. [30:49.020 --> 30:51.420] For GitHub, it's just Iscuri. [30:51.460 --> 30:53.940] And I should be putting out a blog in the next couple of days [30:54.560 --> 30:55.780] outlining all of these details [30:55.780 --> 30:58.000] as well as linking to the YouTube video of this [30:58.000 --> 31:01.460] at pentestpartners.com, which is my company website. [31:01.460 --> 31:03.080] So definitely feel free to have a look [31:03.080 --> 31:05.340] if you want the really nitty-gritty technical details. [31:05.860 --> 31:09.480] Awesome. Well, thank you so much for joining us for this QA session. [31:10.240 --> 31:11.460] It's been great talking to you. [31:11.460 --> 31:14.400] Thank you for providing content to our virtual DEF CON safe mode [31:15.740 --> 31:17.220] and have a nice day. [31:17.260 --> 31:18.720] You too. Thank you very much, guys.