[00:11.430 --> 00:13.570] All right, everybody. We are back. [00:13.610 --> 00:18.570] Hello. We are here with the second to last match of the whole tournament. [00:18.570 --> 00:21.590] This is the finals of the lower bracket of the live CTF. [00:21.590 --> 00:23.490] So these are teams who have all lost once. [00:23.490 --> 00:27.230] They are playing back for the chance to come back into the final match, [00:27.230 --> 00:29.550] which will be the very next match that will happen right after this. [00:29.550 --> 00:31.230] Again, I'm CypherTex. [00:31.270 --> 00:32.730] Hello, I'm Zeta2. [00:33.030 --> 00:36.650] And we're looking to see if we're about ready for the countdown. [00:36.650 --> 00:39.570] So let's go ahead and prepare. We're going to count the teams in. [00:39.570 --> 00:41.490] They know it's time to go. [00:42.330 --> 00:46.330] Five, four, three, two, one. [00:46.330 --> 00:47.030] Go. [00:47.030 --> 00:47.890] All right. [00:47.990 --> 00:48.950] All right. [00:49.230 --> 00:51.110] Oh, a quick lead. [00:51.410 --> 00:52.910] Tell Straw Hat. Tell Straw Hat. [00:52.910 --> 00:53.230] Yeah. [00:53.230 --> 00:54.090] There we go. All right. [00:54.090 --> 00:56.390] Okay. We're on. We're on. [00:56.730 --> 00:58.210] Right. So who do you want to look at first? [00:58.450 --> 01:00.790] Let's go with Straw Hat. [01:00.790 --> 01:01.370] All right. [01:01.370 --> 01:04.330] And so, as we said, lower bracket finals. [01:04.330 --> 01:08.770] We have Team Straw Hat versus the Maple Mallard Magistrates, or MMM. [01:08.770 --> 01:09.510] Or Mighty Ducks. [01:09.510 --> 01:10.390] Mighty Ducks. [01:10.390 --> 01:11.550] Or whatever name. [01:11.550 --> 01:13.430] Those people. [01:15.090 --> 01:20.450] And this is, yeah, you know, we're down to the final three teams. [01:20.450 --> 01:25.690] So whoever wins here will go to the grand finals facing off against Hypeboi. [01:26.130 --> 01:28.030] Who's really just had such a run. [01:28.030 --> 01:29.690] This entire tournament, Hypeboi has just been flowing through it. [01:29.790 --> 01:31.810] Really, really impressive. [01:33.190 --> 01:37.390] So we can see here opening up the challenge in Ida. [01:37.570 --> 01:40.670] Doing some analysis here. [01:40.670 --> 01:44.370] But we do actually have Ghidra as well on the other side. [01:44.370 --> 01:44.550] Right. [01:44.550 --> 01:46.630] So this is, I haven't seen a whole lot of other things. [01:46.630 --> 01:47.850] It's been mostly Ida so far. [01:47.850 --> 01:49.050] Mostly Ida. [01:49.290 --> 01:50.650] But we eventually got to Ghidra. [01:50.650 --> 01:52.030] Yep. Yep. [01:52.130 --> 01:55.170] And the way this challenge. [01:55.170 --> 01:56.310] The way this challenge. [01:56.310 --> 01:56.950] Yeah, right, right. [01:56.950 --> 01:57.770] Let's clarify. [01:57.770 --> 01:59.090] What's the name of this challenge? [01:59.090 --> 02:01.210] So this challenge is called The Way. [02:01.210 --> 02:02.010] This is The Way. [02:02.010 --> 02:06.370] It's actually the only challenge that I have created for this event. [02:06.370 --> 02:06.950] I only have one too. [02:06.950 --> 02:08.030] So you did infrastructure. [02:08.030 --> 02:09.090] I did streaming stuff. [02:09.090 --> 02:09.370] Yeah. [02:09.370 --> 02:10.530] So we were busy with other stuff. [02:10.530 --> 02:11.570] But I have one challenge. [02:11.570 --> 02:12.290] And this is the one. [02:12.290 --> 02:13.270] And this is The Way. [02:14.010 --> 02:15.650] And this is a reversing challenge. [02:15.650 --> 02:16.930] We've seen mostly. [02:17.230 --> 02:17.930] Actually, funny. [02:17.930 --> 02:18.590] The two of us. [02:18.590 --> 02:19.970] We made the two reverse. [02:19.970 --> 02:22.570] The two non-pawn challenges in this tournament. [02:22.570 --> 02:22.770] Yeah. [02:22.770 --> 02:24.630] So this is another reversing challenge. [02:25.850 --> 02:28.930] And we can get back a little bit into the details in a bit. [02:28.930 --> 02:31.930] Let's keep looking here at what they're doing. [02:31.930 --> 02:35.910] So MMM is just doing some initial reversing. [02:35.950 --> 02:37.330] Renaming some variables. [02:38.490 --> 02:41.350] We have kept the symbols in this. [02:41.350 --> 02:42.210] We have the function names. [02:42.210 --> 02:43.030] And what do we tell the team? [02:43.030 --> 02:45.790] So we have categories for each of these matches on the bracket. [02:45.790 --> 02:48.830] We told them, in this case, every day the day before. [02:49.670 --> 02:52.170] We told them all of the categories for each of the challenges. [02:52.170 --> 02:54.010] So what do they know about this one? [02:54.010 --> 02:54.290] Right. [02:54.290 --> 02:55.930] So they know that it's a reversing challenge. [02:55.930 --> 02:58.550] And they know that it's around algorithms. [02:58.550 --> 03:01.410] So they were given reverse engineering algorithms. [03:01.410 --> 03:04.170] Did we tell them specifically, I think, Optimize Me, Even Me? [03:04.350 --> 03:09.250] Right. We said Optimize Me, which may be a good time to explain what this is. [03:09.250 --> 03:17.410] So in the reverse engineering category, there are various standard formats of challenges. [03:17.610 --> 03:21.870] Maybe the most commonly known is the Crack Me, where you send in a flag as an input. [03:21.870 --> 03:24.690] And the program will tell you whether it's correct or not. [03:24.690 --> 03:29.530] And you need to work your way backwards from the verifier to figure out what the input should be. [03:29.530 --> 03:30.910] And Optimize Me... [03:30.910 --> 03:32.390] That was what my challenge was, essentially. [03:32.390 --> 03:34.690] It was a bunch of checks. You gave an input. It verified at the end. [03:34.690 --> 03:37.190] You had to reverse those or invert those or solve through those. [03:37.190 --> 03:42.630] So the constraints, they define the unique input that gives the solution. [03:43.250 --> 03:52.270] In the case of an Optimize Me, you have some computation that is implemented in a terribly inefficient way. [03:52.270 --> 03:57.950] So you have a program that usually takes no input, and it just calculates the flag for you. [03:57.950 --> 03:59.110] All you do is just run it. [03:59.110 --> 04:03.430] You run it, except it will take to the end of the universe before the computation finishes. [04:03.470 --> 04:10.930] So you need to understand what the algorithm is trying to do and optimize the computation so that you can actually complete it. [04:10.930 --> 04:14.210] I remember playing back. I think it was Plaid CTF. [04:14.850 --> 04:18.630] Several years ago, it had a whole category that they called their supercomputer category. [04:18.630 --> 04:25.550] And the same idea was that you would need a supercomputer to run this as it is and to get anything out of it. [04:25.550 --> 04:31.750] But you could also be more efficient if you wanted to do it like the algorithmic solution. [04:31.750 --> 04:35.590] So we're expecting them to do just kind of a lot. [04:35.590 --> 04:40.850] There we go. CallMysteryAlgorithm, I think I saw, was the name over on Straw Hat. [04:40.850 --> 04:45.970] So we have this. So there's a bunch in the main function. [04:45.970 --> 04:49.510] We try to separate out the things that they should not care about. [04:49.510 --> 04:50.670] We try to guide them. [04:51.350 --> 04:52.930] Oh, right. This is interesting. [04:56.630 --> 05:02.970] Oh, my God. It's actually making the correct answer. [05:03.230 --> 05:05.070] It doesn't give them the name. [05:05.930 --> 05:10.450] So to explain here, just go back a few steps. [05:10.450 --> 05:13.650] They basically, they're trying to identify what algorithm this is. [05:13.650 --> 05:16.610] And they asked over chat about this. [05:16.610 --> 05:26.050] And you could see there that it said like it's calculating the shortest path from this to this using this. [05:26.050 --> 05:28.230] And this is actually completely correct. [05:28.230 --> 05:32.770] This is the Floyd-Warshall. [05:32.770 --> 05:39.050] It's actually not the Floyd-Warshall algorithm because it's the unoptimized computation. [05:39.050 --> 05:42.690] If they replaced it with the textbook version of the algorithm, that would be... [05:42.690 --> 05:50.470] Right. So this is like when you come up with or when you prove the Floyd-Warshall algorithm, [05:50.470 --> 05:56.950] this is like the recursion relationship you start with and then you turn and use dynamic programming to make it efficient. [05:56.950 --> 06:01.330] This is just a recursion relationship without the dynamic programming applied. [06:01.330 --> 06:05.730] So this has like a time complexity of like 3 to the N or something like this. [06:06.890 --> 06:11.710] So great move. It looks like they got a fantastic hint certainly from chat. [06:12.110 --> 06:19.330] I'm really impressed by this because one of our test solvers actually tried this and they did not get it to work. [06:19.330 --> 06:24.450] Or like they did after like already knowing the solution and kind of like... [06:24.450 --> 06:27.390] So that's really impressive. [06:27.390 --> 06:29.650] Well, that was before you added symbols I believe too maybe, right? [06:29.650 --> 06:36.030] Yeah, but the only symbol that is relevant here is just I called it mystery algorithm. [06:36.030 --> 06:39.710] Oh, right. This is called the getEdge function. That's true. [06:40.170 --> 06:49.210] So I used this helper function to, you know, you have this matrix of like distance from A to B [06:49.210 --> 06:54.450] and just this helper function to give you a pointer to the relevant entry in the matrix. [06:55.590 --> 06:56.910] Yeah, so... [06:56.910 --> 07:00.470] So I think that was... it looks like that may have been just enough to get it to produce it. [07:00.470 --> 07:02.610] And we've actually got... so yeah, you want to go back over to... [07:02.610 --> 07:08.490] Yeah, because I just saw there if we can switch over... we can't see the code yet, but if we switch back to this, I think the... [07:09.190 --> 07:15.470] Yeah, so here is the... this is really cool because this is the other approach you can take to this. [07:15.470 --> 07:24.430] So you can see over on the straw hat side, they were kind of trying to identify the specific algorithm and then use, you know, knowledge... [07:24.430 --> 07:25.890] Go find a textbook version of that or re-implement that, drop it in place. [07:25.890 --> 07:33.210] Right, right, something. But if we go back to MMM, here you can see that the player is re-implementing the function in Python [07:33.210 --> 07:39.750] and you can see this little at cache annotation for the function, which is... [07:39.750 --> 07:46.270] It will, like, look at all the function arguments and then use that as a key and then cache the return value. [07:46.270 --> 07:49.470] Out code those values because it's, you know, fixed input, fixed output. [07:49.470 --> 07:52.070] Exactly, it's a pure function. [07:52.070 --> 07:52.330] Yeah. [07:52.510 --> 08:01.610] So, and this is actually the kind of trick for those who know a little bit about dynamic programming in, like, algorithm construction. [08:02.030 --> 08:05.530] Usually the way you approach is that you start with a recursion [08:05.530 --> 08:11.570] and then you identify that many or most of the various recursive calls actually are the same. [08:11.570 --> 08:12.650] They're, like, a big overlap. [08:12.650 --> 08:15.650] So then you only have to do it once and then you just do a lookup for the remainder. [08:15.650 --> 08:26.790] Right. And then normally, like, if you do it, like, kind of properly, you do it all the way and, like, flip it all around and compute it, like, bottom up. [08:26.850 --> 08:33.010] But you can skip that stuff and keep it as a recursive relationship but add a cache to it. [08:33.010 --> 08:33.450] Interesting. [08:33.450 --> 08:39.670] And so there's literally just an annotation in Python that lets you, like, a decorator that they can add in that says, yeah, please cache this. [08:40.490 --> 08:43.610] It's in the functools library. [08:43.610 --> 08:49.030] I believe you can give it some parameters with, like, the size of the cache and stuff, but I think the default should be plenty enough. [08:49.030 --> 08:49.690] Might actually work well for this. [08:49.690 --> 09:02.150] So if they implement this correctly, they just need to properly translate from the disassemble or the decompile code into the Python and add this annotation and run it and they should get the answer. [09:02.150 --> 09:07.490] And I wonder now if going into this, they specifically chose Ghidra or Ida based on what they knew about the problem, too. [09:07.490 --> 09:13.350] I don't remember if we've seen, I think this was Robert from NNM who's playing, like, have we seen him use one or the other before? [09:13.350 --> 09:18.170] But it could be that he just feels like maybe I've seen better decompilation for very algorithmic things. [09:18.170 --> 09:24.210] And I'm just curious if that factored into it because it is interesting to see that he's doing that approach. [09:24.210 --> 09:28.490] But, yeah, so I love that we've got two kind of very different approaches, each equally viable, right? [09:28.490 --> 09:32.390] Both of these should absolutely be proper ways of solving this problem. [09:32.390 --> 09:33.490] And it kind of makes sense. [09:33.490 --> 09:35.330] They knew the category going into it. [09:35.330 --> 09:36.230] It wasn't a surprise. [09:36.230 --> 09:38.310] And these are sort of standard ways of doing it. [09:38.490 --> 09:39.530] Let's go back and look over. [09:39.530 --> 09:41.170] We've got more chat, GPT from Straw Hat. [09:41.170 --> 09:42.970] Are they just looking up? [09:42.970 --> 09:44.810] Shortest path in a graph. [09:45.990 --> 09:51.850] And you see the keyword here, dynamic programming is a keyword here. [09:52.870 --> 09:59.070] And this function calculates the combined path or cost from A1 to A2 going via A3. [09:59.070 --> 10:00.690] And this is completely correct. [10:00.690 --> 10:02.530] This is exactly what it's doing. [10:02.530 --> 10:04.810] I'm actually kind of blown away. [10:04.810 --> 10:09.070] So I will admit that I'm a little bit of an AI skeptic. [10:09.230 --> 10:12.730] You see a lot of hype and not a lot of... [10:12.730 --> 10:15.470] I believe there's a bit of an overhype. [10:15.470 --> 10:19.090] And especially in these reverse engineering scenarios, [10:19.090 --> 10:22.730] people have been claiming, oh, you can just put the code in here and it will tell you what it is. [10:22.730 --> 10:25.990] And I've been thinking, well, can you actually, though? [10:25.990 --> 10:27.750] But this is really impressive. [10:27.750 --> 10:28.210] Yeah. [10:28.770 --> 10:31.290] So here we can see the big... [10:31.290 --> 10:34.830] This is the matrix of all of the edges and the... [10:34.830 --> 10:40.590] Right, so this is the matrix defining the individual, the cost or the distances between the nodes. [10:40.590 --> 10:43.070] And you have this full FFFF or minus one. [10:43.070 --> 10:48.550] And this is like a marker for there being no edge between those two nodes. [10:48.550 --> 10:51.350] And this is why you had all of those if statements in the algorithm, [10:51.350 --> 10:54.750] where it's checking if it's minus one. [10:56.430 --> 10:58.330] It's a dead end, essentially. [10:58.330 --> 11:03.150] And then I fortunately had to add in a little bit because checking for overflow [11:03.150 --> 11:06.670] when adding two costs together and stuff like this. [11:06.670 --> 11:11.130] So this made the code a tad messier than what it could have been. [11:11.130 --> 11:12.930] So let's talk about the hints we've got. [11:12.930 --> 11:15.150] Because I know a lot of the challenges, the hints have been super useful. [11:15.150 --> 11:17.490] They've really come down and made a difference. [11:18.050 --> 11:21.110] How much hints do we have for them? [11:21.110 --> 11:23.370] Are we just going to tell them the algorithm at some point? [11:23.370 --> 11:25.350] Or what comes through there? [11:25.370 --> 11:27.910] Yeah, I'm trying to remember the exact hint. [11:27.910 --> 11:31.130] But I know that the second hint that they get says, [11:31.130 --> 11:35.350] like, this is an unoptimized version of the Floyd-Werschel shortest path algorithm [11:35.350 --> 11:36.610] or something like this. [11:36.610 --> 11:39.210] So theoretically, we hopefully won't need a sudden death [11:39.210 --> 11:41.030] because if worst case comes to worst, [11:41.030 --> 11:43.010] they should be able to just look up that implementation [11:43.010 --> 11:44.850] of an efficient version of that algorithm. [11:44.850 --> 11:47.310] Right. And if we go back over to MMM here, [11:47.310 --> 11:52.410] you can see the player looking here at this function [11:52.410 --> 11:55.030] called decrypt flag with the solution. [11:55.330 --> 11:59.110] So once they have calculated this whole thing. [11:59.190 --> 12:05.750] So what this algorithm does is that you give it a graph with nodes [12:05.750 --> 12:08.450] and you tell the distance between all the nodes. [12:08.450 --> 12:11.230] And the algorithm will then produce a new matrix [12:11.230 --> 12:16.930] with the total shortest distance from each node to each node. [12:16.930 --> 12:17.170] Oh, wow. [12:17.170 --> 12:20.370] So it fully characterizes every possible path. [12:20.370 --> 12:23.630] Right. I don't know if you have one of those old map book or something [12:23.630 --> 12:26.650] that's saying if you want to travel from this city to this city, [12:26.650 --> 12:27.790] it's this long and so on. [12:27.790 --> 12:29.670] It builds up this matrix. [12:29.730 --> 12:32.850] And then this function, it will just take that whole matrix [12:32.850 --> 12:35.510] and serialize it into a long sequence of bytes [12:35.510 --> 12:39.050] and use that as a decryption key to get the flag. [12:39.170 --> 12:40.690] Okay. So they have to get it perfectly right [12:40.690 --> 12:43.690] because that whole resulting value is... [12:43.690 --> 12:44.950] and it is a deterministic algorithm. [12:44.950 --> 12:47.250] It's not like it's a heuristic that can produce different results. [12:47.250 --> 12:49.590] It is going to be there is one correct answer [12:49.590 --> 12:51.250] and the algorithm will... which makes sense then [12:51.250 --> 12:54.150] because graph traversal, that's a hard problem. [12:54.490 --> 12:57.590] So it makes sense then that this would be done inefficiently, [12:57.590 --> 13:00.290] would not be possible at all in the scope of this. [13:00.290 --> 13:01.730] How long does your solution take to run? [13:01.730 --> 13:02.590] If you have your implementation... [13:03.150 --> 13:05.090] I mean, it's pretty much instant. [13:05.090 --> 13:05.970] Yeah, yeah. [13:05.970 --> 13:08.670] So the algorithm is... [13:08.670 --> 13:09.530] Is it even in Python then? [13:09.530 --> 13:10.490] It's in Python. [13:10.490 --> 13:11.130] Okay. [13:11.130 --> 13:13.350] So it's the optimized version. [13:13.350 --> 13:16.270] So I said the unoptimized version is like 3 to the n, [13:16.270 --> 13:18.930] so exponential, like it goes up completely. [13:18.970 --> 13:23.650] The optimized version is cubic, so n to the power of 3. [13:24.350 --> 13:26.430] There are faster algorithms for this, [13:26.430 --> 13:29.030] but yeah, anyway, this is what we went for. [13:29.670 --> 13:33.170] So, which is still pretty bad for like a polynomial. [13:33.170 --> 13:35.030] Like cubic is still... [13:35.030 --> 13:36.690] How many nodes do we have? [13:36.690 --> 13:40.710] Right, so it's a 50 node, so it's a 50 by 50 grid. [13:40.710 --> 13:43.430] So I made it small enough that, you know, [13:43.430 --> 13:46.830] like 50 cubed is still a very small number. [13:47.670 --> 13:51.970] And you can see there, like you saw on the screen, [13:51.970 --> 13:52.870] that he was running... [13:52.870 --> 13:54.450] Was that running a debugger dumping out things? [13:54.630 --> 13:56.250] I don't think it was a debugger. [13:56.250 --> 13:58.270] He was just, I think he was just running it [13:58.270 --> 14:02.070] and printing values maybe? [14:02.330 --> 14:04.330] Or I'm trying to... [14:04.330 --> 14:07.750] I want to see the terminal output again. [14:09.350 --> 14:11.770] So I haven't seen a whole lot of people [14:11.770 --> 14:13.690] actually writing like scripts for this. [14:13.690 --> 14:15.990] Like all the solutions so far have been standalone scripts [14:15.990 --> 14:17.810] that really haven't interacted directly with the binaries [14:17.810 --> 14:19.730] for the matches I've casted, [14:19.730 --> 14:21.030] so I've definitely missed some of them. [14:21.030 --> 14:25.450] But I'm seeing some IDA API here to pull out the values. [14:26.250 --> 14:27.450] This is kind of interesting. [14:27.450 --> 14:30.310] They are, it seems like they're generating C code [14:31.210 --> 14:32.570] from the Python scripts. [14:32.570 --> 14:33.770] Do you think they're just not convinced [14:33.770 --> 14:35.610] that their implementation is going to be efficient enough? [14:35.610 --> 14:35.730] Yeah. [14:35.730 --> 14:37.690] It's going to lose some native performance out of it probably? [14:37.730 --> 14:42.990] Might be, which is a bit of a premature optimization. [14:43.010 --> 14:43.430] Yeah, yeah. [14:43.450 --> 14:47.030] Get it working first and then decide if you need that, yeah. [14:47.030 --> 14:47.730] Yeah. [14:47.950 --> 14:52.270] I guess the tricky thing here is that [14:53.830 --> 14:57.430] it's kind of hard to tell, [14:59.010 --> 15:01.390] no, actually, he's just doing test values. [15:01.390 --> 15:02.110] That's fine. [15:02.110 --> 15:03.830] So if you don't get the correct answer, [15:03.830 --> 15:07.390] you don't quite know what's wrong. [15:07.470 --> 15:09.550] Because if you have the wrong decryption key, [15:09.550 --> 15:10.590] you will just get garbage. [15:10.590 --> 15:10.930] Right, right. [15:10.930 --> 15:12.090] There's no close. [15:12.090 --> 15:13.410] There's only done and not done. [15:13.410 --> 15:14.290] Yeah, exactly. [15:14.290 --> 15:18.390] Well, I mean, of course, you can always try to convince yourself [15:18.390 --> 15:21.290] that your algorithm is correct by creating a smaller test case [15:21.290 --> 15:23.990] that you can do with pen and paper. [15:24.370 --> 15:26.390] So when I was doing this, when I was implementing this, [15:26.390 --> 15:29.890] I actually had a bug in the code, [15:29.890 --> 15:33.210] and something was off. [15:33.850 --> 15:37.630] And I solved this by having a very small, [15:37.630 --> 15:39.790] like I had a three-by-three matrix or something, [15:39.790 --> 15:42.330] and I worked it out by hand and eventually found [15:42.330 --> 15:46.590] that the Wikipedia article that I was referencing, [15:46.590 --> 15:49.870] they were using one indexing and I was using zero-based indexing. [15:49.870 --> 15:50.470] Ah, that makes sense. [15:50.470 --> 15:50.970] Yeah. [15:52.610 --> 15:53.950] So let's go back to the straw hat. [15:53.950 --> 15:55.710] Just for a second there, they actually, [15:55.710 --> 15:57.350] I've seen two different things that were interesting [15:57.350 --> 15:59.550] for both of the solutions so far. [15:59.570 --> 16:01.870] So if I pull back up their script again, [16:01.870 --> 16:06.870] or maybe we'll have to go back over to MMM. [16:07.110 --> 16:09.310] Yeah, MMM is, if we switch back to MMM, [16:09.310 --> 16:11.730] they are also using ChatGPT. [16:11.730 --> 16:11.990] Ah, there we go. [16:12.350 --> 16:14.910] And then, right. [16:14.910 --> 16:19.530] And this is basically the output that our tester got. [16:19.530 --> 16:20.390] So interesting. [16:20.390 --> 16:20.990] Right. [16:20.990 --> 16:22.270] It's not able to produce now. [16:22.270 --> 16:24.350] They did feed in the output from different decompilers. [16:24.350 --> 16:26.610] So it could be that Ghita's output versus Ida's output [16:26.610 --> 16:28.850] is different enough that we'd have to test that, [16:28.850 --> 16:29.330] go back and watch. [16:29.330 --> 16:30.570] Oh, that's so interesting. [16:30.570 --> 16:32.990] That very small difference in the inputs. [16:32.990 --> 16:35.430] Just the formatting or even the, [16:35.430 --> 16:37.530] these are non-deterministic systems. [16:37.530 --> 16:37.870] Right. [16:37.870 --> 16:43.250] So maybe there is some input training data out there [16:43.250 --> 16:44.350] that just happens to look... [16:44.350 --> 16:45.490] Looks more like this. [16:45.490 --> 16:47.110] Yeah, it's entirely possible. [16:47.390 --> 16:49.410] Which is pretty cool. [16:49.410 --> 16:50.710] That's very interesting. [16:50.710 --> 16:53.330] I think this is the... [16:53.330 --> 16:58.810] We might have seen a little bit of chat GPT in some of the other... [16:58.810 --> 16:59.230] We have. [16:59.230 --> 17:02.030] This one is where it seems to have been actually useful. [17:02.030 --> 17:02.830] Let's look at Straw Hat. [17:02.830 --> 17:04.630] We've actually seen now the output of the script. [17:05.230 --> 17:08.010] So they're actually generating values that they've... [17:08.010 --> 17:09.130] Are these pulling out... [17:09.130 --> 17:11.950] Are they just using this to dump the data? [17:11.990 --> 17:12.710] Yeah. [17:12.710 --> 17:15.130] So the minus one, I think, is the initial state. [17:15.130 --> 17:17.090] So when the algorithm starts, [17:17.090 --> 17:20.230] it creates the memory to hold the results. [17:20.230 --> 17:21.490] Well, I see 50 lines. [17:21.490 --> 17:22.110] So 50 lines. [17:22.110 --> 17:24.250] This is just essentially... [17:24.250 --> 17:28.130] I think they're dumping the raw values of the grid. [17:28.130 --> 17:28.170] Right. [17:28.170 --> 17:31.370] So all the minus one, that's like the initial state [17:31.370 --> 17:33.630] before filling out the values. [17:33.630 --> 17:35.110] Yeah, but so some of the rows were minus ones [17:35.110 --> 17:36.090] and some of the rows were not. [17:36.090 --> 17:38.950] No, no, but there was this big block, right, of minus ones. [17:38.950 --> 17:39.690] And then there's... [17:39.690 --> 17:42.330] So I think in my code that generates the problem, [17:42.330 --> 17:46.810] about every fifth edge is a minus one. [17:47.250 --> 17:48.070] I think that's like... [17:48.070 --> 17:51.590] I randomly generated the input graph. [17:52.330 --> 17:54.530] So, yeah. [17:54.530 --> 17:57.210] Although you can see there in this Google search history, [17:57.210 --> 17:57.850] torque. [17:59.310 --> 18:00.670] Poor CTF players. [18:00.670 --> 18:04.910] In the main event, one of the challenges is a torque 3D engine script. [18:04.910 --> 18:07.410] So I know that a lot of people suddenly became familiar [18:07.410 --> 18:08.270] with the 3D engine. [18:08.270 --> 18:09.730] They weren't beforehand. [18:09.830 --> 18:10.510] Yeah. [18:11.690 --> 18:12.130] And... [18:12.130 --> 18:13.150] Oh, no. [18:13.150 --> 18:14.410] Verify that you are human. [18:14.410 --> 18:15.230] Yeah, I was kidding. [18:15.230 --> 18:16.150] You typed too fast. [18:16.150 --> 18:17.710] We're going to see a capture. [18:17.710 --> 18:18.410] Yeah. [18:18.490 --> 18:20.950] And while we were looking a little bit more into this, [18:23.130 --> 18:25.270] I saw earlier that I was looking... [18:25.270 --> 18:26.050] I was reading the chat. [18:26.050 --> 18:29.890] So, unfortunately, we don't have the YouTube chat in front of us. [18:29.890 --> 18:31.870] But I saw previously looking from the stream [18:31.870 --> 18:34.710] that someone asked about if we could, you know, [18:34.710 --> 18:36.990] explain a little bit more about, like, the setup [18:36.990 --> 18:39.970] and the environment that we have here. [18:41.490 --> 18:41.930] But... [18:41.930 --> 18:45.050] So we have behind us... [18:45.550 --> 18:49.250] Behind this wall, we have the players sitting across each other at a table. [18:49.250 --> 18:52.410] So, like, they are really, like, face-to-face with their laptops. [18:52.410 --> 18:54.430] They are on a isolated... [18:54.430 --> 18:56.270] Well, kind of isolated network. [18:56.270 --> 18:57.570] They can reach the Internet. [18:57.570 --> 19:01.650] They can reach the game servers that we have on that network. [19:02.390 --> 19:04.250] By the way, I want to go back and really get the straw hat [19:04.250 --> 19:07.550] because they just asked ChatGPT to optimize it, [19:07.550 --> 19:09.750] and it used a memo approach, actually. [19:09.750 --> 19:10.750] And it suggested... [19:10.750 --> 19:11.290] Oh, nice. [19:11.870 --> 19:14.750] Suggested essentially doing really what that hash was doing [19:14.750 --> 19:15.670] on the other side in the Python. [19:15.670 --> 19:16.050] Yeah. [19:16.050 --> 19:19.570] But using, like, a massive array instead of, like, a hash table [19:19.570 --> 19:20.830] or something like this. [19:20.950 --> 19:21.330] Right. [19:21.370 --> 19:23.270] So it's kind of a similar concept. [19:23.270 --> 19:24.030] So it is... [19:24.030 --> 19:27.530] I've got to say the ChatGPT hints that Straw Hat's getting out [19:27.530 --> 19:28.350] seem to be pretty good. [19:28.350 --> 19:30.470] They're, like, certainly not bad advice, bad ideas. [19:30.470 --> 19:31.790] No, it's very valid. [19:31.790 --> 19:35.210] And if we go over to MMM, I saw... [19:35.790 --> 19:37.750] Let's see if we can get this again. [19:37.750 --> 19:43.830] You can see there in the terminal there was a lot of, like... [19:43.830 --> 19:45.910] It was running it in a debugger. [19:45.910 --> 19:47.690] Okay, so that was a debugger we saw earlier. [19:47.690 --> 19:51.610] And I think he's, like, validating that his... [19:51.610 --> 19:54.750] Well, this is, you know, a little bit of speculation from my side, [19:54.750 --> 19:55.770] but this is what I would do. [19:55.770 --> 20:00.510] Like, even though the calculation that's being done in the program, [20:00.510 --> 20:03.910] even though it's slow, you can probably still, like, do a little bit [20:03.910 --> 20:07.270] of debugging and just checking that, like, things are, like, [20:07.270 --> 20:08.430] agreeing with your values. [20:08.430 --> 20:10.450] Your first couple of results of calculation maybe. [20:10.450 --> 20:12.550] I was going to ask earlier if the problem is dividable enough [20:12.550 --> 20:13.370] that you could do that. [20:13.370 --> 20:16.370] So you can go... I think you can... [20:16.370 --> 20:19.350] Yeah, yeah, I think you can bottom out in, like, one branch [20:19.350 --> 20:21.190] and get that result. [20:21.190 --> 20:22.410] And then just compare it to what you have. [20:22.410 --> 20:25.590] Yeah, so you can get a little bit of information out to do a little bit [20:25.590 --> 20:26.090] of validation. [20:26.090 --> 20:28.410] By the way, Newbie Edge on the chat, thank you for chiming in. [20:28.410 --> 20:32.310] We did pull that up now, pointed out that we've got chat GPT-3 [20:32.310 --> 20:33.750] and chat GPT-4. [20:33.750 --> 20:39.090] So MMM is using GPT-3.5, and we've got Straw Hat using 4. [20:39.090 --> 20:40.090] 3.5. [20:40.170 --> 20:42.730] Yeah, so we've got MMM using 3.5. [20:42.730 --> 20:45.150] And we've got Straw Hat using GPT-4. [20:45.150 --> 20:47.470] So it is entirely possible that's actually just the difference [20:47.470 --> 20:49.690] in terms of which version they were using. [20:49.690 --> 20:51.090] Oh, that's really cool. [20:51.530 --> 20:54.490] Newbie Edge, by the way, is one of the players in Norse Code [20:54.490 --> 20:56.130] who did play a match earlier. [20:56.210 --> 21:00.310] Unfortunately lost to MMM, but they did really well [21:00.310 --> 21:01.210] in the tournament. [21:01.210 --> 21:02.990] Had a really great run there. [21:02.990 --> 21:05.050] Well, they can take some pleasure in knowing that the person [21:05.050 --> 21:07.490] that defeated them is being stumped by the old version [21:07.490 --> 21:09.250] that they caught on stream. [21:09.250 --> 21:10.650] They saw the difference. [21:10.650 --> 21:11.230] Thank you for pointing that out. [21:11.230 --> 21:16.110] So here we do see the debugger and checking some value, [21:16.110 --> 21:19.470] dumping out some memory of this. [21:19.870 --> 21:20.230] Oh, right. [21:20.230 --> 21:22.210] So here we also see a dump of this. [21:22.330 --> 21:26.470] So W is the name of the table with all the edges. [21:26.470 --> 21:29.130] So this is what's being dumped out here. [21:29.590 --> 21:31.430] Even just having symbols helps with that too [21:31.430 --> 21:32.850] when you're in the debugger and you've got symbols, [21:32.850 --> 21:34.710] being able to global variable names and whatnot [21:34.710 --> 21:36.450] is a nice convenience. [21:36.450 --> 21:38.450] So I did a little bit of a give and take. [21:38.450 --> 21:44.830] So we made it a little bit easier where we kept the symbols, [21:44.830 --> 21:46.390] but I did choose to... [21:46.390 --> 21:49.190] So that variable was initially called distance matrix [21:49.190 --> 21:50.450] or something like this. [21:50.450 --> 21:52.210] So I did choose to just... [21:52.210 --> 21:54.290] A couple of things were sort of anonymized a little bit. [21:54.470 --> 21:56.590] So the algorithm is called mystery algorithm [21:56.590 --> 21:57.950] instead of the actual name. [21:57.950 --> 22:01.230] The table is called just W instead of distance matrix. [22:01.230 --> 22:03.830] And then they get all the other symbols to tell them, [22:03.830 --> 22:06.310] hey, you don't really need to look at these other functions. [22:06.730 --> 22:08.310] So we are seeing... [22:08.830 --> 22:12.350] They both feel like they've got... [22:12.770 --> 22:16.050] Certainly the beginnings of code, they could be doing this. [22:17.290 --> 22:18.410] But let's see. [22:18.410 --> 22:20.410] So again, we went with the C approach. [22:20.410 --> 22:23.050] Now we've got to fix up all the errors from our auto-generated code [22:23.550 --> 22:30.210] in our chat GPG output that are not valid C potentially. [22:30.290 --> 22:32.030] But that looks a little bit like IDA output actually [22:32.030 --> 22:33.930] with the comments, with the stack. [22:33.930 --> 22:37.850] Well, they generated it from an IDA script. [22:37.850 --> 22:41.870] So their IDA Python script actually generated both the header file [22:41.870 --> 22:44.150] that they're using, that W dot H is literally just W. [22:44.150 --> 22:46.110] So those are the values that they dump from there. [22:46.230 --> 22:48.330] Although again, I am thinking about this though. [22:48.330 --> 22:51.130] You said about every fifth edge was negative one. [22:51.130 --> 22:55.590] But we saw in that W dot H a bunch of rows of all negative ones. [22:55.590 --> 22:58.690] What I think it was was that they dumped stuff in the debugger. [22:58.930 --> 23:01.850] So the big thing with all the minus one, [23:01.850 --> 23:05.870] that's if you would dump the kind of the state variable [23:05.870 --> 23:08.890] before it goes into the algorithm. [23:09.630 --> 23:10.990] Or they just made a mistake. [23:10.990 --> 23:13.010] But there's no reason they should have received that. [23:13.010 --> 23:14.610] It should be pretty straightforward, yeah. [23:14.990 --> 23:18.790] So I think that was just a, you know, we kind of misread that, I think. [23:18.930 --> 23:20.450] Could be. We'll have to see if it comes back up again. [23:25.150 --> 23:28.190] Let's move over to MMM. [23:28.190 --> 23:31.410] And we can see there is like some calculations going on. [23:31.950 --> 23:34.410] In the background. [23:34.410 --> 23:37.210] And you can see it looks like this is going. [23:37.210 --> 23:39.610] So you see kind of these pairs of numbers. [23:39.810 --> 23:41.050] One is going pretty fast. [23:41.050 --> 23:44.150] And then one is taking up 15 and so on. [23:44.610 --> 23:47.250] That's actually a counter. That could be pretty close to itself. [23:47.250 --> 23:49.470] And I will say earlier they had an RC4 script. [23:49.470 --> 23:52.510] They were already pulling it there to say they copied and pasted their RC4. [23:54.270 --> 23:56.390] So they've got the code. [23:56.390 --> 23:59.410] I mean, it's entirely possible that this is a working solution. [23:59.410 --> 24:01.530] We won't really know, just like they won't, until they run it right. [24:01.530 --> 24:02.290] As you were saying earlier. [24:02.290 --> 24:05.870] And then, of course, you also have to be very careful here how you... [24:05.870 --> 24:10.210] So in Python, because you have these S integers and you need to pack them, [24:10.210 --> 24:13.850] you know, make sure you get the ndns correct there. [24:14.510 --> 24:15.990] There's a lot of little fiddly bits. [24:16.250 --> 24:17.510] Yeah, this is like the... [24:18.090 --> 24:19.330] Oh, there's the flag. [24:19.330 --> 24:19.910] That's the flag. [24:19.910 --> 24:20.690] Yeah, yeah, yeah. [24:20.810 --> 24:25.250] So now it just needs to connect to the server and submit this. [24:25.290 --> 24:28.650] And that's the solution. [24:28.650 --> 24:30.110] That is it. Congratulations. [24:30.370 --> 24:34.490] We've got a win from MMM right their way into the final. [24:34.490 --> 24:35.890] Really well done. [24:36.530 --> 24:38.210] All right, let them know we've got a winner. [24:38.210 --> 24:40.070] Yeah, that's really, really cool. [24:40.410 --> 24:41.830] Yeah, that was impressive. [24:41.830 --> 24:44.890] I think it was really cool to see both the different approaches. [24:44.890 --> 24:46.410] It was cool to see... [24:46.410 --> 24:53.670] I mean, I will admit, even though, you know, my skepticism, it was cool to see it did work, even though they didn't win. [24:53.670 --> 24:57.170] I think just the speed of it came down, so they just kind of got beat on speed. [24:57.170 --> 24:58.590] But the approach was sound. [24:58.590 --> 25:02.690] And they may not have even honestly been that far off just looking at where they were and looking at what they had done. [25:02.690 --> 25:03.490] No, totally. [25:04.850 --> 25:10.030] So, yeah, I think... I don't know if there is anything else to add at the moment. [25:10.030 --> 25:10.750] Not for this round. [25:10.750 --> 25:15.010] So just as a reminder for the bracket for folks, this now is one match left. [25:15.010 --> 25:16.230] We have the final event. [25:16.230 --> 25:26.110] The teams that score, the number one team, the individual scores for their team will be getting 1,337 points in the main CTF. [25:26.110 --> 25:28.730] So I think, though, they've blacked out the scoreboard. [25:28.730 --> 25:33.590] They've brought us actually up on the projector just now to see the end of the game. [25:33.590 --> 25:38.910] So for this last match, if you're in the Capture the Flag room, we'll be showing the match in here. [25:38.910 --> 25:39.730] All the teams will be done. [25:39.730 --> 25:44.650] Because our last match happens in 30 minutes, which is actually after the main CTF ends. [25:44.650 --> 25:48.110] So it is the last possible points you can score for your team. [25:48.470 --> 25:51.030] Although I think MMM had a pretty solid lead yesterday. [25:51.030 --> 25:52.450] So depending on what happened today... [25:52.450 --> 25:54.490] Yeah, they are in a very good spot. [25:54.510 --> 25:55.910] Also, they are in the Grand Finals here. [25:55.910 --> 25:58.510] So even... I mean, of course, you know, of course you want to win. [25:58.550 --> 26:01.310] But even if they lose, they still get a good amount of points. [26:01.310 --> 26:02.910] I think the difference between 1 and 2 here... [26:02.910 --> 26:05.770] And again, I don't remember where Straw Hat was on the scoreboard before it... [26:05.770 --> 26:07.570] They were in a good position, but... [26:07.570 --> 26:09.310] Yeah, they may have been like 4th or 3rd or so. [26:09.350 --> 26:11.390] So they're both, you know, kind of solid teams. [26:11.390 --> 26:15.570] But really what would have mattered is one of the 2nd or 3rd place teams that was behind MMM at the time. [26:15.570 --> 26:18.710] If they had come into 1st and MMM had ended up last... [26:18.710 --> 26:21.350] That's really where you might have seen Live CTF impact the main event. [26:21.350 --> 26:22.830] But it's unlikely. [26:22.830 --> 26:24.890] That said, I'm really excited to see DRAMA. [26:24.890 --> 26:28.230] We've got a really fun challenge, I think, for the Finals. [26:28.230 --> 26:31.350] I'm looking forward to seeing how teams approach it. [26:31.350 --> 26:32.250] It's going to be really cool. [26:32.250 --> 26:36.590] So we will have the Grand Finals of the Live CTF coming up in about 30 minutes. [26:36.590 --> 26:40.690] We will have MMM against Hypeboy. [26:40.690 --> 26:43.710] It's going to be a really cool match. [26:43.950 --> 26:46.130] And yeah, looking forward to it. [26:46.130 --> 26:48.630] So we will be back in about 30 minutes. [26:48.630 --> 26:49.450] We'll see you then. Take care. [26:49.450 --> 26:49.850] Bye.