Free YouTube Transcribe

Video transcript

it's just too easy

John Hammond · 3,127 words · 15 min read

WhatsAppTelegramX

Want to search this transcript, jump the video from any line, or download it as TXT, SRT, or VTT?

Open in the transcript tool

Full transcript

0:00Docker. I barely know her. When SSRF is

0:03enough full Docker escape on Windows

0:06Docker Desktop CVE 20259074.

0:10This is a recent write up that I will

0:12leave a link in the video description.

0:13And I do want to give a big shout out.

0:14We'll hop over to his LinkedIn. Felix

0:17Boule. I'm so sorry. I don't know how to

0:19pronounce your last name. Felix.

0:21Sometimes bugs don't need to be that

0:22complicated. This is the tale of how I

0:24found the full Docker escape that was

0:26attributed CVE20259074.

0:29And that is now fixed. It is patched. So

0:31if you are running Docker for desktop on

0:34Windows or Mac OS, make sure you update

0:37upgrade get to version 4.44.3.

0:41Up until that version, an SSRF or like

0:43server side request forgery or a simple

0:46web request from any container was

0:48enough to fully compromise the host

0:51computer. Now you might think of Docker

0:52usually running containers in like oh an

0:55isolated sort of guest space but no we

0:57mean physically the whole computer the

0:59host computer where the Docker engine

1:01and Docker service runs. Felix wants to

1:04shout out Felipe Duger again I'm so

1:06sorry in pronunciation from Pivotal

1:08Technologies. He's a longtime friend and

1:10Docker expert. So I asked for his input

1:12and help during the research. I'll leave

1:14a link to his LinkedIn profile just as

1:16well in the video description. So here

1:17is the situation on an unpatched docker

1:20for desktop for Windows. Anything below

1:22version 4.44.3

1:24any container running container instance

1:26could connect to this IP address on this

1:30port without any authentication. They

1:32could create and start a privileged

1:34container so it could have access to the

1:35host and it could mount the host C drive

1:38running on Windows onto or into that

1:41container. With that you gain full

1:42access on the Windows host. That means

1:44you have access to the file system.

1:46That's not immediately a code execution

1:48on the host, but as I'm sure you know,

1:50you could leverage that write capability

1:53or any read capability, I guess, if you

1:54want on the Windows file system like to

1:57stage something into the startup folder

1:59or gain some other persistence via

2:01scheduled task or whatever and then

2:02eventually get further code execution

2:04and compromise the full computer. This

2:07192.168.65.7

2:0965.7 and port 2375 is the control plane

2:14or like the Docker service API, the

2:17capability to run Docker stuff, hey,

2:20spawn, start containers, create

2:22containers, etc. Again, I'll put a link

2:23to that in the video description, but

2:25I'm more interested in how can we play

2:27with it? Can we do this, too? I thought,

2:29let's go ahead and install Docker

2:31Desktop on Windows and then see if we

2:33could recreate this in a vulnerable

2:34version. Of course, if we were to go try

2:36and download Docker Desktop for Windows

2:38from their website, we'll get a Docker

2:41desktopinst installer.exe. And if you

2:43were to download this, this will be the

2:45patched version, like the latest 4.44.3.

2:48And there's no easy way that I could

2:50tell from the link or URL to be able to

2:52like adjust the version that you're

2:54downloading. I don't think they show or

2:56offer or include I couldn't at least

2:58couldn't track it down any previous or

3:00older versions of Docker Desktop from

3:03their website. So to be honest, the next

3:04thought that I had would be to look on

3:06virus total or is this hosted or

3:08available for download anywhere else on

3:10the internet. Virus Total keeps things

3:12kind of easy for us and we know that the

3:14file will now be called docker desktop

3:17installer.exe.

3:19So we could simply search for files like

3:20with that file name. And if we get a

3:22couple hits probably going to get things

3:24recent from todayish or around this time

3:27frame. And if we go click in one of

3:28these, the Docker desktop installer in

3:31the details section, we might be able to

3:33get a clue as to what the version is.

3:35Scrolling down, we could actually see,

3:37oh yeah, exactly. File version

3:39information. Zooming in a little bit

3:41more, you could see this section here

3:42with the file version included as part

3:44of the data for the portable executable

3:46or the.exe file itself. We could see

3:494.44.3.202

3:52blah blah blah. So that one is patched,

3:54right? That's version 4.44.3.

3:56I want the vulnerable one. So, could I

3:58simply just like add to my query? I

4:01don't see why not. Let's try to see.

4:03Could I just look for that as the file

