[00:01.060 --> 00:02.880] Alright, so let's talk about a proof of concept. [00:03.220 --> 00:04.380] We are going to look at a PCAP. [00:05.420 --> 00:07.040] There is two streams in here. [00:07.860 --> 00:15.040] If we interpret it as a TCP stream, well actually we will get to that in a second, but as an HTTP stream, they are identical. [00:15.320 --> 00:16.680] You will see two different colors of arrows. [00:16.920 --> 00:21.040] Green is the normal one, red is the suspicious one, because red is suspicious. [00:23.700 --> 00:29.120] And if we look at it in the context of a TCP stream, in this case it is a little bit different under the hood. [00:30.420 --> 00:34.180] So, it might be an eye chart here, but at the top we can see the deflate. [00:34.660 --> 00:36.780] There is the garbage there and the deflate there. [00:36.940 --> 00:38.160] It is just a little bit more garbage. [00:38.380 --> 00:38.960] That is the take away. [00:40.460 --> 00:42.800] And we are going to... I lied on the program. [00:43.080 --> 00:43.880] This is technical. [00:45.080 --> 00:48.380] But narratively speaking, this is the foreshadowing. [00:48.740 --> 00:50.180] We will peel it back and explain this all. [00:50.320 --> 00:55.640] So this is going to be a little... but what I highlighted there in hex, that is the binary of the actual compressed data. [00:56.500 --> 01:01.440] In CyberChef, if anybody is familiar with it, it is just kind of a good Swiss Army knife for encoding and decoding things. [01:02.120 --> 01:08.400] We throw it in there with a recipe of from hex to make it binary and then we inflate it with the deflate algorithm. [01:08.640 --> 01:18.000] And in this case we can see the HTML that it is supposed to decompress to, which is, you know, the tags and then the body of it or the actual text of it is nothing unusual here. [01:19.020 --> 01:21.420] But yeah, we will go back and take a look at the suspicious one. [01:21.920 --> 01:23.900] This one, there is a lot more binary to highlight. [01:24.240 --> 01:26.980] We take it into CyberChef and it is the same thing. [01:27.680 --> 01:30.760] And that is kind of the thing to keep in the back of your head for the rest of this. [01:32.000 --> 01:37.360] And to get super technical, there is this really cool tool that allows you to pop the hood and look at the internals of deflate. [01:37.360 --> 01:38.600] It is called ImpGen. [01:38.800 --> 01:39.840] We will get a lot more into it. [01:40.020 --> 01:42.820] I am just kind of giving a brief preview, foreshadowing. [01:43.340 --> 01:46.980] This is kind of just like all the tokens or characters it is building up. [01:47.440 --> 01:49.680] And you can see like the matches, the pattern matches. [01:49.880 --> 01:52.000] You can look at the tables of all the symbols and all that. [01:52.460 --> 01:54.120] But this is just kind of what normal looks like. [01:54.200 --> 01:56.060] This is the table of the characters it actually uses. [01:56.340 --> 01:57.340] No less, no more. [01:58.180 --> 02:01.660] But if we look at the suspicious one, already there is a lot more stuff in here. [02:01.800 --> 02:04.360] Yellow is the table, blue is the actual data. [02:05.360 --> 02:09.340] For the first block of data, you see the building up of HTML, but then it ends the block. [02:10.060 --> 02:14.100] Yet for the actual table of symbols, it has way more symbols than it is actually using. [02:14.240 --> 02:14.800] That is suspicious. [02:15.540 --> 02:18.980] And then on the next block, it is just the letter B and it ends that block. [02:19.420 --> 02:19.660] Yeah. [02:20.260 --> 02:27.060] And you know, there is also a tool that I will be talking about just released a few days ago that allows you to detect suspicious things in deflate. [02:27.220 --> 02:29.520] So it is definitely telling me about all this Huffman table stuff. [02:29.520 --> 02:36.020] It could even... it even has the ability to scrape the data out of there if there is data hidden in there. [02:36.040 --> 02:40.060] In this case, the hidden data in that one was... but actually there is something incredibly unusual here. [02:41.020 --> 02:43.460] So that was a network proof of concept. [02:44.580 --> 02:46.700] Mostly it is doing some Huffman table manipulation. [02:47.460 --> 02:51.360] So it is the Huffman ignorance of some more general ignorance of different things you can do. [02:51.700 --> 02:53.860] And that is just a small part of what we are going to get into. [02:54.000 --> 02:55.160] So that is kind of the preview. [02:57.900 --> 02:58.580] So deflate. [02:59.060 --> 03:02.060] If nobody has heard of it before, which if you are into compression, that would be weird. [03:02.260 --> 03:05.480] But you know, if you are not into compression, that is cool. [03:05.540 --> 03:05.960] Either am I. [03:06.080 --> 03:07.340] Like this talk is not about compression. [03:08.400 --> 03:10.180] But so it is really common. [03:10.360 --> 03:10.820] It is in gzip. [03:11.020 --> 03:12.680] It is HTTP, PNG and a lot of other things. [03:12.840 --> 03:18.260] It is a really, really common just general purpose compression algorithm. [03:19.080 --> 03:20.920] And actually, it is kind of two algorithms. [03:21.160 --> 03:24.180] It is LZ77-ish because patents or something. [03:24.340 --> 03:24.640] I don't know. [03:25.320 --> 03:26.460] And then the Huffman codes. [03:26.660 --> 03:27.880] And we will get into both of those. [03:28.660 --> 03:31.160] But fortunately, it is actually really straight forward, I think. [03:31.400 --> 03:32.880] It is not really super mathy. [03:33.020 --> 03:35.080] It is conceptually pretty easy to understand. [03:36.740 --> 03:40.380] And this slide right here kind of has nothing to do with the deck. [03:40.380 --> 03:45.200] I think it is just kind of something, just a hackery thing to keep in mind when you approach systems. [03:45.400 --> 03:47.640] I think a lot of people that are hackers kind of already know this. [03:48.280 --> 03:53.060] The difference between what a system is intended to do and what it actually does. [03:53.260 --> 03:57.800] And you will be more effective if you can just throw away that first part, what a system actually does. [03:57.960 --> 04:01.120] If you think about what a system actually does, that is going to get in your way of progress. [04:01.480 --> 04:04.060] What the system does compresses data, decompresses data. [04:04.220 --> 04:05.040] That is not what I am doing. [04:05.420 --> 04:06.340] But it actually does. [04:06.340 --> 04:08.600] It does these words here that whatever. [04:09.340 --> 04:13.620] So let's talk about that first algorithm, the LZ77. [04:14.120 --> 04:15.560] That's like the pattern matching. [04:15.880 --> 04:30.200] So if you have a bunch of text, and then you come into text like, well, I saw this word before, I saw this phrase before, you can, with numbers, you can say, well, that pattern that I saw before, it was like 10 bytes. [04:30.420 --> 04:32.120] And I go back 23 bytes to find it. [04:32.340 --> 04:34.660] So that's just two numbers as opposed to a long string of text. [04:34.760 --> 04:35.500] It's just a shorthand. [04:35.620 --> 04:37.380] That's really all it is conceptually. [04:38.120 --> 04:39.080] I know this is small. [04:39.500 --> 04:40.220] I'll read this. [04:40.360 --> 04:47.200] But as a proof of concept, conceptually, we have the phrase, the hacker was hacking the hack system using hacking strips written by other hackers who had hacked it before. [04:47.980 --> 04:49.880] Yeah, it's a terrible sentence, but there's a lot of reputation. [04:49.880 --> 04:51.100] So that's why I went with that. [04:51.460 --> 04:55.840] So, you know, as we're building up the sentence, we can say the hacker was, and I'll zoom in here. [04:57.380 --> 05:00.380] So we start with the hacker was, but we've, the next word is hacking. [05:00.600 --> 05:01.540] So we saw that word before. [05:01.820 --> 05:05.980] And we're going to say five characters, not four for hack, because there was a space before hackers. [05:06.000 --> 05:07.360] So we're cannibalizing that as well. [05:07.380 --> 05:11.740] So that length distance pair is just five, and then go back 11 to find it. [05:11.920 --> 05:12.620] That's it. [05:12.720 --> 05:14.320] That's all the LZ77 really is. [05:15.020 --> 05:18.220] And as we go, I mean, there's a lot of content. [05:18.440 --> 05:20.080] You just trust me, that's how the whole thing works. [05:20.180 --> 05:21.420] Those are all the length distance pairs. [05:21.560 --> 05:22.400] That's what that would look like. [05:22.600 --> 05:26.780] And, you know, in just plain ASCII without compression, 112 bytes would be that sentence. [05:26.920 --> 05:31.360] But just using LZ and not the Huffman tables, that brings it down to 81 bytes. [05:33.740 --> 05:36.620] So now, and I'm going to be in and out of this slide a lot. [05:36.840 --> 05:38.000] These are just kind of the tools. [05:39.140 --> 05:42.800] I kind of organized it this way to when I talk about a tool, I kind of come back to this slide. [05:42.820 --> 05:46.720] So you kind of have a conceptual idea of not just looking at a bunch of screenshots or videos. [05:46.720 --> 05:52.080] But Cyber Chef, I kind of already explained that's for encoding, decoding, we'll use that a lot. [05:52.520 --> 05:55.980] InfGen is the tool to pop the hood of the compression and look on what's inside. [05:56.680 --> 06:01.800] Irreflate is a tool that I wrote to start under the hood and create compression manually. [06:02.880 --> 06:08.960] And then I'm using a fork of InfGen because mine spits out the whole binary blob in color, color coded with all the fields. [06:10.600 --> 06:17.280] So yeah, let's breathe manually for a second here with Irreflate, just to kind of prove the example, the conceptual example, we'll get our hands dirty with it. [06:17.800 --> 06:34.160] So in this case, we're just going to be building up that phrase, character by character, we got the hacker, in this case, and then a space was, and then we're going to say, five, 11, we can manually put in the link distance pair, and then ing, and then the block. [06:34.780 --> 06:38.560] And then it spits out this ASCII hex, that's our binary blob. [06:38.780 --> 06:45.320] So to prove that like that was doing what we expected to do, we go into CyberChef, and we popped that ASCII hex in there. [06:46.300 --> 06:49.120] And we're going to do from hex to make it a binary blob. [06:49.380 --> 06:51.640] So then we can inflate it with the deflate algorithm. [06:51.960 --> 06:53.820] In this case, we get the hacker was hacking. [06:54.240 --> 06:55.020] So like, it works. [06:56.140 --> 07:02.280] And then just to show impgen, just to show it, we can put in that binary blob. [07:03.040 --> 07:07.420] We just echo it out, and we pop it to xxd-r-p to make it binary. [07:07.800 --> 07:14.220] And then we pipe it to impgen, and then we can see every single field under the hood, but also I'm highlighting that 511. [07:14.460 --> 07:19.240] Like it has all the characters down the line, but then we see five characters go back 11 to find it. [07:19.400 --> 07:20.200] So that works. [07:21.240 --> 07:26.360] I'm going to do the same exact exercise again, but to kind of revisit that ambiguity concept. [07:27.160 --> 07:29.360] So we're going to do the same phrase, the hacker was hacking. [07:30.200 --> 07:31.460] So build that up. [07:35.640 --> 07:37.480] But this time we're doing 411. [07:38.060 --> 07:39.780] So we're not cannibalizing that space. [07:39.940 --> 07:41.300] We're just saying, just take the word hack. [07:42.320 --> 07:43.960] We end up with that binary blob. [07:44.640 --> 07:46.220] And we come back to CyberChef. [07:50.220 --> 07:51.280] We have her from hex. [07:52.940 --> 07:54.640] And we inflate it, hacker was hacking. [07:54.940 --> 07:58.820] The whole point of that is, I mean, that sounds pretty obvious, but the ambiguity is what's important. [07:58.900 --> 08:00.020] There's more than one way to do it. [08:00.660 --> 08:02.420] It's not a one-to-one relationship. [08:02.680 --> 08:04.460] And I love that when that happens. [08:06.260 --> 08:11.040] And then in impgen, I mean, just for illustration purposes, just to validate, you know, you pop the hood. [08:11.180 --> 08:14.980] And really what we're just looking for here is to see that we see that 411. [08:17.020 --> 08:19.400] So yeah, down there we have the 411. [08:23.020 --> 08:27.820] All right, so let's get ignorant with LZ77 specifically, these length distance things. [08:28.280 --> 08:31.120] It's two different things we can do to be ignorant with this. [08:31.180 --> 08:33.760] There's illegal lengths, like bad lengths. [08:34.020 --> 08:36.060] And also we have distances, so illegal distances. [08:36.640 --> 08:42.080] I quoted illegal for the lengths because, okay, so we have the letters HA in our buffer. [08:42.320 --> 08:47.340] And then what we're saying with this length distance pair is we're going to have seven more characters, go back two to find it. [08:47.340 --> 08:51.440] So going back two, we have the HA, but seven characters, like what does that mean? [08:52.320 --> 08:53.780] This is a feature, not a bug. [08:54.500 --> 08:58.080] And instead of saying what it is actually supposed to do, we have the tools. [08:58.360 --> 09:00.020] Let's just do it and see what happens, right? [09:03.520 --> 09:08.980] So we're putting in HA72, and we get our binary blob. [09:11.180 --> 09:13.920] Pump it into CyberChef, see what CyberChef thinks about it. [09:16.220 --> 09:18.120] And we get a lot of laughter. [09:19.320 --> 09:20.160] Yeah, yeah, that. [09:21.860 --> 09:23.520] And in this case, it ends with an H. [09:23.780 --> 09:25.100] So that's another side effect. [09:25.240 --> 09:28.500] I chose an even number for the length just to illustrate that it loops. [09:28.520 --> 09:31.620] And if it's an odd number, it just ends at whatever it was at. [09:32.880 --> 09:35.200] So that's not really that ignorant. [09:35.940 --> 09:37.000] That's what it's supposed to do. [09:37.340 --> 09:40.040] This, on the other hand, we're going to go into this for at least 10 minutes. [09:40.040 --> 09:41.860] This one is wild. [09:42.040 --> 09:44.420] There's a lot of different directions this will take us. [09:44.740 --> 09:47.860] So in this case, we have, again, the same HA. [09:48.120 --> 09:50.440] We're going to say seven characters, which that's fine. [09:50.560 --> 09:53.100] But go back 20 in the buffer. [09:53.760 --> 09:54.340] Where's that? [09:55.000 --> 09:59.820] And, you know, when you're using gzip or something like that, it's never going to create those links distance pairs. [10:00.020 --> 10:02.180] But, like, again, we have the tools. [10:02.660 --> 10:04.220] We can put that in there under the hood. [10:04.440 --> 10:06.020] Let's do it and see what actually happens. [10:08.580 --> 10:09.760] So we're putting in HA. [10:09.940 --> 10:11.160] In this case, it did 742. [10:12.520 --> 10:12.980] You know. [10:14.840 --> 10:16.380] And we get our little buffer here. [10:16.580 --> 10:17.720] Let's see what CyberChef thinks. [10:17.880 --> 10:19.040] And this is what CyberChef thinks. [10:19.140 --> 10:20.860] This isn't what all implementations think. [10:21.460 --> 10:24.420] Like, gzip might be a little bit different, but we're just seeing what this thinks. [10:25.480 --> 10:29.660] So we're going to do back two hex, just because it's going to be unprintable stuff. [10:29.780 --> 10:33.320] And in this case, we have this 6861, which is HA, and then a bunch of nulls. [10:33.700 --> 10:35.280] Yeah, where those nulls come from. [10:35.760 --> 10:36.360] We're going to get down. [10:36.480 --> 10:38.580] We're going to get to the bottom of that towards the end of all this ignorance. [10:38.840 --> 10:41.560] And it's not as interesting as I wanted. [10:41.700 --> 10:43.680] I mean, of course, heart bleed for compression, that'd be great. [10:43.800 --> 10:43.940] No. [10:45.580 --> 10:46.620] Well, that wouldn't be great. [10:49.180 --> 10:52.860] But, yeah, and then to look under the hood to see what InfChain thinks, it actually does throw the warning. [10:53.660 --> 10:57.180] Looking at the 42-2, it says, that's a distance too far back. [10:57.300 --> 10:58.000] And, yeah, it is. [11:01.940 --> 11:07.300] So instead of looking at gzip or something super complicated, I wanted to see, well, CyberChef did this. [11:07.380 --> 11:08.380] Where is it getting its nulls? [11:08.380 --> 11:09.440] I kind of looked at their source code. [11:09.580 --> 11:12.860] I didn't come to the answer right away, but I saw something really, really interesting. [11:13.340 --> 11:21.200] And this is, if you know CyberChef, the authors, this is GCHQ, the British NSA, which is just... [11:21.200 --> 11:22.040] That's not relevant. [11:22.160 --> 11:22.760] It's just funny to me. [11:23.220 --> 11:27.100] So they put in this comment here, raw inflate sometimes messes up and returns nonsense like this. [11:27.560 --> 11:34.260] And, you know, like the square brackets and dots, that's the nonsense that four bytes of hex below that produce when they try to inflate it. [11:34.520 --> 11:36.100] So they didn't understand it. [11:36.160 --> 11:38.920] They just built an edge case around this to err on it. [11:39.420 --> 11:53.160] And, like, in shorthand, if it finds a payload that's larger than 158 bytes, and the first and six characters are square brackets, and that every six-byte thing is a square bracket for 155 bytes, which was the exact case here, then, you know, do a warning. [11:53.520 --> 11:56.380] But, like, it's not just, like, square brackets and dots. [11:56.620 --> 12:00.700] I tried, well, what if I did the square brackets with something else and just, like, hacks, hacks, hacks, hacks? [12:00.860 --> 12:03.840] And I still get an error because their edge case is just looking for the square brackets. [12:04.000 --> 12:07.880] So the thing with this recipe to really pay attention to is this is legitimate. [12:08.040 --> 12:11.760] I'm doing... I'm taking the hacks, I'm deflating it, and just reinflating it. [12:12.060 --> 12:13.060] That shouldn't be an error. [12:13.880 --> 12:15.500] But they put in a stupid edge case. [12:16.580 --> 12:17.540] What is this edge case? [12:17.680 --> 12:18.260] Well, we have the tools. [12:18.260 --> 12:19.500] So let's reproduce it. [12:20.860 --> 12:23.920] In this case, we just throw it at impgen and see what the actual problem is. [12:23.980 --> 12:25.300] And it's related to what I was talking about. [12:25.400 --> 12:27.620] It is a length too far back kind of an issue. [12:28.120 --> 12:34.680] In this case, they had the square bracket, and then they said, length of 158, go five bytes back to find it. [12:34.740 --> 12:40.880] And that's why it repeats that square bracket, and the dots are the nulls, because that's what it's representing, the nulls as its dots. [12:43.260 --> 12:51.700] So, like, I wanted to try to do something like that, but without the square bracket, just to see if it would error out on that, which you know it's not gonna, but I just got to prove my point here. [12:52.260 --> 12:56.400] So in this case, I'm doing X instead of a square bracket, and then I'm doing the same 158.5. [12:56.400 --> 13:02.940] I take that, go into CyberChef, and, you know, if it really should be erroring out on that error condition, then it would for that too. [13:03.220 --> 13:08.360] And just to verify, you know, impgen, it's showing that we have that 158. [13:09.880 --> 13:13.040] Yeah, the 158.5 and then 5.1, too far back, but with the X this time. [13:13.720 --> 13:19.560] So when we go to CyberChef, we put that in there, and it's gonna work this time. [13:20.160 --> 13:25.880] Of course, we're gonna put it, after we inflate it, we're gonna go back two hex, just to see the binary of it. [13:28.760 --> 13:29.860] And again, nulls. [13:30.040 --> 13:32.040] I swear, we'll get to the bottom of where those nulls are coming from. [13:32.860 --> 13:38.540] But as an aside, I told the people that maintain CyberChef, that's dumb, remove it. [13:38.960 --> 13:39.540] And then they did. [13:43.080 --> 13:45.240] All right, so that gave me an idea. [13:46.000 --> 13:46.700] Those nulls. [13:46.820 --> 13:51.700] I wanna build the biggest buffer I could possibly do in one block, which in this case is about 32k. [13:52.000 --> 13:54.120] So I wanted to do 32k of too far back. [13:54.240 --> 13:57.840] I wanted to see how far back I can peel, and if there's anything more interesting than nulls. [13:58.780 --> 14:01.120] I mean, long story short, there wasn't, but, you know. [14:01.880 --> 14:03.620] But this is the proof of concept for it. [14:03.820 --> 14:06.320] So I crafted that in Irreflate. [14:06.760 --> 14:10.080] And then I pasted this buffer into CyberChef. [14:10.820 --> 14:13.040] So from hex, then I'm gonna inflate it. [14:13.900 --> 14:16.580] And then I'll do two hex again as well. [14:16.740 --> 14:17.580] Right now it's 32k. [14:17.940 --> 14:19.000] The bottom is really small. [14:19.200 --> 14:22.000] And then when we inflate it, it's like 95,000 something. [14:22.160 --> 14:28.680] That's because, you know, with the space of a delimiter and the two ASCII nibbles, that's like, it triples what it thinks. [14:28.860 --> 14:30.960] But anyway, so yeah, it's just nulls. [14:32.180 --> 14:33.720] Still haven't really got to the bottom of that. [14:34.800 --> 14:37.600] But before we get to the bottom of that, let's play with it a little bit. [14:38.460 --> 14:44.280] We can introduce nulls that kind of are illegitimate in a way, which is interesting. [14:44.460 --> 14:51.720] So as a proof of concept, I'm really not gonna go into too much measures explaining why I'm going through some of these steps here. [14:51.840 --> 14:56.240] Like this first step, I'm only doing it to create a checksum because I'm going to create a gzip file. [14:56.540 --> 15:01.300] So it's kind of... doesn't seem that sensible. [15:01.500 --> 15:06.220] But in this case, I'm using Earflate to manually craft the word test. [15:06.360 --> 15:08.940] And then I do 4.8 as the pattern. [15:09.100 --> 15:15.360] So going back eight, which I don't have, it should be a bunch of nulls and the checksum is going to match what would be with the nulls. [15:16.300 --> 15:24.420] And in this case, I try to use pigs to extract it, which pigs... it's written... I mean, Mark Adler's behind that too. [15:24.640 --> 15:27.180] He's also one of the main people behind gzip. [15:27.420 --> 15:32.020] Pigs is pretty much like gzip, if I understand this right, except for it's multi-threaded, but it's more modern. [15:32.260 --> 15:38.600] And when I gave pigs this test.gz, it says, no, this is invalid, which it is. [15:38.720 --> 15:39.480] That's what it should do. [15:39.580 --> 15:41.400] This is... you shouldn't be able to be extracting this. [15:42.400 --> 15:47.340] gzip version 1.13, and not version 1.13, but I'd say version 13. [15:48.380 --> 15:50.660] Also, it's modern enough to be like, no. [15:51.540 --> 15:54.600] And then I took the hash, the SHA-256. [15:54.700 --> 15:58.500] Just to show, it starts with 3B, ends with F3. [15:59.240 --> 16:00.420] This is the file. [16:00.740 --> 16:11.060] Just to say, when we go into an older version of Ubuntu that I had, and this is going to be gzip 1.9, which is an older one, we try to extract tests there. [16:11.060 --> 16:12.160] And we get it. [16:12.660 --> 16:14.520] So this is before they were doing this check. [16:15.440 --> 16:16.900] So let's get weirder with that. [16:17.700 --> 16:20.220] So now I have a file called lol.gz. [16:20.560 --> 16:21.840] This is a hex dump of it. [16:22.420 --> 16:24.140] We're going to do gzip with it. [16:24.300 --> 16:24.820] Same problem. [16:25.040 --> 16:26.520] The newer gzip can't handle that. [16:26.720 --> 16:31.340] But if we use the older gzip for it, we're going to... yeah, it's gzip compressed. [16:31.580 --> 16:32.720] There's the hex dump of it. [16:32.880 --> 16:34.120] We're going to extract it. [16:35.160 --> 16:35.900] No errors. [16:36.140 --> 16:36.760] We have our LOL. [16:37.260 --> 16:37.880] What is it? [16:38.080 --> 16:39.080] It's an elp executable. [16:39.080 --> 16:40.600] Okay, let's make it executable. [16:41.520 --> 16:42.280] We're going to run it. [16:42.540 --> 16:43.180] Well, what? [16:43.980 --> 16:52.040] So the cool thing here is you can create a file that can extract something legitimate, but not on newer gzip. [16:53.200 --> 16:56.640] I mean, I don't know what to use that for, but I think that's kind of interesting. [16:59.880 --> 17:02.500] And just as an aside, how does a browser handle this? [17:03.280 --> 17:04.560] So, you know, I made a proof of concept. [17:04.740 --> 17:05.880] Same kind of thing. [17:06.120 --> 17:06.240] Test. [17:06.460 --> 17:09.140] And then, you know, 10 characters go back 50, end of block. [17:10.140 --> 17:14.320] You know, it sort of looks okay so far, but the browser just pukes when it sees that. [17:14.460 --> 17:15.100] So the browser... [17:15.100 --> 17:16.120] That's what it should do. [17:16.220 --> 17:18.320] It shouldn't be handling that like Cyber Chef. [17:20.040 --> 17:25.580] Okay, so to really go into what gzip is doing, debugger time. [17:25.900 --> 17:26.740] And I'm not going to... [17:26.740 --> 17:28.480] Don't have a lot of time to go really crazy with it. [17:28.540 --> 17:30.000] I'll give you the short of what's happening. [17:30.160 --> 17:36.760] But, you know, when I get into the section where it's actually copying the bytes from the buffer, doing that part of it, you know, you go up the... [17:36.760 --> 17:39.880] all the functions, and you get to the memcopy. [17:40.320 --> 17:42.320] And for memcopy, it's just length, source, destination. [17:42.940 --> 17:45.900] If you look at the source and the destination... [17:45.900 --> 17:47.760] So the source is... [17:47.760 --> 17:50.920] They both start with 4, 3, and hex, and then the source is ffdf. [17:51.320 --> 17:53.660] The destination is 7fe3. [17:55.900 --> 17:56.780] For those... [17:56.780 --> 17:59.780] Really, long story short, the destination comes before the source. [18:00.140 --> 18:03.240] So what's actually happening is it's not going back to find nulls. [18:04.840 --> 18:05.560] It's actually... [18:07.100 --> 18:10.220] It's coming around to the end and back. [18:10.780 --> 18:17.520] So it's like, in a way, this makes total sense, because if it was accessing a buffer and shouldn't have, like, maybe the OS would be throwing an error. [18:17.780 --> 18:19.760] Like, you would be having more problems. [18:20.020 --> 18:27.400] So it makes sense that this is why you're not getting an error, but also why you're getting nulls, because it's pre-initialized, and there is no data in it. [18:28.460 --> 18:30.480] So I was glad to get to the bottom of it. [18:30.800 --> 18:32.300] Disappointed that it was something so simple. [18:33.540 --> 18:35.440] But that's the story for that. [18:36.980 --> 18:37.420] Cool. [18:37.720 --> 18:39.220] I'm going to check the time real quick here. [18:39.800 --> 18:44.760] I think we're doing good, because now we're going to get to the next algorithm, the Huffman codes. [18:45.720 --> 18:48.620] A little bit more complicated, but conceptually still not that bad. [18:51.480 --> 18:55.620] So in this case, we're using the example phrase of no error to report. [18:56.160 --> 18:58.860] I use this phrase because there's repetition in the letters. [19:00.740 --> 19:05.760] If it were just ASCII, these are the characters in this table, and the binary it would represent. [19:06.380 --> 19:07.780] That would be 18 bytes. [19:08.980 --> 19:13.520] What if we could say, well, we're only using like seven characters, including the space. [19:13.640 --> 19:15.160] What if we just did three bits for each? [19:15.160 --> 19:21.480] Of course, we could save there, but that'd be naive, because of course, with real data, we're going to have more than just those seven characters. [19:22.920 --> 19:26.620] But what if we could vary the amount of bits that we use for each one? [19:26.740 --> 19:30.240] Like, what if the letter E was really frequent, but the letter Z wasn't? [19:30.420 --> 19:32.840] So maybe we encode the letter E with like two to three bits. [19:32.980 --> 19:37.200] And yeah, the Z, we might have to use like nine or 10 bits, but that's okay, because we only use it a couple of times. [19:37.300 --> 19:38.280] That savings is worth it. [19:38.280 --> 19:47.040] So like, this is an example that could look that like with just these characters, like a little north of six bytes, 49 bits. [19:48.000 --> 19:50.220] And this is not just abstract. [19:50.440 --> 19:53.800] Again, I really like to get hands-on with this. [19:53.960 --> 20:02.640] So in this case, I'll just show like no error to report in CyberChef, and I'm going to run deflate on it to actually compress it. [20:02.740 --> 20:07.140] I'm choosing to use dynamic Huffman coding, so we get that Huffman table, and we get our blob there. [20:07.680 --> 20:11.960] So now that we have our blob, we can go to InfGen and inspect it and actually look at what that table looks like. [20:12.040 --> 20:13.280] That's one of the cool things about InfGen. [20:13.880 --> 20:15.840] You can really see all the internals. [20:16.480 --> 20:17.760] And in this case, color-coded. [20:18.860 --> 20:20.600] So that's what the table looks like. [20:20.760 --> 20:21.360] I'll come back. [20:21.860 --> 20:22.580] Did I mess it up? [20:23.060 --> 20:24.740] No, I'm just checking it. [20:24.880 --> 20:25.300] Go for it. [20:25.560 --> 20:28.660] I just want it to be a little more pointed towards you. [20:29.140 --> 20:29.500] Go up there. [20:30.120 --> 20:30.600] All right. [20:32.580 --> 20:36.620] So I'm just bringing the table back from InfGen to show this is the same. [20:37.520 --> 20:38.460] It's not hypothetical. [20:38.760 --> 20:44.940] So it makes sense if we look at the ones that are really short in bits, like the O is 00 and R is 01. [20:45.760 --> 20:49.360] If you look at no error to report, there's a lot of O's and a lot of R's. [20:49.980 --> 20:54.160] But if you look at the ones that are a lot of bits, five bits each, the N and the P have five bits each. [20:54.460 --> 20:57.040] And really, there's only one N and there's only one P in the phrase. [20:57.300 --> 20:59.120] So conceptually, that's Huffman tables. [20:59.120 --> 21:05.380] Like, yeah, if you want to breathe manually and encode it yourself in binary, like that's... I'm not going to talk about that. [21:05.500 --> 21:08.300] Like we could after, but that does get pretty crazy. [21:08.480 --> 21:10.320] But that's conceptually all you got to do. [21:11.480 --> 21:12.900] That's kind of the algorithm for doing it. [21:13.080 --> 21:15.460] So one of the things is like, well, what about delimiters? [21:15.800 --> 21:18.620] The beauty of how it's encoded is it's a binary tree. [21:18.780 --> 21:20.140] So there actually is no ambiguity. [21:20.360 --> 21:21.020] It's really clever. [21:21.640 --> 21:26.440] In the RFC 1951, this is kind of talking about that, but no time for that. [21:27.280 --> 21:30.520] Let's talk about some Huffman ignorance now that we're in here. [21:30.680 --> 21:31.840] And now that we understand Huffman tables. [21:32.800 --> 21:35.100] So we're about just filling up the whole table and not using it. [21:35.240 --> 21:38.280] Like we make a table for all of our alphabet and then we just end the block. [21:38.540 --> 21:39.660] Like, what would that look like? [21:41.500 --> 21:43.040] This video is a little bit longer. [21:43.680 --> 21:58.660] By that, I mean like not more than 30 seconds, but I'm using Earflate to just max out everything, max out the whole alphabet I'm going to be using and all the bit links for all the characters, just to make this table as big as I possibly can. [21:59.420 --> 22:05.760] And interestingly enough, the Huffman table itself is encoded with another Huffman table. [22:06.500 --> 22:06.900] It's... [22:08.500 --> 22:16.320] And it's like, while Earflate is pretty useful to be able to manually create your own Huffman tables, it's still tricky. [22:16.480 --> 22:22.380] You kind of still have to understand what you're doing because you can do things like over subscribing or under utilizing. [22:22.800 --> 22:24.800] Like it's... [22:25.340 --> 22:31.520] Which like I try to make it a little bit easier with the tool that it'll tell you how many codes you have left and all that as you're building it up. [22:31.620 --> 22:33.140] But it's still kind of an art. [22:33.900 --> 22:35.620] But okay, so now we finally got our buffer. [22:36.520 --> 22:38.420] We're going to go over to CyberChef. [22:40.960 --> 22:42.840] And it's a lot of data. [22:43.620 --> 22:44.020] That's... [22:44.020 --> 22:45.060] You know, now it's binary. [22:45.220 --> 22:46.240] Let's inflate it up. [22:47.340 --> 22:47.800] Nothing. [22:49.560 --> 22:50.540] It's funny to me. [22:51.860 --> 22:56.000] And to pop the hood, we'll tell mchen to analyze this. [22:58.480 --> 23:00.800] And really, I just want that color-coded bit pattern. [23:01.200 --> 23:04.400] So like I said a long time ago, yellow, that's the Huffman table. [23:04.980 --> 23:06.520] There's a lot of Huffman table in this. [23:07.180 --> 23:10.000] If we want to look at that and just kind of pick the pieces apart. [23:10.760 --> 23:13.640] Bit by bit, you know, that purple bit, that's saying it's the last block. [23:14.000 --> 23:16.460] So if it was zero, that would mean there's more blocks to follow. [23:17.000 --> 23:19.180] We want dynamic mode, means using Huffman tables. [23:19.420 --> 23:29.940] We want the max amount of literal length codes, the max amount of distance codes, the max amount of code length codes, which is that that's the part of the Huffman table encoded as the Huffman table. [23:30.740 --> 23:34.280] And then that's the actual codes that are building up the Huffman table. [23:34.280 --> 23:36.540] And this is the Huffman table. [23:37.400 --> 23:43.320] And then end the block in blue and those three white zero bits are the padding. [23:44.100 --> 23:46.780] But yeah, you're ending the block before you even use it. [23:47.320 --> 23:48.580] So that's how that one works. [23:49.280 --> 23:50.520] What about this? [23:50.700 --> 23:53.760] This is just another stupid compression trick here. [23:55.360 --> 23:57.200] So we have this blob here. [23:57.380 --> 23:58.840] I think this is the legitimate one. [23:59.040 --> 24:01.880] What we get out of here is the word hacks, H4x. [24:02.700 --> 24:05.040] But the point is for this, it's a binary blob. [24:05.420 --> 24:13.340] What if we took out the conversion from hacks and we have this phrase, five carriage return, IR, dollar sign, blah, blah, blah. [24:14.300 --> 24:16.180] This decodes to hacks as well. [24:16.460 --> 24:20.660] But the cool trick with this is that this is not binary, this source input. [24:20.900 --> 24:24.340] This compressed data, this compressed blob of data, it's all ASCII printable. [24:25.080 --> 24:26.680] That's actually kind of hard to pull off. [24:27.840 --> 24:32.200] So the way that that looks, I'll go into impchen and pop the hood on this one. [24:35.940 --> 24:36.480] All right. [24:36.640 --> 24:40.400] So still lots of Huffman table, but we actually are using some of it. [24:42.040 --> 24:45.180] In this case, we have our four bit literal. [24:45.400 --> 24:49.740] So H4x and end of block is also a token we got to use. [24:50.560 --> 24:53.260] Each of our bit links are four bits long. [24:54.640 --> 25:03.460] And so the reason I did that is so they're all aligned, because I don't get that many characters to choose from when my Huffman table is only really encoding for four different things. [25:04.780 --> 25:07.100] But yeah, another stupid compression trick. [25:07.460 --> 25:12.960] And we already talked about packing in arbitrary data with the network proof of concept. [25:13.340 --> 25:17.400] So now let's just talk about some general ignorance that uses all those tricks. [25:17.760 --> 25:20.120] R.zip, this one's really cool. [25:20.120 --> 25:25.720] So R.tar.gz, you extract it, it puts R.tar.gz into a directory called R. [25:26.080 --> 25:29.060] You go in there and you extract it and you get the idea. [25:29.280 --> 25:30.520] The hash is the same every time. [25:31.240 --> 25:33.420] That's some just dark arts right there. [25:34.400 --> 25:39.960] Because you are having to do crafting manual compression there. [25:39.960 --> 25:49.880] And also the author of this, being that this is a GZ file and also the .zip that this applies, you have to recursively understand the checksum too. [25:50.700 --> 25:51.880] And I read his blog. [25:52.620 --> 25:54.160] They brute forced that. [25:54.680 --> 25:55.900] What else are you going to do? [25:57.020 --> 25:58.460] That's what that one looks like. [25:58.540 --> 25:59.000] R.zip. [26:00.220 --> 26:01.000] It's cool. [26:02.180 --> 26:04.080] Another little bit of ignorance. [26:04.420 --> 26:07.940] For a little while I was handing out this business card, like a hacker card. [26:08.200 --> 26:13.180] A lot of people thought that this was just like a PGP key or something like that, but it's not. [26:13.500 --> 26:20.140] The idea was I saw a lot of hacker challenges at conferences that were just like, decode Base64, you win. [26:20.400 --> 26:21.380] And I was like, that's kind of dumb. [26:21.380 --> 26:26.940] So I wanted to make something, not to challenge people, but like I just, I'm big into satire. [26:27.780 --> 26:29.080] So this is Base64. [26:29.640 --> 26:32.060] There is a clue here for what the next step is going to be. [26:32.500 --> 26:35.520] It's hard to see from here, but there's a couple of characters that are light blue. [26:36.660 --> 26:38.340] So those characters spell it deflate. [26:38.780 --> 26:41.940] So at least you know when you go into CyberChef and do it, you know what the next step is. [26:42.480 --> 26:45.060] So let's solve this code in like less than two minutes. [26:46.540 --> 26:48.220] We'll go into CyberChef. [26:48.220 --> 26:50.720] We put that in there from Base64. [26:51.060 --> 26:51.840] Obviously it's binary. [26:52.160 --> 26:53.520] So let's do two hex. [26:54.640 --> 26:56.660] And then in this case, we're going to inflate it. [26:58.460 --> 27:01.000] And there's a couple of clues here with what we end up. [27:01.700 --> 27:05.440] It says 100 or 1024 at the bottom for how many characters we have. [27:05.720 --> 27:07.080] Know that this is a C hex. [27:07.180 --> 27:09.040] So it really means this is 512 bytes. [27:09.240 --> 27:10.140] It's clue one. [27:10.360 --> 27:11.940] It ends with 55AA. [27:12.220 --> 27:12.840] It's clue two. [27:13.540 --> 27:19.260] The other clue, this is kind of obscure, but if anybody does a lot of reversing and looks at machine code a lot, that 31 C zero. [27:20.320 --> 27:21.580] XOR EAX EAX. [27:21.720 --> 27:22.900] Like that just kind of pops out at you. [27:23.200 --> 27:24.840] So it's executable. [27:25.060 --> 27:25.740] That's third clue. [27:26.360 --> 27:27.820] Long story short, that's a boot sector. [27:29.740 --> 27:30.800] So let's boot it. [27:31.740 --> 27:33.260] We're going to echo this buffer out. [27:33.380 --> 27:34.780] We're going to use XXD to make it binary. [27:35.620 --> 27:36.640] Call it card.bin. [27:37.160 --> 27:40.060] We're going to use chemu to boot it. [27:42.400 --> 27:45.700] And it asks us enter the last nine LZ distances. [27:45.960 --> 27:48.300] It's asking for a password and it's XOR encoded. [27:49.480 --> 27:55.580] So, well, now we got to actually look at pop the hood and what are the last nine LZ distances of the compressed blob there. [27:55.740 --> 27:56.460] And there they are. [27:57.540 --> 28:01.260] So there's some like recursive stuff or self-referencing stuff going in here. [28:01.760 --> 28:04.180] The challenge was harder to create than it is to solve. [28:04.320 --> 28:06.240] And I kind of like and prefer that asymmetry. [28:06.360 --> 28:09.020] Of course, it's easy to make something that will confuse people. [28:09.160 --> 28:10.000] It's easier to do that. [28:10.940 --> 28:14.140] But anyway, so the result of that, I'll make it a little bit bigger because the screen. [28:14.300 --> 28:16.340] But so this is what you end up with. [28:16.440 --> 28:18.440] You enter the password and it says hacker challenges are pointless. [28:18.620 --> 28:18.880] Am I right? [28:23.080 --> 28:24.300] So let's talk about forensics. [28:24.620 --> 28:25.940] We're kind of getting near the end of this. [28:27.180 --> 28:29.840] And then I'll talk about the Cobra channel stuff right after this. [28:29.900 --> 28:30.800] We'll go through this pretty quick. [28:30.940 --> 28:34.240] But there was a tool out there that looked really cool. [28:34.480 --> 28:35.140] It is called ZipRec. [28:35.320 --> 28:43.300] And it takes the same approach that I ended up taking, except that they also apply some LLM stuff to fill in the gaps, which I thought was really clever, honestly. [28:44.100 --> 28:49.200] But my problem with it is the same problem all the other three open cases are with this GitHub repo, is you can't compile it. [28:49.200 --> 28:54.780] I mean, I felt dumb, but then being that everybody else was not able to do it, I'm like, I'm just going to make my own. [28:55.000 --> 28:58.260] So my tool is not as good as this tool, but you can run my tool. [29:01.340 --> 29:04.180] So hypothetically, consider a fragment of data. [29:04.360 --> 29:05.480] It was the part that was in red. [29:06.880 --> 29:07.880] Alignment is the big issue. [29:07.980 --> 29:10.840] You can't just paste it into CyberChef and get, you know, something sensible. [29:11.120 --> 29:15.220] So in this case, we're going to try anyway, and we're just going to delete bytes off the front and see if we get anything. [29:15.400 --> 29:16.120] It's like broken buffers. [29:16.240 --> 29:17.420] Oh, this looks like words, right? [29:17.760 --> 29:18.700] And then we keep on deleting. [29:18.700 --> 29:19.560] Oh, no, that's garbage. [29:19.760 --> 29:20.040] It's garbage. [29:20.240 --> 29:23.100] And so that approach doesn't quite work perfectly. [29:23.780 --> 29:25.100] You kind of do need a tool for it. [29:25.160 --> 29:27.100] But I just kind of wanted to show what that would look like. [29:28.320 --> 29:35.600] So we get back to a demonstration here of toe knife, because scalpel, toe knife, forensics. [29:35.880 --> 29:37.120] So we put the data in there. [29:37.300 --> 29:40.940] And this kind of allows us to just look at examples. [29:40.940 --> 29:44.180] And when we land on the right one, it'll tell us what we have. [29:44.280 --> 29:46.300] But it also will give you those length distance pairs. [29:46.920 --> 29:50.660] And then once you land on it, this version just shows you what the table would look like. [29:50.720 --> 29:52.780] So you can have a good idea of what you might want to guess. [29:52.980 --> 30:01.440] I'm going to give it some guesses for those length distance pairs, the word for and the ERS, because that seemed right to me and give it that as hints or clues as opposed to using an LOM. [30:02.520 --> 30:11.720] And then I'm able to get the result, which is it even backfills for what the length distance would be before the fragment. [30:11.980 --> 30:15.760] So in this case, we end up with ERS and then a bunch of questions and then four. [30:15.940 --> 30:19.400] And then four is the only of those that has four letters in it, is the phrase. [30:19.740 --> 30:25.060] If you want to see what the whole thing looks like, that's a screenshot of the full buffer and not the fragment. [30:25.220 --> 30:26.600] So that's what the original sentence would look like. [30:26.600 --> 30:32.980] So really the RFC says that 1951 for deflate says you shouldn't really... [30:32.980 --> 30:36.440] It's not meant to look at arbitrary data, which makes sense, you know. [30:36.920 --> 30:38.460] But that doesn't mean it's impossible. [30:40.820 --> 30:42.720] So let's talk about some covert actions. [30:45.400 --> 30:52.960] This is Stego territory, and I'm bored of Stego, but like, I know it's possible here. [30:52.980 --> 30:54.180] So talking about it. [30:54.640 --> 31:02.480] What is interesting about this PNG-based Stego, though, is that the bits or the colors aren't going to change at all. [31:04.280 --> 31:07.400] Because traditionally, you know, change red a little bit and you can code a bit. [31:07.500 --> 31:09.660] No, we're not changing the actual data at all. [31:12.260 --> 31:16.600] So, you know, here's all of our PNGs, different file sizes, different hashes. [31:17.780 --> 31:19.260] We're going to look at each one of them. [31:19.840 --> 31:22.280] You know, that's one, that's one, that's one. [31:22.280 --> 31:23.220] They're all the same. [31:23.400 --> 31:24.400] The data is identical. [31:27.240 --> 31:33.240] So if we look at these kind of one by one, looking at the hex stump and the mGen output of it. [31:33.740 --> 31:35.920] And this one, this is stored mode, so not compressed at all. [31:36.100 --> 31:42.040] So we see that the first zero is not part of the actual PNG data, but the 25500, that's your red. [31:42.040 --> 31:46.040] The 00255, that's your blue. [31:47.240 --> 31:50.520] In this case, we're using dynamic mode, so we do have a Huffman table. [31:50.780 --> 31:54.460] But if you look at the literals, we, again, that first zero is not the color. [31:54.580 --> 31:56.260] So we have a 25500, that's your red. [31:56.400 --> 32:02.920] Then we say match six, there's going to be six more bits, or bytes in this case, and then go back four to find it. [32:02.920 --> 32:06.220] And it kind of like, that unevenness is what gets your green and blue. [32:07.020 --> 32:09.100] We do the same thing without a Huffman table. [32:09.240 --> 32:13.980] So we do fixed mode, and it's the exact same approach there, just a different way of representing the same data. [32:15.040 --> 32:21.080] Again, fixed mode, we do it a little bit differently with our length distance pairs, but the end result is the same data. [32:21.380 --> 32:23.500] Same data, same data. [32:23.700 --> 32:24.960] Many ways, the same thing. [32:26.080 --> 32:36.280] So I got to a point where I kind of wanted to automate, not just this concept of creating many different arbitrary variations of a file, but also to hide data in the Huffman tables. [32:36.680 --> 32:40.560] And I am writing this tool, and it is working pretty well. [32:41.820 --> 32:44.200] I haven't released it, and I don't know if I plan to. [32:44.640 --> 32:52.060] I didn't have... I could not in good conscience make this tool public without writing the tool that can detect this nonsense. [32:52.060 --> 32:56.980] And not just the nonsense of my tool, but all nonsense of deflate. [32:57.920 --> 33:00.600] So this tool I call deflate defector. [33:01.480 --> 33:03.540] It detects anomalies and deflate. [33:03.880 --> 33:07.880] The five big ones that I do is unnecessary repetition. [33:08.240 --> 33:11.720] So let's say we have the phrase OMG hacks, OMG hacks, OMG hacks. [33:12.880 --> 33:20.180] If you were to look at some deflate and you saw those as literals, like no length distance pairs, but just literals down the line, that's suspicious. [33:20.440 --> 33:21.460] You should never see that. [33:21.780 --> 33:25.960] If you're compressing with anything legitimate, it is going to make those patterns. [33:26.680 --> 33:27.680] So that's suspicious. [33:27.820 --> 33:28.620] The tool detects that. [33:28.920 --> 33:35.540] But even if you're not splitting the pairs, or if you're not like crafting the pairs the most efficient way, that's still suspicious. [33:35.880 --> 33:40.820] So like, let's say OMG hacks, we could say six characters go back six to find them. [33:41.260 --> 33:42.760] Six characters go back six to find them. [33:43.080 --> 33:43.740] That would work. [33:43.860 --> 33:44.440] That would decode. [33:44.440 --> 33:45.800] But that's still suspicious. [33:46.140 --> 33:47.720] Your compression tools are not going to make that. [33:48.260 --> 33:50.360] What it really would make is 12.6. [33:50.540 --> 33:51.580] That's what you'd expect to see. [33:51.920 --> 33:58.080] And for proof of concepts like the R.zip and my business card, they both split pairs ends up in both of those. [33:59.520 --> 34:00.280] Empty blocks. [34:00.520 --> 34:05.480] Well, we saw that with me just crafting an empty block to see what would happen. [34:06.680 --> 34:08.940] But like, yeah, that's also suspicious. [34:11.160 --> 34:14.080] Underutilized blocks, that's definitely the network proof of concept. [34:14.400 --> 34:18.380] So I have a Huffman table built up, but I'm not using all the characters from it. [34:18.480 --> 34:22.260] I built the Huffman table to put the data in, but not to use it for the actual message. [34:23.520 --> 34:37.480] And if that wasn't enough, what if you were clever enough to make your Huffman table to put all of your encoded data in, your secret data, but you were clever enough to actually use every single symbol in that table to try to thwart this even? [34:37.900 --> 34:40.520] Well, statistics are still going to catch up with you. [34:40.520 --> 34:42.720] So it has this heuristic as well. [34:42.960 --> 34:54.860] So even if I used all of them, it would say, well, the bit length in the Huffman table for the letter Z, it's a little bit long, yet you use the letter Z a lot in your actual payload. [34:55.020 --> 34:57.200] That doesn't match statistically. [34:57.660 --> 34:59.720] So it does that analysis as well. [35:00.060 --> 35:07.480] So with this deflate defector tool, there's not a lot of wiggle room to do something sketchy. [35:07.480 --> 35:12.660] Pretty much any of the examples, any of the ignorance that I talked about here, this tool would pick up on all that. [35:12.840 --> 35:18.000] And other things like r.zip, I didn't write that, but this tool would definitely pick up on all the ignorance in there. [35:20.020 --> 35:21.160] So what's next? [35:21.480 --> 35:24.820] Honestly, I kind of wanted to do all this before this talk. [35:25.000 --> 35:26.460] But, you know, life gets busy. [35:27.060 --> 35:28.460] These are things I still want to do. [35:28.980 --> 35:33.560] This deflate stuff is something I've been kind of obsessing about for like the last seven years. [35:33.560 --> 35:36.740] I just keep on putting it down like, yeah, there's nothing useful. [35:37.100 --> 35:38.940] And then I'm like, oh, I really... Yeah. [35:39.800 --> 35:42.220] But so this is kind of a passion project. [35:42.400 --> 35:47.820] I do kind of vapor some of the stuff I do, but this one I'm still interested in. [35:48.040 --> 35:56.240] So one of the first things I wanted to do is spider for anomalies, like just go out there on the Internet and not just to help debug my tool and make sure it's better. [35:58.080 --> 36:03.380] But, you know, I don't want to give the impression that I even think that threat actors are using this as a way to... [36:03.380 --> 36:05.180] There's so many other ways to do it. [36:06.440 --> 36:13.220] And I mean, of course, I didn't find any evidence of it, but it'd be cool to find weird stuff out there. [36:14.940 --> 36:20.560] If there were people using it because there's no evidence of it, it's those kind of people using it. [36:21.240 --> 36:30.000] And, you know, one of my friends, Lambda Calculus, he's been doing a lot of stuff with, you know, DPRK, the North Red Star OS. [36:30.260 --> 36:32.140] Like they definitely do some sketchy stuff. [36:32.280 --> 36:39.540] And it's just it's been on my mind, which is why I put more energy in the deflate defector as opposed to the deflate tool. [36:40.180 --> 36:43.280] And also kind of probably why I call it deflate defector. [36:44.880 --> 36:49.600] But yeah, so it'd be really interesting to find anomalies out there in the wild, not to say that they're going to be malicious. [36:49.760 --> 36:52.740] But if I do find an anomaly, it's probably going to be at least interesting. [36:53.980 --> 37:01.400] And, you know, if this is going somewhere, it'd be cool to write a web service where people could upload a file and get the result back. [37:01.560 --> 37:09.360] Like, I guess the use case for that is, you know, maybe it's somebody that doesn't want to download my script off of GitHub and maybe not technical enough. [37:09.360 --> 37:10.500] That's fine. [37:10.760 --> 37:12.280] So, you know, make something easy for it. [37:12.360 --> 37:17.900] But I do want to take considerations with this because, I mean, as far as privacy goes and all those kind of things. [37:18.660 --> 37:25.720] And then browser plugin, one of my other friends, he was talking about... [37:25.720 --> 37:33.480] First, we were landing on the idea of, you know, HTTP has deflate, so we can kind of sniff that coming through as a plugin. [37:33.480 --> 37:41.660] But at a browser level, it's kind of, to the best of what we were finding, it doesn't really see it at that layer of abstraction. [37:42.420 --> 37:46.680] So then I guess maybe you'd have to do something like burp and kind of get it at that level. [37:46.800 --> 37:54.580] But if the whole point is usability, well, then having somebody set up burp and then use a custom script, that doesn't work. [37:54.580 --> 38:01.300] But another thing we're thinking that might be possible is just the cached content so that, you know, the PNGs and that kind of stuff. [38:01.500 --> 38:06.400] And by the way, that guy is the one in the black hat over there calling him out, putting the pressure. [38:06.580 --> 38:08.020] You know, he didn't want me to. [38:11.040 --> 38:14.520] But these are the three things that I have looking at going forward. [38:15.660 --> 38:22.260] Beyond that, I'm just going back to this, like I've been throughout the whole talk, just to show these are the tools involved. [38:23.380 --> 38:26.620] And cannibalizing it as the question's last slide. [38:26.780 --> 38:28.560] So that's all the content I have. [38:36.260 --> 38:37.920] And I can do Q&A. [38:39.920 --> 38:40.580] Thank you. [38:40.760 --> 38:44.100] I actually did my graduate thesis on Deflate. [38:44.300 --> 38:47.080] And you just hit a bunch of awesome things. [38:47.260 --> 38:48.640] So, good job. [38:49.780 --> 38:55.100] If you want interesting data sources, have you looked at the hardware compression devices that will do Deflate? [38:55.340 --> 38:57.380] Because they have some interesting characteristics. [38:57.860 --> 38:58.320] No. [38:58.640 --> 38:59.880] Maybe we should talk after. [39:00.080 --> 39:02.820] Because one thing I... you know how I was talking about with gzip and other things? [39:02.880 --> 39:06.360] I was kind of expecting maybe there's a Heartbleed for... [39:06.360 --> 39:08.800] Well, there wasn't not because of Deflate. [39:09.000 --> 39:10.340] It's just implementation-specific. [39:10.600 --> 39:13.640] That's just how gzip handles that illegal distance. [39:13.860 --> 39:16.800] But if somebody else is reinventing the wheel, they might do it differently. [39:16.980 --> 39:18.080] So I am kind of interested. [39:18.260 --> 39:29.960] There's hardware, and then there's... I have not investigated them deeply, but there's a vast number of re-implementations of Deflate, especially for an embedded hardware, which could be an interesting target. [39:29.960 --> 39:35.620] Right, especially because they're going to probably be doing some, you know, savings on code size. [39:35.780 --> 39:37.180] They might be doing some tricks that... [39:37.180 --> 39:38.420] Yeah, I'm interested. [39:38.580 --> 39:39.740] I'm absolutely interested. [39:40.900 --> 39:43.820] I really mean, like, maybe after this, like, I can get some notes from you. [39:44.260 --> 39:44.860] Cool, cool. [39:46.840 --> 39:47.880] Any more questions? [39:49.060 --> 39:49.680] Right here. [39:50.440 --> 39:51.280] Excellent talk. [39:51.440 --> 39:52.960] This is really cool and very educational. [39:53.180 --> 39:56.220] I'm curious, so you start off with the LZ-77 compression algorithm. [39:56.920 --> 40:10.780] I'm curious if you've seen or if you've played around with the LZ-78 or LZW, that I think LZ-78 is, what is it, it builds this dictionary and then it builds a secondary dictionary on top of it and references the second dictionary for repeated instances, and then LZW pre-initializes the dictionary. [40:13.900 --> 40:18.220] And I'm wondering if that might be, like, for Deflate, that might throw some interesting curveballs for it. [40:18.360 --> 40:18.740] Yeah, maybe. [40:18.880 --> 40:19.980] I haven't played with those. [40:20.060 --> 40:20.300] No. [40:20.580 --> 40:20.720] Yeah. [40:21.340 --> 40:22.620] The question was on LZW? [40:23.360 --> 40:26.300] Yeah, if I played with LZW or LZ-78. [40:27.180 --> 40:28.640] Yeah, no, I haven't played with those. [40:29.520 --> 40:29.880] Cool. [40:30.000 --> 40:34.440] Well, for the people that accidentally came in here and weren't interested in compression, we can get 10 minutes back. [40:38.220 --> 40:38.700] Thank you. [40:38.760 --> 40:38.760] Thank you.