WEBVTT

00:00.000 --> 00:03.720
Good morning

00:25.060 --> 00:26.020
and welcome back.

00:26.020 --> 00:28.680
We're here with live CTF day 2.

00:28.680 --> 00:29.480
I'm Mark.

00:29.480 --> 00:30.680
I'm Josh.

00:30.680 --> 00:35.360
And we're bringing to you the first of day 2 here.

00:35.360 --> 00:39.480
We've got two matches, head-to-head going on behind this wall.

00:39.480 --> 00:40.960
Speed match.

00:40.960 --> 00:45.640
We're looking at... we're going to have Undefined versus BlueWater on screen.

00:45.640 --> 00:50.260
And then we're going to have... SuperDiceCode versus NorseCode off screen.

00:50.260 --> 00:51.820
Now we're in the lower bracket here.

00:51.820 --> 00:52.900
Sorry to cut you off.

00:52.900 --> 00:54.380
But we're in lower bracket here.

00:54.380 --> 00:56.780
So a team that loses this is out.

00:56.780 --> 00:58.420
They're out of the entire bracket.

00:58.420 --> 00:59.780
Yeah, a lot of pressure is on.

00:59.780 --> 01:03.380
But we've got a good challenge cooked up for them and I think we're ready to start.

01:03.460 --> 01:09.700
I think we're good to go, except our production team has now turned into ghosts or are hiding.

01:09.700 --> 01:10.640
But we're good to go.

01:10.640 --> 01:12.100
We're good to go, so let's count it down.

01:12.100 --> 01:12.860
Yeah, together.

01:13.480 --> 01:17.600
5, 4, 3, 2, 1.

01:17.600 --> 01:18.640
Let's go.

01:18.640 --> 01:23.640
All right, and bear with us here as we figure out...

01:27.640 --> 01:29.100
There we go.

01:29.100 --> 01:31.900
All right, and so we're watching Undefined first.

01:32.320 --> 01:33.780
All right, Undefined.

01:33.780 --> 01:36.340
And so this challenge is called Jammer.

01:36.340 --> 01:44.680
And this is a special one because it's another throwback challenge to a time when things were a bit simpler, you know?

01:44.680 --> 01:46.060
Ah, better times.

01:46.060 --> 01:48.240
Yeah, really the golden age for vulnerabilities.

01:48.240 --> 01:50.600
But this is a stack buffer overflow.

01:50.840 --> 01:52.520
First Ghidra.

01:53.480 --> 02:01.480
Yeah, I think someone noted in the comments yesterday that it was 7 out of 8 teams that they watched had Ida and one Ghidra user.

02:01.480 --> 02:04.000
So I really like to see the variety.

02:04.000 --> 02:10.240
Yeah, we're starting off with Ida versus Ghidra battle of the second and third best reverse engineering tools.

02:10.240 --> 02:15.340
Yeah, you know, I'm a Binary Ninja fan myself, but...

02:15.840 --> 02:17.540
I'm a Binary Ninja dev myself.

02:17.540 --> 02:21.640
People use what they're used to and they're definitely all going to be...

02:21.640 --> 02:22.140
Absolutely.

02:22.140 --> 02:24.700
The best tool is the one you can use effectively.

02:24.700 --> 02:25.380
Exactly.

02:25.380 --> 02:28.240
And people do get really good at using their favorite.

02:28.620 --> 02:29.740
So let's...

02:29.740 --> 02:33.920
So, okay, we see again two different approaches here.

02:33.920 --> 02:37.680
We see Undefined going with...

02:37.680 --> 02:39.320
That's us.

02:40.140 --> 02:41.660
Team 2 overlay.

02:45.150 --> 02:47.390
All right, so we see Undefined.

02:47.390 --> 02:53.430
They started out a little bit doing, whatchamacallit, dynamic analysis.

02:53.430 --> 02:56.210
Just interacting with the program, seeing what it looks like.

02:56.210 --> 03:01.390
And now they're hopping back into Ghidra, trying to figure out where interaction starts, where they can go.

03:01.690 --> 03:03.190
What is this challenge?

03:03.190 --> 03:04.430
You wrote this challenge.

03:04.790 --> 03:06.670
Right, well, yes, I did.

03:06.730 --> 03:09.270
And this is, as I said, a throwback challenge.

03:09.270 --> 03:15.170
This is a challenge that was originally written for the DARPA Cyber Grand Challenge in 2016.

03:15.170 --> 03:15.610
Really ?

03:15.610 --> 03:19.210
Yes, so it's a rematch of a rematch challenge, really.

03:19.330 --> 03:19.570
Nice.

03:19.570 --> 03:22.990
So shout out to Debbie Nuttall, who was the original author of the challenge.

03:22.990 --> 03:26.790
And I lightly modified it so it would fit for our scope here.

03:27.670 --> 03:33.530
But it is a throwback to a bug from 2002.

03:33.530 --> 03:35.870
If you remember the sequel, Slammer Worm?

03:36.350 --> 03:37.430
Slammer Worm?

03:37.430 --> 03:39.170
No, I don't think I was around for that one.

03:39.170 --> 03:46.770
Yeah, yeah, so early in 2003 is when sequel Slammer was taken over the internet.

03:46.770 --> 03:51.310
And so this is a stack-based buffer overflow, a classic stir copy.

03:51.310 --> 03:55.350
And so I think here what we're really going to be looking for is how fast can they find that?

03:55.610 --> 03:58.510
Slammer Jammer, I just got the, I like it.

03:58.970 --> 04:00.590
We're very clever here.

04:01.170 --> 04:03.230
So I was the one that verified this challenge.

04:03.230 --> 04:09.990
So I can say going from zero knowledge to a full solution on this challenge, it was pretty clean.

04:09.990 --> 04:17.410
You know, you figure an interaction flow with the program, and then you start building an idea of what to do, I want to say.

04:17.410 --> 04:19.410
Like, you're not lost in the sauce.

04:19.410 --> 04:23.130
Yeah, yeah, and it is, you know, a simplified challenge.

04:23.130 --> 04:37.630
The DARPA Cyber Grand Challenge was built to be, these challenges were built to be analyzed by automated competitors, which I think is funny because it's like the biggest data set ever produced to be looked at by machines, right?

04:37.730 --> 04:42.670
And so let's see how fast our competitors can figure this one out.

04:42.670 --> 04:51.260
So let's switch over and look at Blue Water here.

04:54.150 --> 05:00.350
All right, so they're going through, now this binary isn't stripped, is it?

05:00.350 --> 05:01.190
No.

05:01.190 --> 05:03.750
Okay, so they have some symbols to work with in the beginning.

05:03.990 --> 05:06.430
So they're going through, they're annotating different structs.

05:06.850 --> 05:14.070
And they're kind of figuring out, okay, so they're building a struct just called instance, and I think that's returned by create instance.

05:14.110 --> 05:19.390
So the names of these functions really do help you out with your first initial look around.

05:19.930 --> 05:27.270
Yeah, and so what's interesting with this is that we're actually seeing both competitors digging into the structs right away.

05:27.270 --> 05:35.950
And this is an interesting one because there's a decent bit here, but actually the vulnerability itself doesn't require any knowledge of the structure.

05:35.950 --> 05:36.690
Really?

05:36.690 --> 05:37.530
Oh, you're right.

05:37.530 --> 05:39.770
It's just a stack-based str copy.

05:39.770 --> 05:42.450
So a classic bug, very simple.

05:42.450 --> 05:46.610
And really the challenge here, because it's a speed race, is who can find it and exploit it faster?

05:46.610 --> 05:49.330
So this is kind of a reverse engineering pwn challenge.

05:49.330 --> 05:53.870
Like you need to find the right area first, obviously recognize the bug.

05:53.870 --> 05:59.210
But then popping a shell after that is, these guys should be used to it.

05:59.210 --> 05:59.810
Right, right.

05:59.810 --> 06:08.490
And so that's one of the things that I enjoy about this challenge in particular with the speed challenges is you just have to win first.

06:08.490 --> 06:18.650
And so one strategy, which I'm not seeing either competitor do, is to look at the key functions that might be the fast win functions.

06:18.650 --> 06:23.410
So you can see a reference on BlueWater's screen here.

06:23.410 --> 06:26.610
On the left-hand side you see the list of imports and you see str copy there.

06:26.690 --> 06:29.130
And str copy can be innocuous.

06:29.270 --> 06:31.650
Yeah, but do you see a stern copy and a str copy?

06:31.650 --> 06:35.310
I kind of raised an eyebrow at that and I'm like, the author left this in.

06:35.510 --> 06:36.110
That's true.

06:36.110 --> 06:41.050
And especially whenever you're dealing with strings in C code, you have to be careful.

06:41.050 --> 06:45.210
And so you want to, it's always reasonable to take a quick peek at those and see where it gets used.

06:45.210 --> 06:45.870
Oh, yeah.

06:45.870 --> 06:48.710
For as much flack as I give Go, they do strings better.

06:49.890 --> 06:52.270
I think C sets a pretty low bar.

06:52.450 --> 06:53.690
Yeah, maybe.

06:54.630 --> 06:55.390
What are you talking about?

06:55.390 --> 06:58.610
I'll never bash fgets.

06:59.930 --> 07:04.210
You know, as a friend of mine likes to say, no, I love C.

07:04.370 --> 07:06.470
I like bugs and I don't want it to go away.