4:05name kind of in strings. And I'm not

4:07even using like any operators here. I'm

4:08just going to make this stupid, dumb,

4:10and easy. Let me search for 4.44.2.

4:13Now, when we get results back, I do see

4:15a couple. Let's check the details on

4:16him. This one is perfect file version

4:19information. This clues us in 4.44.2.

4:23So, let me download this from virus

4:24total. Click download sample download

4:26file. And now I have the Docker desktop

4:29installer on my desktop. Let me say I

4:32usually record videos inside of a

4:34virtual machine because I just prefer to

4:35do that when looking at malware and

4:37vulnerabilities and exploits and weird

4:38stuff, right? But I always get a little

4:40bit sketched when I have to record on my

4:42host. This might be a scenario because I

4:44have not yet provisioned or set up even

4:46this desktop machine to uh virtualize

4:49inside of virtualized virtual machines.

4:51You know what I mean? like nested

4:52virtualization because Docker on Windows

4:55uses Windows Subsystem for Linux or WSL

4:58and WSL 2. You could use HyperV just as

5:01well, but let me see if I can get this

5:03installed. Okay, installation succeeded.

5:05I have to restart my computer though.

5:07And since it's my host, going to stop

5:08recording for a quick moment. Okay, I

5:11have rebooted. Now I am inside of Docker

5:14Desktop on Windows. We're going to ahead

5:16and start the Docker engine. I guess

5:18I'll move my face a little bit further

5:19down. Obviously, you could see I don't

5:20know if that's funny. New version is

5:22available. Yeah. Uh, we should update.

5:24I'll talk more about that later, but

5:25let's get this thing going just to show

5:26you it in action. Okay, looks like

5:28Docker on Windows is ready. So, let me

5:31open up a terminal. And do I have the

5:33command on the command line? Docker. I

5:35do. Okay. Excellent. All right. Now,

5:37let's bounce back to the write up and

5:39article for a quick second so we could

5:40see how the pock or proof of concept

5:42worked. The entire exploit takes two

5:45post HTTP calls from inside any

5:48container. Okay, kind of easy. post a

5:50JSON payload to /containers create. Now

5:53again this is like the API for the

5:55docker engine obviously giving us the

5:57capability to create a new container

5:59binding the host C drive to a folder

6:01inside the container like /mounthost C

6:04colhostroot in the container and using a

6:07startup cmd or command to write or read

6:10anything under that host routt on

6:12container startup. Now that we created

6:14the container, you do need to start it,

6:16but that's again just coming from the

6:18API or this connection 192.16868.57

6:22or whatever 2375 was the port. And you

6:24post to the container start endpoint

6:27with the ID of the container that you

6:29just created. That will launch the

6:30container and start execution. And

6:32because this is all webbased, right,

6:35like the fact that you're just making

6:36two post requests, you could do like

6:38with curl or wget or python or anything,

6:42right? uh you could have the opportunity

6:44to do this via a web app like if a web

6:47app were presented as a front-end

6:49application and maybe it was just served

6:52out of a container. Well, if there were

6:54a vulnerability in that application

6:55where you had SSRF or serverside request

6:58forgery, then you could just try to

7:00manipulate any of the capabilities like

7:02use that vulnerability on its own to now

7:04exploit this. They mentioned you don't

7:06need code execution or you technically

7:08don't need code execution because if

7:10there's an opportunity to still make

7:11those web requests without running

7:13commands, this is doable. There's some

7:15really cool lessons here in the spotting

7:17the gap sooner section. At its core,

7:19this is just kind of an oversight

7:20because that internal API is reachable

7:22from any container without

7:24authentication or any other access

7:25control. Good reminder that critical

7:27security gaps often stem from the most

7:28basic assumptions. And look, they found

7:30this just by running end mapap against

7:32the Docker documented private network.

7:34That's easy to do. It's not isolated, at

7:37least as we've learned. So, you could

7:39always test your network isolation and

7:41don't trust that all security models are

7:42aligned by default. Cool takeaways:

7:44internal interfaces are not inherently

7:46secure. Assess every access path and

7:48entry points, both external and internal

7:50tests and scans are essential. And work

7:52with your friends, encourage outside

7:54collaboration, even if that's just

7:55public and private bug bounty programs,

7:57to find these lowhanging fruit things.

7:59Because this is in essence simple,

8:01right? You're just creating a container,

8:02starting it, and then taking advantage

8:04of all the functionalities that Docker

8:06naturally gives you and with good

8:07intentions. Hey, mounting capabilities