07:06.470 --> 07:07.330
Yeah, I love C.

07:07.330 --> 07:08.150
I love my job.

07:10.190 --> 07:12.170
All right, so we see...

07:12.170 --> 07:13.710
Let's flip over here.

07:13.710 --> 07:14.530
Nope.

07:14.910 --> 07:16.870
Just hit this one right here.

07:17.330 --> 07:18.190
Just this.

07:18.910 --> 07:21.970
Yeah, no, we have a fancy new stream set up for day two.

07:21.970 --> 07:27.670
Jordan was here late and early setting stuff up, moving stuff around, so we have no idea what we're working with anymore.

07:27.670 --> 07:28.610
Thank you.

07:28.610 --> 07:32.650
I have to say it's very impressive and I'm very bad at using it so far, but we'll get there.

07:32.650 --> 07:34.010
It's the first match of the day.

07:34.010 --> 07:35.850
We're how many minutes in?

07:35.850 --> 07:36.070
Yeah.

07:36.070 --> 07:36.890
A couple.

07:37.170 --> 07:42.970
So as our competitors are digging into it here, they're doing the standard reverse engineering.

07:42.970 --> 07:45.330
Do you want to take a look at the bracket and sort of...

07:46.010 --> 07:48.590
Yeah, we can talk about the bracket, what we're going to see today.

07:48.590 --> 07:49.130
Yeah.

07:52.500 --> 07:57.440
So we've got, as you can see, it's a double elimination bracket.

07:57.440 --> 08:00.660
And so this was a number one feedback from last year, right?

08:00.660 --> 08:01.520
Oh, absolutely.

08:01.520 --> 08:04.220
Teams were upset that they got a challenge they weren't familiar with.

08:04.220 --> 08:08.120
We didn't tell them the categories last year either, which was an oversight on our part.

08:08.260 --> 08:10.580
But you were out after one match last year.

08:10.580 --> 08:14.420
And that was absolutely... we got feedback saying this is absolutely not what we want to do.

08:14.420 --> 08:16.500
That's so unfair and stressful.

08:16.500 --> 08:21.400
So it's a double elimination bracket this year, which means a lot more work for us, but a lot more fair for the teams.

08:21.400 --> 08:23.660
And honestly, that's a good tradeoff as far as we're concerned.

08:23.660 --> 08:29.160
Yeah, it's really good to see that because you can be really, really good.

08:29.240 --> 08:36.700
And as we said, sometimes you just notice something that your competitor doesn't and that can get you ahead real fast.

08:37.000 --> 08:37.560
Absolutely.

08:37.560 --> 08:43.240
And all these players are good, so we do want to see the best player come out on top.

08:46.500 --> 08:49.460
So switching over to Undefined.

08:51.080 --> 08:52.740
Let's see, what are they doing?

08:52.740 --> 08:54.820
Oh, that's... see, I don't use Ghidra.

08:54.820 --> 08:59.580
So all of these UIs are new to me, but they also look like they were before my time.

09:00.060 --> 09:03.480
Yeah, well, Ghidra... I mean, it's an impressive tool.

09:03.480 --> 09:07.840
You can do so much with it, and it is not my go-to, but their struct editor...

09:07.840 --> 09:13.820
I like the visual of the sizing going on and being able to pick out specific stuff.

09:13.820 --> 09:15.260
Oh, that's what that is down there.

09:15.320 --> 09:16.220
That's nice.

09:16.220 --> 09:17.340
Yeah, I like that.

09:18.320 --> 09:20.080
I'm not stealing ideas here.

09:20.160 --> 09:20.900
Yeah.

09:21.620 --> 09:23.060
Scoping out the competition.

09:23.340 --> 09:28.240
I got to say, though, with both Ida and Ghidra, I'm not a light theme guy.

09:28.240 --> 09:29.680
I really do prefer the dark theme.

09:29.680 --> 09:34.100
I definitely don't appreciate having two monitors with light themes blasting into our eyes.

09:34.100 --> 09:36.400
It's brighter than the studio lights we have here.

09:36.440 --> 09:38.080
It's definitely good to wake you up, though.

09:38.080 --> 09:39.400
Oh, absolutely.

09:39.400 --> 09:41.000
The coffee wasn't enough.

09:41.520 --> 09:43.280
All right, so they're still annotating strokes.

09:43.280 --> 09:44.520
They're still going through...

09:45.680 --> 09:51.140
They're kind of going through the normal CTF mindset of, OK, get all of my bearings, figure out what's going on.

09:51.140 --> 09:53.780
Then we look for the bug once I know what everything is.

09:53.960 --> 09:59.660
Yeah, well, once you've got a decent bit of annotation here, I really do think that the bug's going to pop out.

09:59.660 --> 10:03.840
And this isn't just, hey, I'm going to go through and name everything.

10:03.840 --> 10:07.620
It's also they're understanding the algorithm as they name things.

10:07.620 --> 10:11.900
And so right now they're looking at strcmp and thinking about, OK, what does this do?

10:11.900 --> 10:18.040
I think if you were taking this approach and you get to the target function with the strcpy, it's going to pop right out.

10:18.040 --> 10:18.600
Oh, yeah.

10:18.600 --> 10:20.280
No, you're going to see that immediately.

10:22.340 --> 10:25.560
Especially because... So what is kind of this challenge?

10:25.560 --> 10:29.680
Like, in a nutshell, what does the interaction flow look like?

10:29.680 --> 10:31.080
What is it supposed to be?

10:31.080 --> 10:39.660
Yeah, so as we're seeing here, both competitors looking at these functions are talking about querying and servers.

10:39.660 --> 10:44.100
So this is an address resolution service was the sort of origin of the bug.

10:44.100 --> 10:49.920
And the CGC challenge called itself server resolution service.

10:49.920 --> 10:57.380
So really this is about, hey, can you create a query to enumerate these instances and find things?

10:57.600 --> 11:05.360
And it's just copying one of these fields to another in a request leads to an overflow.

11:06.900 --> 11:07.360
Nice.

11:07.360 --> 11:07.580
Yeah.

11:07.580 --> 11:12.820
So it's a fairly standard service interaction flow, I want to say.

11:12.820 --> 11:15.120
You have creation.

11:15.120 --> 11:15.960
You have querying.

11:15.960 --> 11:17.400
I don't think you have any deletion here.

11:17.400 --> 11:20.680
So it's not going to be like a false double free or something.

11:21.260 --> 11:23.260
Oh yeah, I don't see free in the function list.

11:26.800 --> 11:29.660
I'm going to flip over to Bluewater here.

11:29.680 --> 11:32.160
It looks like they are... I see them.

11:32.160 --> 11:35.120
They just labeled something in a stir copy right there.

11:37.560 --> 11:43.540
It's funny when you see somebody and you know they're close and you're starting to see as he's clicking around.

11:43.540 --> 11:45.760
Oh, he's looking right at the stir copy.

11:45.760 --> 11:47.020
Oh, is he?

11:47.020 --> 11:48.780
Oh, he sees that it's a stack.

11:48.780 --> 11:49.840
He sees it.

11:49.840 --> 11:51.760
I think that we're seeing...

11:53.300 --> 11:54.600
Immediately back to the terminal.

11:54.600 --> 11:57.580
When they flip back to the terminal after that.

11:57.780 --> 12:00.920
Check sec, no railroad, NX disabled, no canary, no pie.

12:00.920 --> 12:02.740
I think he sees his path now.

12:03.280 --> 12:06.700
Yeah, I think he's just like, oh my god, I spent all of that time.

12:06.840 --> 12:15.300
Yeah, well, but also there's a lot of excitement because he's just had a breakthrough and he just wants to know how close is the other competitor.

12:15.300 --> 12:18.000
Oh, yeah, he has no idea if they've already found the bug.

12:18.000 --> 12:20.620
If they're building a ROP chain, there's no NX.

12:20.620 --> 12:22.340
I don't know why.

12:22.340 --> 12:26.260
ROP chains, there's always ROP chains when you have no NX.

12:26.360 --> 12:27.980
I think it's just practice.

12:28.140 --> 12:31.660
And especially there's no ASLR in play.

12:31.780 --> 12:37.960
Do you really think that's faster than just, you know, finding one call or like pop call gadget?

12:38.520 --> 12:44.400
Yeah, and if I recall this one, there is a friendly gadget.

12:44.400 --> 12:46.640
Yes, there's a very friendly gadget.

12:46.860 --> 12:51.280
When I verified this challenge, I sent my solution and I looked at the source like, oh, what does this look like?

12:51.280 --> 12:54.360
And I see a comment on it saying, we left this here to be nice.

12:54.540 --> 13:05.780
Yeah, well, like I said, there's a little modification because we really don't want to beat the players up with things that aren't really the core bug here.

13:05.780 --> 13:07.300
And we want this to go fast.

13:07.300 --> 13:09.560
Yeah, these challenges are meant to be solved.

13:09.560 --> 13:11.680
So the challenge is finding the bug.

13:11.680 --> 13:15.800
We might give you, you know, an easy primitive or two to just kind of facilitate.

13:15.800 --> 13:19.080
So you don't need to search the entire binary space, binary search, if you will.

13:19.540 --> 13:22.320
And, you know, find the right primitive to use here.

13:22.320 --> 13:23.840
We just kind of lay it out for you.

13:24.460 --> 13:28.820
Yeah, and it's a line to walk when you're designing challenges.

13:28.920 --> 13:30.740
How easy do you want to make?

13:30.740 --> 13:33.200
What is the real challenge that you want them to solve?

13:33.200 --> 13:43.820
And in this case, it was really just finding that stir copy, understanding what you've got on your hands, understanding the mitigations, and then writing your exploit.

13:44.120 --> 13:46.340
Yeah, so now they're going.

13:46.940 --> 13:52.240
BlueWater is going to be stepping through, figuring out their offsets, and starting to write their exploit.

13:52.240 --> 13:54.300
What is Undefined doing right about now?

13:54.400 --> 13:55.520
Yeah, let's flip over and see.

13:55.520 --> 14:03.560
It looks like they're reversing in the main function, so they're exploring sort of the switch statement that...

14:03.560 --> 14:09.940
This is almost a menu sort of setup, where you've got a switch statement that handles the different kinds of requests.

14:10.180 --> 14:11.520
And there's not a lot, right?

14:11.900 --> 14:20.600
Originally, in the CGC version, there was more stuff, and we kind of commented that out because we didn't want the competitors to have to spend all their time just sort of digging through, you know?

14:20.600 --> 14:21.360
Yeah.

14:22.220 --> 14:29.800
And it looks like Undefined hasn't reached the area of code with the stir copy yet.

14:30.080 --> 14:32.000
Right, they're still labeling.

14:32.000 --> 14:33.740
They're building their understanding.

14:33.980 --> 14:41.540
Now, this might help them in the long run, if they know offsets better, because it looks like BlueWater is over there calculating offsets.

14:41.540 --> 14:52.360
And you can tell, based on what they're looking at, that they're real concerned about linked lists, which are a common source of bugs, mishandling linked lists.

14:52.380 --> 14:54.200
Not in this case, though.

14:55.600 --> 15:05.160
And I think that this is kind of an interesting thing to talk about, because in the CGC, you had these automated competitors that they aren't looking at the binary, right?

15:05.160 --> 15:05.480
Yeah.

15:05.480 --> 15:08.220
They're not reversing or annotating.

15:08.220 --> 15:17.140
They were fuzzing and doing symbolic execution, but they can cover a lot of ground, whereas our competitors here are having to manually reverse engineer and find bugs.

15:17.140 --> 15:20.640
As good as you are, you're, at the end of the day, only one person.

15:20.640 --> 15:21.620
That's true.

15:21.620 --> 15:30.840
I have been hoping to see somebody pull out, you know, a fuzzer or some other extra tooling to try to overcome this.

15:30.840 --> 15:32.260
Oh, I'm really looking forward to it.

15:32.260 --> 15:35.480
But it looks like teams are going to the basics, what they can do the fastest.

15:36.280 --> 15:43.280
And that looks like, you know, GDB with whatever fancy wrapper they want to put on it, Geph or Pwnbag or PETA.

15:45.120 --> 15:47.320
IDA, Ghidra, no Binge yet.

15:47.700 --> 15:48.340
Sad.

15:48.600 --> 15:52.740
But they're going with what they know and what they've been using for the longest time.

15:52.740 --> 16:03.460
Yeah, and I think that the discussion really is, if you have to solve something in only 20, 30 minutes, do you have time to work with something like an anger?

16:03.460 --> 16:04.760
Like, you have to be really practiced.

16:04.760 --> 16:08.560
And there's still a little, you know, finesse involved, unless it pops the answer right out.

16:08.560 --> 16:08.880
Yeah.

16:08.880 --> 16:13.340
Well, we saw yesterday with the final match of the day that teams were racing to build ROP chains.

16:13.460 --> 16:17.700
And one team had a full layout, he had the offsets right, and everything was going right.

16:17.700 --> 16:21.640
And then Pwn Tools kept throwing like, oh, you can't append to a relocated ROP chain.

16:22.420 --> 16:24.800
And he was stuck there for 10 minutes.

16:24.800 --> 16:26.260
We had to go into sudden death.

16:26.260 --> 16:30.420
And then sudden death was a ROP off again, a ROP race.

16:31.020 --> 16:39.300
And, you know, you get these really fancy tools, but if you trip over all their bells and whistles, you might be better off with basics.

16:39.720 --> 16:48.480
Yeah, and I think it's interesting because this isn't actually what you'd see in the real world, so to speak.

16:48.480 --> 16:49.740
This is a competition.

16:49.740 --> 16:53.840
This is testing, pushing people to their limits.

16:53.860 --> 16:59.780
But in a normal situation, if you were looking for bugs and trying to write an exploit, you could really take your time.

16:59.780 --> 17:00.560
Oh, yeah.

17:00.560 --> 17:01.260
No.

17:01.500 --> 17:07.460
I mean, in daily jobs, you know, reliability and undetectability of exploits is one thing.

17:07.540 --> 17:11.580
But CTF code is notoriously messy.

17:11.580 --> 17:19.400
It is built on a pile of commented out things that didn't work, curses, variable names that are just frustration with the author and the challenge.

17:19.960 --> 17:22.140
Yeah, we're looking at BlueWater right now.

17:22.140 --> 17:26.600
The A's and the B's are sort of the classic visual padding.

17:27.280 --> 17:36.160
But , you know, so far I haven't seen a lot of variable names like LOL or HA or WTF, but I've definitely seen that before.

17:36.160 --> 17:38.640
Yeah, a lot of maybe, a lot of underscore IDK.

17:38.640 --> 17:39.500
Yeah, yeah.

17:39.500 --> 17:44.340
But BlueWater is writing in their solution script undefined.

17:44.340 --> 17:47.840
It looks like they're also building out their script.

17:47.840 --> 17:55.940
So they've enumerated that, hey, there's there's a couple of commands here and they've broken down what each command type can take.

17:55.940 --> 17:58.240
So they have the idea.

17:58.240 --> 17:59.680
I don't think that they've seen the bug yet.

17:59.760 --> 18:02.800
Just just based on what we're looking at here.

18:02.800 --> 18:05.080
But they they've got the skeleton going.

18:05.080 --> 18:10.480
It looks like over on BlueWater, they're starting to send their BNSH shellcode.

18:10.800 --> 18:13.000
Yeah, they look like they're pretty close.

18:13.000 --> 18:13.440
Oh, yeah.

18:13.440 --> 18:15.120
And they're going to pack an address.

18:15.360 --> 18:16.800
Oh, do they have their gadget?

18:16.800 --> 18:17.660
Oh, do they?

18:17.660 --> 18:19.140
Oh, the receive buffer.

18:20.360 --> 18:23.620
OK, so they're putting the address of the receive buffer.

18:23.960 --> 18:30.080
But do they have no ASLR in place so they can they can use the binary address?

18:30.080 --> 18:32.500
Yeah, no, no, no, nothing.

18:32.500 --> 18:35.840
But do they have the gadget?

18:36.800 --> 18:39.220
Because, oh, you know what?

18:39.500 --> 18:46.260
They might just put on top of the stack and then, you know, Red will get to it or leave.

18:46.780 --> 18:47.520
Hmm.

18:47.760 --> 18:50.620
I'm not sure exactly.

18:50.620 --> 18:52.020
I think we're seeing them.

18:52.500 --> 18:56.940
I think they're they're they're still exploring here, but they're pretty close.

18:57.260 --> 18:57.800
Oh, yeah.

18:57.800 --> 18:58.740
OK, they're going back.

18:58.740 --> 19:00.240
They're double checking their offsets.

19:00.240 --> 19:02.640
They're making sure they're in the right function here.

19:04.320 --> 19:09.380
OK, and then they have a jump and they're like, but but the leaves should load it.

19:09.380 --> 19:10.760
It should work.

19:13.060 --> 19:15.560
So setting a breakpoint, walking through.

19:17.060 --> 19:19.820
Yeah, and he knows he's so close, right?

19:19.820 --> 19:24.480
This is this is the tense almost to the finish line.

19:24.480 --> 19:26.700
Just got to figure this last bit out.

19:27.520 --> 19:35.520
It looks like he's going to hard code the stack, which will work fine in local execution GDB, but stack address not fixed.

19:36.360 --> 19:37.800
Yeah , yeah, stack addresses.

19:39.880 --> 19:44.680
Not as not your reliable binary gadget here.

19:44.680 --> 19:46.480
Yeah, no, it is not built into the binary.

19:46.480 --> 19:47.860
It is not affected by Pi.

19:47.860 --> 19:49.460
I'm sure it is in some way or another.

19:51.020 --> 19:53.220
OK, so we see the first mean variable name.

19:56.700 --> 19:58.860
All right, so they're building out shellcode.

19:58.860 --> 20:02.500
Yeah, this is starting to look like the code that I wrote to solve this.

20:05.330 --> 20:08.550
Building out padding correctly, making sure everything lines up properly.

20:08.890 --> 20:13.830
And walking through, they're going to get segfaults here, but they're going to know where exactly in their chain they're segfaulting.

20:13.830 --> 20:16.530
It'll give them a better idea where to hone in on that offset.

20:17.210 --> 20:25.110
Yeah, and some of this really is just that iterative try one thing, see where see where we're at, maybe a missed assumption or things just.

20:25.110 --> 20:26.330
Yeah, here we go.

20:26.330 --> 20:28.970
So top of the stack is the address of the receive buffer.

20:29.350 --> 20:34.250
And then it looks like the shellcode isn't being written properly.

20:35.190 --> 20:38.610
Oh, nope, I saw push x68.