8:09from the host, being able to run

8:11commands like that is good. So, it's

8:12just taking advantage of the fact that

8:14this is all possible with just the

8:16hiccup gimmick that oh, we could reach

8:18the internal API without any issue. They

8:21have a little uh proof.mpp4 or a video

8:23demonstration, but we could do the very

8:25same thing. We could try it out and run

8:26it ourselves. Proof of concept can be

8:28executed from any container running

8:30docker run tac it for interactive in a

8:33terminal and they just use an alpine

8:35image. So Linux right vanilla barebone

8:38basics alpine image using bin sh as

8:41their okay invoking command to run or

8:43entry point so that they have a shell

8:45they can interact from. Again not

8:47necessary because if there is an

8:49opportunity for ssrf this could all

8:50still be done. So let's take a look at

8:52this proof of concept that they have

8:54here. Obviously, this is just simple

8:56bash like running from the shell or bin

8:58sh as you ran within Alpine. And they're

9:01using wget, that small command line

9:03utility to be able to work with internet

9:04resources over HTTP. They send a header

9:07to provide a JSON blob. And the post

9:09data that they use is just like you

9:11would expect in any sort of Docker

9:13container configuration specifying, oh,

9:15let's create a new container with an

9:16Alpine image. Again, use a command or

9:18cmd where they invoke sh taxi to provide

9:21a command as an argument. And just as a

9:23simple test, they echo the word poned

9:25into hostroot/pone.ext.

9:28That of course could be anything you

9:29want to read or write files or take

9:32things out of the host machine, put it

9:33in the container or the guest or write

9:36what could be something in the startup

9:37directory for later access, persistence,

9:40post, exploitation, etc. The gimmick

9:42here though of course is using a host

9:44config that will bind or mount part of

9:46the host file system within the guest

9:49container. So the colon here is the

9:50delimiter and because hey you've got the

9:52capability to reach mounted hosts in

9:54/mount/host in the C drive of the

9:58computer Windows host machine in the

10:00directory/hostroot

10:02they don't output anything so t capital

10:04O to a hyphen or just nothing or maybe

10:07that's standard output forgive me we'll

10:08see it when we run it but obviously it's

10:10that exact same IP address and port

10:12number for the internal control plane or

10:15HTTP docker API they staged that as a

10:18temporary file just create.json. So in a

10:21later line, they could retrieve the

10:22container ID. That's that C ID variable

10:25that they set here. They're using

10:26command substitution with just the

10:28dollar sign parenthesis, the cut utility

10:30to use the delimiter of a double quote

10:32field number four out of that file

10:34create.json. And then with that, because

10:37you know that was the key ingredient, we

10:39needed to get to the other HTTP endpoint

10:41for their API containers container ID

10:44and then start it. No post is necessary

10:46there. We just needed to hit that

10:48endpoint with a post request but no like

10:50form data body payload. Does that make

10:52sense? Like we could go through the

10:53process of oh changing this command but

10:55I feel like we're okay. Check out one of

10:57the other previous videos when we were

10:58looking at the winar CVE. You can see

11:00how it might write on the file system to

11:03startup. So that way there's code

11:05execution just the computer begins and

11:07runs. Let's try to use this proof of

11:10concept. But first let's get a docker

11:12image running back on our terminal or

11:15command line. Remember this all happens

11:17inside of a guest container. So let's

11:19try to run tac it for interactive

11:21intelllete on the terminal. Alpine being

11:24the image name that we want to run and

11:26then the command or entry point will

11:27start with /bin/sh.

11:30Will that work for me? Okay, I have a

11:32Linux prompt here. Now I am the root

11:34user inside of this Alpine Linux image

11:37guest container. But if I were to you

11:40know what? Let's open up uh Windows

11:41Explorer. And you know what? Rather than

11:43exposing the root of my file system to

11:45you all on the internet, let me create

11:46just a directory for uh docker cve test.

11:50Obviously, this folder will start empty.

11:52But let's adjust our pock to now write

11:54to pone.ext inside of the host route or

11:58part of the file system where we do have

11:59docker cve test and a forward slash to

12:03note inside of that subdirectory there.

12:04Does that make sense? Let's copy all

12:06this and let me put these side by side

12:08and then let's paste in this command. I

12:11didn't I didn't have to do anything

12:13else. I didn't have to say anything. It

12:14already It just did it. Right. Open that

12:16up in Sublime Text. It's exactly what

12:18you think. Bear in mind, I'm on my host

12:20computer. This is my desktop machine.

12:23And I just wanted to do the little demo.

12:25Light off the fireworks here because of

12:27course we've now broken out of that

12:29Docker container that we were in and

12:31could have the capability on the whole

12:32rest of my machine. That's it. Those

12:34couple commands. Obviously, that is why

12:37this is a 9.3 CVS out of 10 critical

12:40severity. Okay. Uh breakout, escape the

12:43sandbox of a Docker instance. And I

12:45believe that's even beyond their

12:47encapsulated or enhanced container

12:49isolation feature functionality thing.

12:51There are links down below. We could go

12:53take a look at the CVE CV 20259074.

12:57Docker desktop allows unauthenticated

12:59access to a Docker engine API from

13:02containers. Yeah, even with or without

13:04enhanced container isolation enabled and

13:06with or without the exposed Damon on

13:08that instance. Now, this happens again

13:11only on Windows or at least that's what

13:13I've showcased. But if we take a look at

13:15the release notes from Docker, they're

13:18now offering this patch of 4.44.3. And

13:21this was released relatively quickly

13:22from what I understand. That's fixed.

13:24That's patched. But this is affecting

13:26Windows and Mac. If we look at Felipe or

13:29Phillip, I'm so sorry. If we look at his

13:32blog, he covers the exact same thing.

13:34And again, we'll have a link in the

13:35video description. He tells the whole

13:37story, which is kind of cool. A little

13:39bit of the human walk back of how this

13:41was approached. But of course, this is

13:43not going to be affecting Linux because

13:45Linux does not use a TCP socket for the

13:48Docker engine's API. It uses a name pipe

13:51on the host file system. Unless there's

13:52any like super specific unsafe

13:54misconfiguration, the container usually

13:56does not have access to that name pipe

13:58and can't make these internal engine

14:00like control plane calls to the API,

14:02right? But his little MacOSS proof of

14:05concept is done with just simple Python

14:07code and he imports Docker. You can see

14:09the syntax here. Import Docker, create a

14:11new client where you connect to that API

14:14and then run a whole new container of

14:16Alpine being the image. a command to run

14:19touching the or creating the file

14:21/mount/pone where it has now mounted

14:24from what would have been the MacOss

14:26file system/ users and their username

14:28now/mount inside the container neat easy

14:32too easy now here's the thing first and

14:34foremost you should patch you should

14:36update you should get the latest version

14:374.44.3 44.3 would recommend you do that.

14:40But I wonder and I'm curious of your

14:42take. So please genuinely let me know in

14:44the comments. What is the likelihood of

14:46this being exploited? It is within a

14:48container. You don't need the code

14:50execution to be ran within the

14:51container. If there were a forward

14:53front-facing web app that SSRF was an

14:55opportunity or the server side request

14:57forgery vulnerability existed, then you

14:59could sort of chain this or enact and

15:01invoke this via that. Maybe that's a

15:04thing. I don't know how easily you might

15:06be able to fingerprint for what looks

15:07like a web app being ran out of a Docker

15:09container with the old version on

15:11Windows or Mac, but granted that it

15:13should be a Docker container running in

15:15production if it were to be exposed

15:17probably out on the open internet via

15:19Windows or Mac. That seems just a little

15:21unlikely to me. Regardless, extremely

15:24cool, neat find, and I think Felix was

15:26pretty upfront like, "Hey, he stumbled

15:28across this." And him and his buddy, his

15:30friend were trying to go take a look,

15:32see how you could pull that thread. And

15:33that's how a whole lot of sweet fun

15:35security vulnerability research stuff

15:36just tends to happen. Real bummer that

15:38there wasn't a bug bounty or anything uh

15:40sort of a payout for him, but I think it

15:41sounds like he's getting a sweet merch

15:42bag. So cool. But there you go. You

15:44know, that's it. That's what everybody's

15:46screaming and shouting about for uh this

15:48big Docker 9.3 critical severity CVE

15:5120259074.

15:53Patch your potatoes, everybody. Thank

15:54you so much for watching. Please do all

15:56those YouTube algorithm things. Like,

15:57comment, subscribe. I'm going to go

15:58remove the uh vulnerable version of

16:00Docker that's installed on my host

16:02desktop machine. Uh, thanks. I'll see

16:03you

More from John Hammond

All 86 transcripts from John Hammond

Recently added transcripts

Browse the whole transcript library Browse all English transcripts

This transcript was generated from the captions YouTube publishes for this video. Get the transcript of any YouTube video atfreeyoutubetranscribe.com, free, unlimited, no sign-up.