20:38.790 --> 20:39.310
OK.

20:39.310 --> 20:40.690
That looks promising.

20:40.690 --> 20:47.030
The SBB, the add, that doesn't look like the shellcode, but looks like they're landing something.

20:47.130 --> 20:48.490
Yeah, they're definitely somewhere.

20:48.490 --> 20:49.750
They're almost there.

20:49.750 --> 20:53.630
Over on undefined, let's see what's going on.

20:53.630 --> 20:55.290
Python solved up high.

20:55.910 --> 20:57.850
OK, so they're printing out receive packet information.

20:57.850 --> 21:00.190
They're still writing an interaction here.

21:00.190 --> 21:02.270
Do they have the query one implemented yet?

21:02.270 --> 21:03.610
I can't see quite that far.

21:03.610 --> 21:07.710
They have a function written to do the query one.

21:07.710 --> 21:14.670
I'm not sure that I've seen them bring that up, though, in terms of looking at it in Ghidra and finding...

21:14.670 --> 21:17.190
Oh, they're going really in-depth in the query all.

21:17.190 --> 21:25.850
Yeah, they're going a little deep on the reverse engineering, and it may cost them because the bug isn't...

21:25.850 --> 21:28.430
It's not too complicated in this case.

21:30.810 --> 21:32.350
But we're seeing them.

21:33.670 --> 21:35.630
They're giving it everything they've got.

21:35.970 --> 21:37.490
They're frantically looking through.

21:37.490 --> 21:44.970
I think the speed that they work at is impressive, but you can also, I think at this point, start to sense a little desperation.

21:44.970 --> 21:47.170
I'm sure that they're feeling, where is the bug?

21:47.170 --> 21:48.210
Where is the bug?

21:48.210 --> 21:49.410
Yeah, they're looking through.

21:49.410 --> 21:55.910
They're getting a really solid understanding of the binary, but they're missing shallow bugs looking for deep ones.

21:55.910 --> 21:57.670
Okay, so hint number one just dropped.

21:57.670 --> 21:59.570
The hints are set up to drop.

22:00.750 --> 22:01.310
Let's see.

22:01.310 --> 22:01.990
What is hint number one?

22:01.990 --> 22:03.710
This is a classic old-school bug.

22:03.710 --> 22:05.530
What a helpful hint, Mark.

22:11.330 --> 22:14.150
When I think of old-school bugs, I think of string bugs.

22:14.150 --> 22:14.610
I don't know about you.

22:14.610 --> 22:15.170
Fair.

22:16.030 --> 22:19.150
String handling bugs, I'm looking at...

22:19.150 --> 22:20.850
Stack buffer overflow, too.

22:20.850 --> 22:21.930
Yeah, stack buffer overflow.

22:21.930 --> 22:23.090
Okay, it is a helpful hint.

22:23.090 --> 22:24.510
I'm not thinking linked list.

22:24.510 --> 22:25.870
I'm not thinking heap.

22:26.030 --> 22:28.190
It's not an IOU ring, but...

22:28.190 --> 22:30.270
There's a stack buffer overflow somewhere.

22:31.050 --> 22:37.370
And for me, I'm looking at strcpy, strcat, hoping something like that.

22:37.370 --> 22:39.390
Any of the classic overflow vectors.

22:39.390 --> 22:40.410
Right, right.

22:41.890 --> 22:56.830
Now, for all of these challenges, we're doing it to try to set them on the right track, especially a case like this, where maybe they're just looking in the wrong spot, and so hint number one is trying to guide them towards the right spot.

22:56.910 --> 23:00.250
And then hint number two is like, okay, here it is, just do this.

23:00.370 --> 23:02.370
Hints released at 20, 35 minutes.

23:02.370 --> 23:04.210
50 minutes, we go into sudden death.

23:04.490 --> 23:06.810
We're setting a hard cutoff on that this year.

23:06.810 --> 23:09.170
We made the mistake last year of being too lenient with it.

23:10.310 --> 23:14.410
But it looks like we're 15, 18 minutes in, somewhere in there.

23:15.630 --> 23:17.770
Yeah, and really, looking at...

23:18.550 --> 23:20.450
That's right, hint drop.

23:20.450 --> 23:24.650
Hint drops automatically, this go around, which is a nice bit of automation.

23:25.390 --> 23:29.510
We're not completely beyond the setting pieces of paper down in front of the competitors.

23:29.510 --> 23:32.210
That is how they connect to the challenge server, yeah.

23:34.330 --> 23:35.870
But going through...

23:35.870 --> 23:42.830
Okay, so blue water is going through making sure they're on the right path, or are they looking for another vector?

23:43.350 --> 23:45.390
Or are they just checking offsets?

23:45.950 --> 23:47.030
Well, they...

23:47.030 --> 23:49.910
And I saw both competitors look at the hint.

23:51.190 --> 23:52.830
And it says it's an old school bug.

23:52.830 --> 23:54.130
They've got a stack buffer overflow.

23:54.130 --> 23:58.630
I think that they're just trying to break down, how do I get to my shellcode at this point?

23:58.990 --> 24:00.210
Yep, looking at gadgets.

24:00.210 --> 24:01.490
Yeah, oh my.

24:01.910 --> 24:05.290
Yeah, that's some ANSI color sequences there.

24:05.530 --> 24:07.070
Yeah, see, that made me ANSI.

24:10.270 --> 24:13.130
Okay, so we're looking for sub-RSPs, right?

24:13.310 --> 24:14.510
Okay, that's the road they're going.

24:14.510 --> 24:17.770
I think that there is a call register.

24:17.770 --> 24:21.310
There is a pop EDI call EDI or something, RDI.

24:21.310 --> 24:22.810
It's not that old school.

24:22.890 --> 24:24.430
Trying to make it easier.

24:24.430 --> 24:32.590
And so if you have that kind of tool, and you're grepping for a call or a jump gadget, it should just pop out at you.

24:32.590 --> 24:35.910
Well, absolutely, but he's looking for what he knows.

24:36.110 --> 24:38.050
He's looking for classic...

24:38.050 --> 24:39.270
That's right.

24:39.270 --> 24:45.150
And if you're used to working on modern exploitation challenges, they're not this easy.

24:45.150 --> 24:47.130
You have to do a little more.

24:47.230 --> 24:51.950
And so they're probably not expecting it as easy of a challenge.

24:51.950 --> 24:56.190
So hopefully as the tournament goes on, we'll see a little bit of that.

24:56.190 --> 24:59.030
Okay, check for the easy thing first, and then maybe...

24:59.030 --> 25:00.390
Yeah, this is a live CTF.

25:00.390 --> 25:01.810
We do want you to solve it.

25:02.770 --> 25:05.030
We really want you to solve it.

25:06.910 --> 25:08.970
Alright, so it looks like...

25:09.930 --> 25:17.290
just building a manual payload here instead of using PwnTool's shellcraft.

25:18.030 --> 25:18.970
Or maybe he'll still use it.

25:18.970 --> 25:20.870
I think it looks like he's...

25:20.870 --> 25:22.530
Oh, he's just figuring out the offsets again.

25:22.930 --> 25:26.810
Playing with the padding, trying to understand what exactly...

25:26.810 --> 25:28.530
Maybe looking for a leak.

25:30.870 --> 25:31.750
Yeah?

25:34.050 --> 25:37.270
They're looking at the output there, seeing what the server sent them.

25:37.270 --> 25:38.530
There's a lot of junk.

25:39.230 --> 25:40.530
It's all randomized.

25:40.530 --> 25:49.090
Again, this challenge was built to be run in a different environment where randomization was handled differently.

25:49.570 --> 25:51.050
These were automated competitors.

25:51.050 --> 25:52.430
They're not reading the output.

25:52.450 --> 25:53.330
No.

25:53.330 --> 25:54.250
It is garbage.

25:54.250 --> 25:58.410
It threw me off a little bit when I was parsing output, and I just got random strings back.

25:58.410 --> 26:00.150
And I'm like, am I parsing this right?

26:00.150 --> 26:02.050
Is it like 7-bit UTF?

26:02.970 --> 26:05.590
But no, it's just completely random strings.

26:06.530 --> 26:07.410
Printable strings.

26:07.410 --> 26:08.470
That's important.

26:08.670 --> 26:09.490
Right, right.

26:09.490 --> 26:12.150
Yeah, that would be mean if we just throw a null byte in there.

26:12.150 --> 26:13.810
They parse it out and early.

26:14.410 --> 26:15.530
Let's switch over to Undefined.

26:15.530 --> 26:16.430
It looks like they...

26:16.430 --> 26:20.510
I have to imagine that's their overflow that they're playing with, with all those A's.

26:20.510 --> 26:24.350
Yeah, it looks like they're stepping through, figuring out where in all those A's they are.

26:24.810 --> 26:29.490
And I gotta say, I'm loving their debugger setup here.

26:31.690 --> 26:34.530
So they're in parse query, it looks like.

26:34.530 --> 26:36.290
Not stepped fully into the query one.

26:36.290 --> 26:38.470
Oh no, parse query has a strcpy, doesn't it?

26:38.470 --> 26:39.630
Or is it in query one?

26:39.630 --> 26:40.330
I forget.

26:40.450 --> 26:41.990
I believe it's query one.

26:41.990 --> 26:45.470
In parse query, I think they're looking at the string handling to try to...

26:45.470 --> 26:50.070
They've got an idea that this is an overflow, so that hint looks like it did give them a little bit of an idea.

26:50.070 --> 26:51.510
Yeah , okay, it was a good hint.

26:51.530 --> 27:01.670
They're looking for overflows, seeing some comments go down, tracking, hey, what are the maximum lengths that can be sent in different places?

27:01.730 --> 27:10.150
And so what that was, that was the parse query, which populates a larger buffer, and then the query one buffer is a stack buffer, which is smaller.

27:10.150 --> 27:12.530
So they're on the right path.

27:13.090 --> 27:14.320
They're looking for that...

27:14.830 --> 27:16.830
Oh, now we see them looking at a strcpy.

27:16.830 --> 27:17.510
Oh.

27:17.510 --> 27:22.990
So they're thinking, hey, is this a strcpy bug, stack overflow?

27:22.990 --> 27:24.450
Right, kind of thinking.

27:24.650 --> 27:25.690
The wrong strcpy.

27:25.690 --> 27:28.090
That strcpy there is an innocuous one.

27:28.090 --> 27:28.490
Yeah.

27:28.490 --> 27:33.770
You can totally use it safely with enough checks or static string buffers.

27:33.770 --> 27:39.990
But if they were to look at the cross references on strcpy, that would drop them right in the right spot.

27:39.990 --> 27:41.090
They would.

27:41.550 --> 27:44.650
So let's see, going into...

27:44.650 --> 27:53.630
So this is the receive until, so just helpful wrappers around the receive function.

27:53.750 --> 27:55.730
Again, this was built in the CGC.

27:55.730 --> 27:59.830
There's a fair bit of scaffolding in play that they had.

27:59.830 --> 28:01.650
They had their own libc.

28:01.650 --> 28:10.790
So the challenge authors then built familiar wrappers commonly to make the challenges look like what we'd expect.

28:11.270 --> 28:17.130
But this is, I think, the competitor trying to understand, okay, what are the limits?

28:17.530 --> 28:19.690
How much exactly is going to be written in that buffer?

28:19.690 --> 28:21.410
Okay, we see the buffer label.

28:21.410 --> 28:23.150
The size is right next to it.

28:23.150 --> 28:30.210
But over on BlueWater, they have rbp414141.

28:30.210 --> 28:32.930
All right, so when we see register control, we know we're close.

28:32.930 --> 28:38.110
Because really, in this case, building a stack buffer overflow, there's only a few steps, right?

28:38.110 --> 28:38.830
Yeah.

28:38.830 --> 28:40.990
So you've got your overflow.

28:40.990 --> 28:43.730
You understand, okay, what registers do I control?

28:43.810 --> 28:46.710
What are the offsets to control those registers?

28:46.890 --> 28:50.090
And then what should I put in each of those?

28:50.090 --> 28:53.670
And what's going to be the easiest way to get shellcode running?

28:53.670 --> 29:00.930
Now, what I'm worried about with BlueWater is they were returning, I think, to the receive buffer, which I think is in BSS.

29:01.790 --> 29:02.650
Oh.

29:02.650 --> 29:08.210
So I'm not sure that that's executable, unless you unprotect it.

29:08.390 --> 29:12.830
That might have just been where they're putting their return address and they pop it and read to stack.

29:12.910 --> 29:14.250
I'm not 100%.

29:14.970 --> 29:18.350
I did see them looking at the virtual memory map.

29:18.350 --> 29:23.970
So they were looking at permissions for readable, writable, etc.

29:23.970 --> 29:25.270
Hopefully, yeah.

29:26.590 --> 29:28.490
I mean, we don't know what's going through their heads.

29:28.490 --> 29:30.290
They could be thinking anything right now.

29:30.330 --> 29:34.470
You could be thinking, man, this would just be so much easier if I can get a UAF in here.

29:34.870 --> 29:35.750
Yeah, yeah.

29:37.350 --> 29:40.410
Their mind may still be on the DEF CON CTF finals, right?

29:40.410 --> 29:45.450
Maybe they've been working on another challenge and this is just total whiplash in terms of...

29:45.450 --> 29:51.450
Yeah, BlueWater sat down and asked, can I unplug from HDMI so I can keep working on the challenge I was working on?

29:51.450 --> 29:52.430
Love that dedication.

29:52.430 --> 29:53.190
Yeah, go for it.

29:53.190 --> 29:54.370
We're going live in a couple minutes.

29:54.370 --> 29:56.670
And he's like, unplug, keep working on the challenge.

29:56.670 --> 29:58.850
I go over and I'm like, we're going live soon.

29:58.850 --> 30:03.310
He's like, okay, cool, plug it back in, close everything down so no other team can see what's going on.

30:03.310 --> 30:03.630
Awesome.

30:03.630 --> 30:11.250
We don't want to leak any DEF CON CTF challenge solution progress, anything about that.

30:12.250 --> 30:18.270
Yeah, it's definitely the case where the competitors know that their screens are being streamed.

30:18.270 --> 30:21.630
Yes, we are very explicit telling them that.

30:21.630 --> 30:23.290
We don't want anyone leaking anything.

30:23.290 --> 30:25.850
No password managers pulled up and they're like, oh yeah, what's my password again?

30:25.850 --> 30:26.930
Pull it up on screen.

30:27.830 --> 30:30.290
RBP, oh, okay, so it looks like he is the offset, right?

30:30.290 --> 30:31.590
RBP is bees now.

30:32.170 --> 30:33.170
Okay, yep.

30:33.430 --> 30:40.210
So he's nailed that offset and now just determining, okay, where do I go from here?

30:40.210 --> 30:41.830
What's the gadget I want?

30:41.830 --> 30:43.610
Can I do something with RBP?

30:43.610 --> 30:48.530
Man, it sure would be great if I had a DRFRSP plus 32 call.

30:48.870 --> 30:54.150
I'm just waiting for him to go back to his gadgets file and look for some friendlier gadgets.

30:54.150 --> 31:00.790
Yeah, you can make do with what he's found so far, but it is not going to be fast.

31:01.190 --> 31:06.070
You need that nice gadget to just kind of expedite the entire process.

31:06.410 --> 31:12.190
Or maybe he'll jump back, you know, call some puts, call printf and get a stack leak, do it that way.

31:12.270 --> 31:14.810
Yeah, and I never count these competitors out.

31:14.810 --> 31:20.630
I fully expect when I write a challenge like this that they are going to come up with some way to solve it that I didn't expect.

31:20.730 --> 31:21.610
Absolutely.

31:21.610 --> 31:24.930
I mean, we've seen that in a couple challenges yesterday.

31:24.930 --> 31:31.730
They were close to intended, but they did, you know, they diverged from the path that we kind of cut for them, that we put in place for them.

31:31.850 --> 31:37.010
And I think that really says that these competitors are all experts in the field.

31:37.310 --> 31:41.130
You know, they understand these things so well that they can go around.

31:41.130 --> 31:43.830
They don't need to walk the path that we kind of laid out for them.

31:43.830 --> 31:49.890
They see something off to the side, traverse that, and it might end up being faster, might end up being slower, but it'll work in the end.

31:49.890 --> 31:52.870
As I say that they're experts.

31:52.870 --> 31:54.570
What does the leave instruction do?

31:55.730 --> 31:57.030
But this is real.

31:57.030 --> 31:58.450
Honestly, it's totally fair.

31:58.450 --> 32:00.510
Every expert uses Stack Overflow.

32:00.630 --> 32:01.810
Tell me you don't.

32:01.810 --> 32:02.770
Tell me you don't, Josh.

32:02.770 --> 32:03.730
I can't.

32:03.730 --> 32:04.270
Well, I could.

32:04.270 --> 32:05.170
I'd be lying.

32:05.710 --> 32:13.050
No, we saw yesterday we had man7.org and Stack Overflow, and I don't know which one is better as far as describing what things do.

32:13.830 --> 32:14.490
Let's take a look.

32:14.490 --> 32:19.490
I think on the undefined side here, he's in the right function.

32:19.490 --> 32:21.130
He's got his cursor on strcpy.

32:21.130 --> 32:25.370
I think that we're watching him live understand.

32:25.490 --> 32:30.230
So he's got the instance buffer, the stack buffer labeled as instance.

32:30.230 --> 32:32.150
He's highlighting the strcpy.

32:32.150 --> 32:34.290
He's like, how big can this be again?

32:35.290 --> 32:38.050
Wait, this is such a small buffer.

32:38.050 --> 32:39.910
Oh, he walked over it.

32:41.110 --> 32:49.370
I'm not sure if he just counted out because there was an innocuous one earlier, and it just kind of blends into the background.

32:49.370 --> 32:53.590
Or if he saw it, and he's just marking stuff around it so he knows what's going on after.

32:53.650 --> 33:03.150
Yeah, perhaps looking for something afterwards that might modify or otherwise change the environment.

33:03.290 --> 33:19.430
But the query being the argument to the query1 function, that is a little bit of a hint that, hey, if he can go back and understand what part of that structure he controls, I mean, he's looking right at it.

33:19.430 --> 33:22.010
So I think we're seeing...

33:22.010 --> 33:24.790
Yeah, rewriting to use the query1, it looks like.

33:24.790 --> 33:34.130
So this competitor is understanding, okay, we've got structures in terms of server name, instance name, and then on the right path.

33:34.130 --> 33:35.810
You know what I'm seeing a lack of?

33:35.910 --> 33:37.750
Type hints in their solve scripts.

33:37.830 --> 33:39.650
It is honestly underrated.

33:39.650 --> 33:48.730
The number of times I pass a string to a function that takes bytes and the encoding gets messed up, or it passes and PwnTools throws a warning that I'm not aware of, UTF fucks everything up.

33:49.090 --> 33:54.070
Like, really, type hints and exploit scripts have saved me so many debugging steps.

33:54.110 --> 34:02.350
Oh, yeah, I mean, the only time in the past year or two that I've written Python without type hints was writing a challenge for this.

34:02.350 --> 34:03.010
Yeah.

34:03.390 --> 34:05.810
Because I didn't want people to figure it out too quickly.

34:05.810 --> 34:07.170
Yeah, yeah.

34:07.670 --> 34:11.470
All right, let's take a look and switch over to Bluewater.

34:11.470 --> 34:12.990
All right, Bluewater.

34:12.990 --> 34:17.430
Looks like they're going in the parse query, looking at the calloc lengths.

34:20.710 --> 34:25.950
I think they haven't seen the nice gadget yet.

34:26.550 --> 34:28.450
Yep, I agree.

34:28.450 --> 34:30.410
I think that there's a...

34:32.150 --> 34:34.750
They might have a technique in mind.

34:36.970 --> 34:38.310
Yeah, so it's hanging.

34:38.310 --> 34:43.230
I wonder if they're just going to run it against and wait for the stack to line up at some nice boundary or something.

34:43.230 --> 34:44.790
I'm not 100% sure.

34:44.790 --> 34:47.390
It looks like they're exploring the other functionality in there.

34:47.630 --> 34:48.070
Interesting.

34:48.070 --> 34:53.530
If I recall, there's only three or four different things you can get the target to do.

34:53.530 --> 34:55.150
Yeah, it's a smaller surface.

34:55.330 --> 35:03.710
Perhaps there's something hidden in the other functions that he wants to use or thinks that might be helpful in terms of...

35:03.710 --> 35:04.450
Yeah.

35:04.450 --> 35:10.610
Now, looking at decompilation, you're not going to see those nice gadgets hidden in there because they're just going to be optimized out in some cases.

35:10.610 --> 35:11.510
They could be dead code.

35:11.510 --> 35:13.690
They could be just unoptimized.

35:13.830 --> 35:16.690
Decompiler throws them away because it's an if-false.

35:17.150 --> 35:18.090
Right, exactly.

35:18.090 --> 35:20.530
And I think that that's the case with this specific gadget.

35:20.530 --> 35:26.290
It was inserted to make life easier, but it's really not in the hot path.

35:26.290 --> 35:29.430
It's not something that you're going to run into just running the binary.

35:29.670 --> 35:43.970
Yeah, and that kind of brings up one of the major downsides of only looking at decompilation is you're looking at this output where all these heuristics, especially in IDA, all these heuristics were being applied that removes things you're not interested in for actual functionality.

35:44.190 --> 35:55.190
But when you're getting down to the actual creation of an exploit, you really need to look at the fine-grained, you know, I have a sub-RSP 32 call.

35:55.370 --> 35:59.250
Like, I have all of these things in dead paths that I can use.

35:59.250 --> 36:03.190
And we saw him looking at ROP gadgets for, you know, a minute maybe.

36:03.490 --> 36:06.410
But he was just searching through for sub-ESPs.

36:07.190 --> 36:12.810
Yeah, yeah, I think that there's a tendency to go with what you know.

36:12.810 --> 36:17.330
And I don't think that Magic Gadget is going to work on this one, right?

36:17.330 --> 36:20.130
So it's like, all right, what's the fallback here?

36:20.130 --> 36:24.510
And that can be challenging if, you know, you're not prepared for it.

36:24.510 --> 36:25.730
You're not expecting it.

36:25.810 --> 36:31.530
I'm wondering if now he's trying to get a libc leak or something and like, oh, just one gadget it, something like that.

36:31.530 --> 36:33.170
But just as easily, there's no NX.

36:33.170 --> 36:34.910
You can get a stack leak and jump to it.

36:35.650 --> 36:40.910
Yeah, I think that at this point, there's...

36:42.650 --> 36:51.190
It's just, it feels like this is one of those parts in the pattern of writing an exploit that automation would help, you know?

36:51.230 --> 36:53.770
Like, suggest a few things.

36:53.770 --> 36:56.510
Because as you said, there's a lot of trust in the tools.

36:56.510 --> 36:58.110
Decompilation, a great example.

36:59.710 --> 37:03.290
You're counting on the tool to show you exactly what's there.

37:03.290 --> 37:14.670
And I think that walking that line of using tools to make you faster and make things that are hard easier is something that I only expect to see more of in the future.

37:14.670 --> 37:19.290
And we see over on Blue Water, they just highlighted the RWX stack.

37:19.610 --> 37:20.690
I don't think they noticed.

37:20.690 --> 37:21.490
Oh, we're back.

37:21.490 --> 37:23.150
We're back in the gadgets.

37:23.430 --> 37:27.650
But at the same time, Undefined was writing their solve script too.

37:27.650 --> 37:30.550
In their solve script, they have hard-coded binary data.

37:30.550 --> 37:32.290
So it looks like they're just fine-tuning.

37:32.290 --> 37:34.930
They're going through with a fine comb now, figuring out where it goes wrong.

37:34.970 --> 37:37.290
Oh, they have a threat to...

37:37.810 --> 37:38.830
Is that a controlled address?

37:38.830 --> 37:39.890
I can't see that far.

37:39.890 --> 37:40.810
Yeah, we've got RSP.

37:40.810 --> 37:41.630
They control RSP.

37:41.630 --> 37:47.150
And you can see the cyclic pattern is going to allow them to calculate exactly what the offset is.

37:47.210 --> 37:48.130
Oh, that's what that was.

37:48.130 --> 37:49.950
They were just pasting cyclic output, maybe.

37:50.730 --> 37:53.610
Yeah, so now they're going through and actually...

37:53.610 --> 37:56.270
And so this is a clever point because even...

37:56.270 --> 38:01.730
It's not just, hey, okay, so you can see that they're putting a known value that's going to go in the return address.

38:01.730 --> 38:06.170
But then after that, seeing, okay, which of these other values ends up in other registers.

38:06.170 --> 38:11.490
So you can understand, hey, each register that I control, this is exactly the offset that's going into it.

38:11.490 --> 38:12.430
Oh, yeah.

38:13.030 --> 38:15.310
And it looks like... Is that dead beef I see over there?

38:15.450 --> 38:19.350
So they've definitely landed the return address overwrite.

38:19.570 --> 38:23.550
And now let's see what their strategy to get execution is.

38:23.830 --> 38:25.650
All right, so are they going to look through gadgets?

38:25.650 --> 38:29.750
Are they going to see any nice leak there?

38:30.890 --> 38:31.770
Not 100%.

38:31.770 --> 38:32.950
It's never guaranteed.

38:32.950 --> 38:39.010
You can be so close to the solution and then overlook one thing, one nice gadget, one win function.

38:40.570 --> 38:42.590
And a hint, too, just came out.

38:42.670 --> 38:48.550
Yeah, I saw somebody checking the live CTF page to see if that hint had dropped.

38:49.010 --> 38:54.550
And I think that we added a timer today so that competitors could see exactly how close they were to getting a hint.

38:55.190 --> 38:59.590
That, I was told, was not 100% not going to break the infra.

38:59.590 --> 39:02.790
So I did not deploy it for first match.

39:03.070 --> 39:07.310
But I told them in person, you know, check back at this time and this time.

39:07.330 --> 39:08.390
There will be hints.

39:08.390 --> 39:09.470
Refresh the page.

39:09.890 --> 39:12.110
But they might be a little too focused on this.

39:12.110 --> 39:13.090
They might not notice it.

39:13.130 --> 39:13.650
Outstanding.

39:13.650 --> 39:16.570
Yeah, the priority is that the infrastructure actually works.

39:16.730 --> 39:17.250
Yes.

39:17.250 --> 39:21.990
I was not about... I waited in line for breakfast, came over here a couple minutes before.

39:21.990 --> 39:22.750
Plug everything in.

39:22.750 --> 39:23.490
Please work, please work.

39:23.490 --> 39:25.570
IP tables routed everything properly.

39:25.710 --> 39:26.590
Container started.

39:26.590 --> 39:27.530
I'm like, yes!

39:28.810 --> 39:31.110
So, undefined.

39:31.450 --> 39:33.450
Hang on, no arch presence.

39:33.670 --> 39:34.750
Are they?

39:36.170 --> 39:37.070
Oh.

39:38.310 --> 39:42.190
I think we're seeing a... Yeah, we're seeing a ret to the receive buffer again.

39:44.390 --> 39:46.730
And so, they're working through.

39:46.730 --> 39:47.950
They've got the overwrite.

39:47.950 --> 39:50.750
They know that they've got the bug.

39:50.750 --> 39:53.250
They're just trying to finish out.

39:53.250 --> 39:57.170
And honestly, BlueWater, if we flip over them, they're looking through gadgets.

39:57.170 --> 40:00.650
They know that they've been closed for a long time.

40:00.650 --> 40:03.870
They see that pop RVP ret, which is pretty nice.

40:04.030 --> 40:04.390
Yep.

40:04.390 --> 40:06.470
But that doesn't give them the stack offset.

40:06.910 --> 40:07.550
Yep.

40:07.550 --> 40:08.930
Yeah, so at this point...

40:08.930 --> 40:10.650
They're just going with full ROP chain.

40:10.950 --> 40:12.750
Well, and that's an option.

40:14.150 --> 40:16.070
I don't know if it is.

40:16.210 --> 40:18.610
Because there's no system call in this.

40:18.690 --> 40:20.490
There's no, like...

40:20.490 --> 40:24.010
Like, I guess if you get lucky and find the syscall ret, right?

40:24.070 --> 40:25.410
That's what it comes down to.

40:25.410 --> 40:27.450
But I don't know if there are any raw syscalls in this.

40:29.070 --> 40:29.910
Good point.

40:29.910 --> 40:31.530
I think...

40:31.530 --> 40:33.690
You know, but it's...

40:35.350 --> 40:38.610
With an overwrite like this, there's...

40:38.610 --> 40:40.770
There's a few things you can do.

40:40.770 --> 40:42.530
If I recall...

40:42.530 --> 40:45.550
It's not null terminated, so you can write...

40:45.550 --> 40:46.250
Oh!

40:47.750 --> 40:49.150
It's... I want to say it's new...

40:49.150 --> 40:49.770
That's pretty nice.

40:49.770 --> 40:51.210
No , it's a strcpy, so it is...

40:51.210 --> 40:52.330
Oh, yeah, yeah, yeah.

40:52.370 --> 40:55.290
Okay, but you can have null-free shellcode pretty easily.

40:55.290 --> 40:57.190
That's not too bad of a constraint.

40:59.930 --> 41:00.510
Let's see.

41:00.510 --> 41:02.430
So they're getting the offset right.

41:02.430 --> 41:04.750
Oh, no, you don't...

41:05.270 --> 41:05.890
No.

41:05.890 --> 41:14.970
I mean, if they're writing a ROP chain, you can just fully ROP to it and probably build binsh that way because you have address of the receive buffer.

41:14.970 --> 41:16.650
You can just send binsh in it.

41:16.950 --> 41:17.330
That's right.

41:17.330 --> 41:19.730
You've got a larger buffer that you can stage stuff.

41:20.250 --> 41:22.150
So they actually...

41:22.150 --> 41:24.390
And it looks like that's what they're trying to do.

41:25.290 --> 41:26.330
Oh , I hope so.

41:26.850 --> 41:28.190
Where is that?

41:29.730 --> 41:33.110
Yeah, so they have padded shellcode on there.

41:33.110 --> 41:37.690
They're putting ROP gadgets after, which are going to be on top of the stack and hopefully RET to it.

41:37.730 --> 41:40.150
And that makes sense with the other...

41:40.150 --> 41:49.910
When they were looking at the other functions, I think that they might have been trying to send data to get it staged somewhere else and then maybe look for references to that data later.

41:49.910 --> 41:58.030
Yeah, but it looks like also that they're sending 7 A's instead of 8, so they still have that leading FD on top of the stack.

41:58.470 --> 42:01.470
So I'm not sure if they see that or if they just see the A's at the end.

42:01.470 --> 42:02.050
Okay, cool.

42:02.050 --> 42:03.190
I'm overriding everything.

42:06.270 --> 42:08.690
Yeah, they see a REX.B.

42:08.690 --> 42:10.470
I don't think that's part of their shellcode.

42:10.990 --> 42:17.590
I just wanted to point out Undefined pulling out the checksec, understanding that there's no mitigations in play.

42:19.710 --> 42:21.470
They're looking for...

42:21.470 --> 42:23.850
How do I get execution?

42:23.850 --> 42:25.250
I've got the strcpy.

42:25.250 --> 42:26.350
They have strcpy.

42:26.350 --> 42:28.010
We saw them get RIP.

42:28.310 --> 42:30.630
They got RIP once at deadbeef.

42:30.630 --> 42:36.710
Okay, so what we're seeing here is looking at ROP gadgets.

42:36.910 --> 42:37.570
Oh, yeah.

42:37.830 --> 42:40.090
And they're looking for RSP gadgets.

42:40.090 --> 42:40.850
Yep.

42:41.090 --> 42:43.230
Which is on the right path.

42:43.230 --> 42:44.350
It's close.

42:46.710 --> 42:52.130
Yeah, you know, parsing these outputs, that wall of text, it's always tough for me.

42:52.190 --> 42:53.990
I always feel like there's got to be a better way.

42:55.150 --> 42:58.510
Oh, this is a tool I haven't seen before on Bluewater.

42:58.910 --> 43:02.070
Disasm.will.gl Oh, this is nice.

43:02.070 --> 43:04.790
It's like a nicer Diffuse CA, honestly.

43:04.810 --> 43:08.830
Diffuse CA is something I go to for just like in-browser disassembly-assembly.

43:08.830 --> 43:10.890
You know, I just want to copy a bunch of bytes out.

43:11.750 --> 43:14.170
Yeah, having little tools like that is...

43:16.270 --> 43:17.230
It's really helpful.

43:17.230 --> 43:22.570
And in competitions like this, really having a number of tools to go to is helpful.

43:22.570 --> 43:28.190
You want to have all the tools in your toolbox that you could possibly need because you never know what's going to come up for a challenge.

43:29.030 --> 43:30.830
Oh, and it looks like...

43:30.830 --> 43:33.270
Okay, so he's looking now.

43:33.590 --> 43:39.670
What opcodes can I use that start with 0x3, the command code in the packet, to get to this path?

43:42.400 --> 43:43.880
Oh, they're both so close.

43:43.880 --> 43:45.960
I just heard mumbles of sudden death.

43:46.380 --> 43:50.400
I'm not sure when we're getting there, but I imagine we're getting close.

43:50.940 --> 43:52.320
Ten minutes?

43:52.940 --> 43:53.600
Eight.

43:53.600 --> 43:55.620
Eight minutes to sudden death.

43:55.620 --> 43:55.960
Wow.

43:55.960 --> 43:59.500
Sudden death, an easier challenge, should be solved fairly quickly.

43:59.840 --> 44:04.600
We did not write all of them last night, but I verified all of them and they work.

44:04.600 --> 44:06.160
Very easy challenges.

44:06.160 --> 44:07.000
Very fast.

44:07.000 --> 44:12.290
Does not require this level of either reverse engineering or this kind of...

44:13.580 --> 44:16.400
these exploitation chops, I guess.

44:17.140 --> 44:23.100
Yeah, and, you know, really hoping to see a solve for this, especially because I feel for the competitors.

44:23.100 --> 44:24.100
Been there.

44:24.100 --> 44:31.480
You know you're so close and you hate to go into sudden death when you know you're just minutes away from a solve.

44:31.500 --> 44:42.720
Yeah, but it looks like over on Blue Water, they're trying to read from an invalid address and that really looks like just random data on the stack.

44:42.980 --> 44:45.320
They're reading to what's in their RBP.

44:45.320 --> 44:47.200
Oh, they're scrolling so fast.

44:48.840 --> 44:51.680
Oh, RBP is argv0.

44:52.200 --> 44:53.780
Or a pointer to argv0.

44:53.780 --> 44:55.820
So they're too far down the stack.

44:58.060 --> 44:58.700
Okay.

44:58.700 --> 45:03.740
Sometimes it just becomes a challenge to follow the thought process because these competitors are so fast.

45:03.740 --> 45:06.240
Oh, and they have five different threads going at once.

45:06.240 --> 45:10.100
Yep, they're trying different ideas, seeing what sticks.

45:10.480 --> 45:11.320
Yeah.

45:11.320 --> 45:17.200
And really, we give a general category of what the challenge is.

45:17.200 --> 45:20.560
So I think this one was old school Pwn as the hint or something like that.

45:20.560 --> 45:23.040
Or as the category we give the competitors.

45:23.360 --> 45:26.180
So outside of that, they don't have anything.

45:26.180 --> 45:32.840
They don't know whether to send, you know, the guy that wrote House of Blue 42 or whatever.

45:33.160 --> 45:46.600
Yeah, there's we try to set them up this go around with information at least categorical so that they can say, hey, you're better at heap challenges, you're better at stack challenges.

45:47.200 --> 45:49.920
And we see that second...

45:49.920 --> 45:53.660
Second hint, query 1 uses strcpy was the hint.

45:53.660 --> 45:55.320
Both competitors already there.

45:55.320 --> 45:56.280
Already knew that, yeah.

45:56.280 --> 45:58.920
So I don't think hint 2 is going to be that helpful.

45:58.920 --> 46:01.600
I mean, really, at this point, they have everything they need.

46:01.980 --> 46:06.520
You know, we're not going to say, oh yeah, this gadget is at this offset.

46:06.760 --> 46:08.160
That's so incredibly free.

46:08.160 --> 46:09.580
They need to know what they're looking for.

46:09.580 --> 46:12.840
They need to have an idea of what they need next in the exploit chain.

46:13.760 --> 46:19.220
But it looks like they're getting hung up on kind of how do I get a leak?

46:19.540 --> 46:20.340
True, true.

46:20.340 --> 46:25.940
I mean, yes, we could have put the hint as maybe this gadget would be helpful.

46:25.940 --> 46:29.400
And I think that both of these competitors honestly would really appreciate that right now.

46:29.400 --> 46:33.100
Then it would just be a race to see who can type in that address faster.

46:33.100 --> 46:35.100
It's just monkey type at that point.

46:36.560 --> 46:45.960
I think on the undefined side, we're seeing some PwnTools use that they're resolving symbols to get those addresses automatically.

46:46.360 --> 46:57.180
I think that that's I'd love to see the power users of libraries, frameworks, tools and see how they can make their lives easier.

46:57.180 --> 47:00.440
Because I really feel like that should be faster.

47:00.440 --> 47:03.860
Oh yeah, PwnTools has a lot of great bells and whistles on it.

47:03.860 --> 47:07.380
It has a lot of great functionality for mundane tasks.

47:07.860 --> 47:09.980
Like calculating offsets, working from a base .

47:09.980 --> 47:12.560
You don't need to have some libc base variable in there.

47:12.560 --> 47:16.760
You can just load the elf setBaseAddress once and then work relative to that with symbols.

47:16.760 --> 47:17.880
It's really nice.

47:18.740 --> 47:26.080
Yeah, and this this RobGadget interaction that they're doing is very cool.

47:26.080 --> 47:27.680
I don't think I've seen this tool.

47:27.920 --> 47:30.180
Yeah, so what tool are they using?

47:30.180 --> 47:31.400
I can't read there.

47:32.260 --> 47:35.280
RpLin64 could be a custom tool.

47:35.280 --> 47:36.060
Oh, it could be.

47:36.100 --> 47:37.680
I'm a fan of like Ropper.

47:37.680 --> 47:39.200
RopGadget is a classic.

47:39.200 --> 47:58.600
Well, I think actually what we were seeing was a grep output that they could scroll through and highlight lines, which was... Yeah, we have or we had in RPiSec a tool called Grepper, g-r-e-p-r that would do RopGadget search and then provide a nice live filterable view of all the gadgets and you can use like regexes in there.

47:58.600 --> 47:59.700
It's really nice.

47:59.700 --> 48:01.740
Yeah, stuff like that.

48:01.740 --> 48:12.640
I mean, it seems simple but you put enough of these simple tools put them together and it makes your life easier, which equates to faster solve.

48:13.100 --> 48:19.940
Hopefully it does because we see so close we see blue...

48:19.940 --> 48:20.980
Oh, wait.

48:21.880 --> 48:24.340
Alright, so they're looking for pops still.

48:24.840 --> 48:32.480
Over on blue water we also saw them looking at that pop rbp ret call or gadget again.

48:32.620 --> 48:34.980
Yeah, they're both looking for that.

48:35.020 --> 48:46.740
Yeah, but because they've got control over rbp That's going to put them maybe in some random invalid address because there's just data after that before their buffer.

48:46.740 --> 48:52.840
They really need that that stack ink or deck I forget which one it is.

48:52.840 --> 48:53.900
I think it's ink.

48:56.850 --> 49:08.630
Yeah, and this is this is tough because you never know what exactly is going to be the gadget that's going to do it for you going in and everything's easy to look at in retrospect, right?

49:08.630 --> 49:09.350
Oh, yeah.

49:09.350 --> 49:11.970
No, CTF is a lot about making do with what you have.

49:11.970 --> 49:16.730
And you can easily accept that all you have are the gadgets and the binary.

49:16.730 --> 49:18.190
There aren't any nice ones there.

49:18.190 --> 49:20.710
But at least take a cursory look.

49:21.150 --> 49:21.630
Oh!

49:21.630 --> 49:23.290
Move racks rsb.

49:23.290 --> 49:24.470
Add racks.

49:24.670 --> 49:25.450
Oh!

49:25.450 --> 49:28.050
Okay, he found the nice gadget.

49:28.590 --> 49:29.270
4019fd.

49:29.270 --> 49:30.770
My favorite address.

49:31.530 --> 49:32.970
It's up there in me.

49:32.970 --> 49:37.070
It's like it's in the top 4 billion, I want to say.

49:37.070 --> 49:37.510
Yeah.

49:37.670 --> 49:38.550
Roughly.

49:40.770 --> 49:42.610
At least the 32 bit.

49:43.410 --> 49:45.770
So this is exactly what we talked about.

49:46.370 --> 49:53.590
They're going back to the gadgets, finding the thing that's going to make their life easier and I think at this point it's just a matter of time.

49:53.590 --> 49:54.530
Oh yeah.

49:54.530 --> 49:57.750
So it looks like BlueWater found the nice gadget they're working through.

49:57.810 --> 50:01.830
That pop is going to take them exactly to the beginning of their overflow.

50:01.990 --> 50:05.430
So it should just be as simple as inserting shellcode after that.

50:05.430 --> 50:07.110
Almost like it was made that way.

50:07.330 --> 50:08.290
Imagine.

50:08.370 --> 50:10.470
Alright, let's take a look at Undefined.

50:11.090 --> 50:13.310
Looking through stack addresses here.

50:13.310 --> 50:15.850
Trying to understand what they control.

50:15.850 --> 50:18.090
What this pointer specifically is looking at.

50:18.090 --> 50:21.430
You know, the pop, rut kind of gadgets.

50:22.670 --> 50:24.810
They're looking to see if that's useful for them.

50:25.170 --> 50:25.650
They are.

50:25.650 --> 50:28.990
And then over on BlueWater, they're on the stack.

50:29.310 --> 50:30.530
And I see that syscall instruction.

50:30.530 --> 50:32.210
I see push0x3b syscall.

50:32.210 --> 50:32.990
They walk through it.

50:32.990 --> 50:35.190
They just have registers set up wrong it looks like.

50:35.190 --> 50:36.670
I couldn't see quite in time.

50:39.110 --> 50:41.810
So they might just have offset 1.

50:41.810 --> 50:44.090
Might be missing the first instruction in that chain.

50:44.090 --> 50:46.970
Could just be a XOR of like RCX or something.

50:47.050 --> 50:50.390
Yeah, I saw that they were using the PwnTools built-in shellcode.

50:50.430 --> 50:52.810
So probably not any mistakes there.

50:52.810 --> 50:54.550
No , it's very thorough.

50:54.550 --> 50:55.410
It's verbose.

50:55.410 --> 51:03.230
But making sure that that came through untouched, you know, completely valid, that looks like what they're doing there.

51:03.230 --> 51:06.890
Yeah, I don't know if PwnTools shellcode actually has nullbytes in it.

51:07.330 --> 51:08.990
It might have nullbytes.

51:10.390 --> 51:13.690
Which would really break this flow here.

51:13.690 --> 51:14.930
Because it would stop reading the string.

51:14.930 --> 51:16.630
But no, it got to the syscall.

51:16.630 --> 51:18.150
So it can't have nullbytes in there.

51:18.150 --> 51:19.290
So there's the call.

51:19.290 --> 51:21.730
He's looking at this.

51:21.730 --> 51:22.470
Alright.

51:22.470 --> 51:24.630
Oh yeah, that's...

51:26.050 --> 51:27.390
ESPDI REF RSP.

51:27.390 --> 51:29.850
Probably doesn't want that at the beginning of his shellcode.

51:30.190 --> 51:31.210
Does he?

51:32.150 --> 51:33.930
I don't know.

51:33.930 --> 51:36.510
Oh, and I just got word that we're heading to sudden death.

51:36.510 --> 51:38.330
We're heading to sudden death?

51:40.870 --> 51:41.750
No!

51:42.570 --> 51:44.410
He's on his shellcode!

51:46.630 --> 51:47.510
Oh my gosh.

51:47.930 --> 51:49.050
No!

51:49.410 --> 51:50.850
Oh, don't save the database.

51:50.850 --> 51:52.130
You can feel it.

51:52.130 --> 51:53.650
That's so upsetting.

51:53.930 --> 51:56.330
Oh, he's deleting the challenge.

51:57.170 --> 51:58.930
Oh, that's so sad.

51:58.930 --> 52:01.430
He was walking through his shellcode.

52:02.950 --> 52:04.430
But we mentioned...

52:04.430 --> 52:06.270
I made sure to mention 50 minutes.

52:06.270 --> 52:07.830
We're going to sudden death.

52:07.830 --> 52:10.330
That is so sad.

52:10.330 --> 52:16.450
So we're having some technical difficulties with the camera here on our end, but...

52:16.970 --> 52:20.150
Oh, so we're just going to stay on bracket view for a bit.

52:20.670 --> 52:22.830
I don't know which way this is going to go.

52:23.090 --> 52:24.870
Undefined was working slowly through it.

52:24.870 --> 52:26.750
They were about to find the gadget, I'm sure.

52:26.790 --> 52:28.350
BlueWater just found it.

52:28.350 --> 52:30.530
Yep, they were just looking through gadgets again.

52:30.530 --> 52:31.410
Oh man.

52:32.610 --> 52:34.450
Oh, that's...

52:36.190 --> 52:37.550
You know that...

52:37.550 --> 52:43.010
It wasn't guaranteed to go one way or another because BlueWater was just starting to debug where they were jumping to.

52:43.010 --> 52:44.510
I think that they were very close.

52:44.510 --> 52:48.450
You saw them highlighting the first instruction in their payload and it was just...

52:49.830 --> 52:52.690
As far as I know, bad.

52:52.690 --> 52:54.130
It was just a bad instruction.

52:54.530 --> 52:57.370
Well, not bad instruction, but it was bad instruction to have in your payload.

52:57.470 --> 52:59.270
It wasn't the right instruction.

