HomeVideos

The Worm that changed everything

Now Playing

The Worm that changed everything

Transcript

490 segments

0:00

November 2nd, around 6:00 p.m. Pacific

0:02

Standard Time, the worm is unleashed on

0:05

an MIT computer. Within the hour, the

0:07

University of Pittsburgh receives the

0:09

worm. Within 3 hours, Stanford and the

0:11

University of Minnesota has the worm.

0:14

Within 4 hours, Berkeley, Princeton,

0:16

University of North Carolina, and the

0:18

University of Maryland has the worm.

0:20

Within 5 hours, MIT, University of

0:23

Maryland, Dartmouth, and the University

0:25

of Utah are infected. By midnight,

0:28

University of Arizona, Princeton main

0:31

computer, and the University of

0:32

Delaware, UCLA at 1:00 a.m., Harvard at

0:36

2:00 a.m., University of Chicago by 3:00

0:39

a.m. it got fingered. Colorado State and

0:41

Purdue were next to fall, then finally

0:44

Georgia Tech. All of this within 13

0:47

hours. That represents about 10% of all

0:50

connected computers. To put this into

0:52

perspective, if that happened today,

0:54

that'd be about 1 billion computers and

0:57

smartphones infected within 13 hours.

1:01

This was a massive event in 1988. The

1:05

world's smartest people from Harvard,

1:07

Stanford, MIT, and NASA got together,

1:09

decompiled the worm, and understood how

1:12

it worked, which led to the arrest of

1:14

Robert Tappan Morris 6 months later. And

1:17

6 months after that led to the very

1:20

first arrest of the Computer Fraud and

1:22

Abuse Act. Now, you're probably

1:24

thinking, "Okay, Morris, he must have

1:26

been like tossed in Arkham Asylum at

1:27

this point." Infecting 10% of the

1:30

world's computers? No, actually, he just

1:32

got a little bit of probation, started

1:33

doing startups with Paul Graham, and

1:35

co-founded one of the biggest worms of

1:36

all time, Y Combinator, spreading

1:39

through the minds of young,

1:40

impressionable founders. At the time of

1:42

the worm, not everybody was impressed by

1:44

what actually happened. In fact, some

1:45

people said that Morris, kind of a

1:48

rookie. Many people have stated that the

1:49

author of this code must have been a

1:51

computer geniuses of some sort. I have

1:54

been bothered by that supposition since

1:56

first hearing it. And after having

1:58

examined the code in some depth, I am

1:59

convinced that the program is not

2:01

evidence to support any such claims. The

2:02

code was apparently unfinished and done

2:04

by someone clever, but not particularly

2:06

gifted, at least in the way we usually

2:09

associated with talented programmers and

2:11

designers. Bro, this guy is legitimately

2:13

this meme right here, okay? Man infects

2:16

10% of all connected computers, and the

2:19

guy's like, "Yo, that [ __ ] guy sucks.

2:21

He doesn't even know what he's doing."

2:22

Incredible. So, we're going to break

2:24

down the worm actually going to go over

2:25

all the code because it is spectacular.

2:28

I cannot believe how amazing the code

2:31

actually is and what it does. It's so

2:33

incredibly simple and so easy to

2:35

understand, yet at the same time just

2:37

blows my rookie mind. And yes, I am

2:41

technically impressed. There's

2:43

deception. There's some of the funniest

2:45

things ever. There are bugs that make

2:47

the worm worse for the people that get

2:49

infected. It's hilarious.

2:51

But before we break down this worm, we

2:53

got to break down the sponsor. Thank

2:54

you, sponsor. Did you know that I've

2:56

done a lot of weird stuff that's

2:58

difficult to explain to my

2:59

father-in-law, such as building a tower

3:01

defense game in a water tower,

3:04

pretending to be Mark Zuckerberg in a

3:06

social network parody in SF, by the way,

3:09

stands for San Francisco, or even did a

3:11

live Super Smash Brothers event at

3:13

OpenSauce?

3:15

>> [cheering]

3:16

>> Well, if you didn't know those things,

3:17

you should just go check out the

3:18

Terminal channel. That's where I do all

3:20

the fun group videos. Check it out.

3:21

Links in the description. All right, so

3:23

to begin, I think it's best to say, why

3:25

is it called a worm, right? Because we

3:27

hear this term worm, but have you ever

3:28

thought about why is it called a worm?

3:29

Well, it actually comes from a novel

3:31

called Shockwave Riders in 1975.

3:34

In the novel, it had this idea of

3:36

tapeworms that would go through the net.

3:38

Effectively, if you killed part of the

3:40

program on one computer, the worm, the

3:42

tapeworm, could survive because it would

3:44

replicate itself across of other

3:46

computers. And so, you couldn't just

3:47

kill one of them. You had to kill all of

3:49

them to kill it. And that's exactly what

3:51

this famous Morris worm is. To put it in

3:53

a nutshell, there is a small program

3:55

that runs and all it really does is

3:58

first decides, do I need population

4:00

control? It figures out if it needs to

4:02

kill itself or not. Next, it's simply

4:05

going to go and try to find all the

4:07

things that are connected to it so it

4:08

can go and spread itself. Then it's also

4:11

going to do some local password cracking

4:14

of accounts that exist on the system and

4:16

see if it can kind of just guess some

4:17

passwords. And it just sits there and

4:19

does these two in a loop over and over

4:21

again if it wasn't killed by the

4:23

population control. But who cares about

4:25

the diagrams, okay? We want to look at

4:27

some C. That's what everybody has always

4:29

said to me. It's the famous phrase,

4:31

"Just show me the C already." All right,

4:33

so the worm effectively has a main loop.

4:35

The main loop you can think of like a

4:36

game loop. It just goes and it does a

4:38

series of actions, restarts and does a

4:40

series of actions. The first thing the

4:42

worm does is attempts to spread itself.

4:44

This makes sense because if it gets

4:45

caught pretty quickly, it wants to have

4:47

a chance to jump to another machine. So

4:49

whenever you see HG or HL or HA, any of

4:51

those weird H functions, just know

4:53

that's it going and attempting to spread

4:55

itself. The second thing it does is it

4:57

goes and sees, "Do I need to do

4:59

population control?" Now, population

5:01

control is extremely clever. So the

5:04

first thing it checks is, "Hey, random

5:06

one out of seven chance, you're an

5:08

immortal worm. You don't get killed

5:10

unless if somebody kills the program.

5:12

You just exist." Now, if it's not one of

5:14

the lucky one out of seven, the chosen

5:17

worms, instead it attempts to connect to

5:19

a local server on port 23357.

5:24

Obviously, you should be able to clearly

5:25

see that. I mean, if you're not doing

5:27

hexadecimal conversions in your head

5:28

instantaneously, you're not going to

5:30

make it. For whatever reason, if it

5:32

can't connect, it just simply closes

5:33

down and it continues on. But if it does

5:35

connect, it then does a little battle

5:38

royale with the worm that it connect to.

5:40

Now, this local server is just another

5:42

worm. There's a server worm and then

5:43

there's client worm. To make the battle

5:45

royale easy, I made this quick little

5:47

animation. Effectively, they exchange

5:49

keys to prove who they are. Client sends

5:51

a random number, server sends a random

5:53

number. Both the client and the server

5:55

add the two numbers together, and if the

5:57

number is odd, the server goes, "Oh, I'm

6:00

the one that needs to die." If the

6:02

number is even, the client goes, "Oh,

6:04

I'm the one that needs to die." And

6:06

that's what all this code is right here,

6:07

the exchange of the two keys and the two

6:09

random numbers, the two comparisons in

6:11

determining, "Do I or do I not quit?"

6:15

Funny little bug number one, if any of

6:17

these operations fail, the worm becomes

6:20

immortal. It just simply returns, never

6:22

checks to see should it kill itself ever

6:24

again, and the worm becomes immortal.

6:25

This is one of the reasons why the worm

6:29

infected faster than Morris intended.

6:31

The surviving client worm will then go

6:33

and attempt to become the server itself.

6:35

If becoming the server fails, which by

6:37

the way, reconnecting and recreating a

6:39

server within 5 seconds, that can often

6:41

fail cuz the port could be busy.

6:43

Therefore, accidental immortal worms

6:46

again. And this is effectively just how

6:48

population control works. Either one out

6:50

of seven worms makes it, or a client and

6:52

server battle royale and just one of

6:54

them lives. That way, it doesn't go too

6:56

fast. It doesn't spread super, super

6:58

fast. And this makes sense. Remember how

7:00

I told you the first thing it does is

7:01

attempts to go and infect other host

7:04

right away. You can imagine you have a

7:05

server that goes and hits the client,

7:07

and then this thing creates a new worm,

7:09

which then connects to the server and

7:10

creates new worm, which connects to the

7:12

client, which creates a new worm, which

7:13

connects to the server, and creates a

7:15

new worm. So, there needs to be a way in

7:17

which these worms don't just

7:18

instantaneously go to like a kajillion.

7:20

That's why there's the one out of seven

7:21

chance for worm immortality. So, after

7:25

the worm survives, it does just the

7:27

funniest thing. Now, this was clearly

7:29

used to kind of trick people. This

7:32

report bit break-in, which I believe the

7:34

original function's name was send

7:35

message, it would just send a single

7:37

byte diagram, one out of 15 chance, to a

7:41

address called ernie.berkeley.edu.

7:45

That way when people decompiled the

7:47

program they're like, "Who's that son of

7:48

a [ __ ] Ernie over at Berkeley? We got

7:50

to go find Ernie and we're going to go

7:52

arrest his ass." Ernie had nothing to do

7:54

with it. This is just a fake little way

7:57

for the worm to phone home but not

8:00

actually phone home at all because when

8:02

you inspect the code you will notice

8:04

that it doesn't send the proper packets.

8:06

It creates a TCP connection and sends a

8:08

UDP packet. Thus not working at all.

8:11

Still one of my favorite parts of the

8:12

code. Absolutely love this. It's so

8:15

funny to put in some like smoke and

8:18

mirrors into the code so that the

8:20

decompilers actually go on a wild goose

8:22

chase. And dude, pour one out for Ernie.

8:24

Ernie, respect. After the worm is done

8:27

phoning home, it then goes and attempts

8:29

to crack some local passwords. Now it

8:31

just has a big old table of about 432

8:35

uh favorite basic uh passwords including

8:37

the classic banks and bananas. Uh and

8:40

Aztec and as you were, is that

8:43

Microsoft? By the way, the password list

8:45

reminds me of my favorite PR of all

8:47

time. Remove my password from the list

8:49

so hackers won't be able to hack me.

8:51

Dolphins.

8:52

Dude, I love it. I love this so

8:55

I love this PR so much cuz I really do

8:58

hope that this is not somebody trolling

9:01

but it's actually somebody being

9:02

serious. Like, "Bro, why would you put

9:04

my password in this list? Okay, I want

9:06

the dolphins are mine, buddy." I mean, I

9:08

know it's not that but in my heart of

9:10

hearts I kind of hope it is. Either way,

9:12

it just did a little bit of password

9:13

cracking. Now it didn't try to crack all

9:15

the passwords because back then and even

9:17

today when it's running the cryptography

9:19

and running against stuff it actually

9:21

takes a little bit of time and it

9:22

actually takes quite a bit of CPU. So

9:23

cracking one password could take up to 5

9:26

seconds per attempt. So it didn't want

9:28

to just block and cause a whole bunch of

9:30

CPU threads. So it would do a couple at

9:32

a time. And it would back off and okay,

9:34

I am I'm doing any of that. And you can

9:36

see that right After it cracked a few

9:38

passwords, it would just go to sleep.

9:40

I'm not I'm not causing any problems,

9:42

sir. Mister Mister, it's not me. If you

9:44

happen to hit top at that point, you

9:45

just wouldn't see the worm at all. Now,

9:47

time for the main loop. The main loop,

9:49

of course, starts off with little local

9:51

password cracking. The reason why this

9:53

would happen is that it needed to store

9:55

up a list of username and passwords that

9:56

it had cracked because it could

9:58

potentially be used on remote machines,

10:00

thus making spreading faster and easier.

10:03

Next, it would fork itself and then exit

10:05

the current process. Now, the reason why

10:07

it would do this is that way the PID

10:09

would constantly be changing. Every few

10:11

minutes, a new PID would be added to the

10:13

system and the current PID would be

10:15

killed. So, any kind of looking at past

10:17

CPU usage would show a program that no

10:20

longer existed. Extremely smart. Then

10:22

again, it does this remote checking.

10:23

Now, I think I should probably dive into

10:25

this remote checking here for a second,

10:28

but you can imagine the remote checking,

10:30

you know, it needs to figure out how to

10:31

hack stuff. Now, back in the day,

10:32

there's this thing called remote shell.

10:34

Effectively, if you were Berkeley and

10:37

you wanted to go and talk to MIT, you

10:39

could just simply remote shell over

10:42

there. They were trusted laboratories

10:44

with each other. Imagine SSH and having

10:47

an RSA key, except for it works for like

10:49

an entire department. And so, the worm

10:51

would often take advantage of remote

10:53

shell and start a remote shell on some

10:56

sort of client far away. If that didn't

10:58

work, it'd use something called fingerd.

11:00

This is something to go look up some

11:01

information about a user, but it turns

11:03

out if you sent an extra 24 bytes and a

11:06

new line, it would end up turning

11:07

fingerd into a shell session. And

11:10

lastly, if that didn't work, it'd use

11:11

sendmail. And if sendmail in debug mode

11:14

works, because most sendmail at that

11:16

time was actually compiled to have debug

11:18

mode on, you could send some debug

11:20

commands and just spawn a shell

11:22

effectively for yourself right away. So,

11:24

that is how the worm spread, which was

11:26

mostly through trust. Like people had

11:28

debug things up. People had remote shell

11:30

just sitting there where anybody could

11:32

log into any system.

11:34

You could see why Morris could easily

11:37

take advantage of things. Again, to make

11:39

itself look like it's not doing

11:40

anything, it sleeps for 2 minutes, makes

11:41

sure it's really quiet, nice and quiet,

11:44

and then lastly, it will automatically

11:45

quit if it was part of the kill command

11:48

or the population control. But you'll

11:49

notice that there's this net W right

11:51

here. Well, it turns out that if it

11:53

hasn't cracked 10 passwords, then it

11:56

wouldn't kill itself. So, it actually

11:57

minimally does a couple checks before it

12:00

kills itself. So, the worms would last

12:02

for a while before actually killing

12:03

themselves. All right. So, now we need

12:05

to go back into this cuz I've kind of

12:06

glossed over this whole like just go and

12:09

spread yourself time, right? Cuz this is

12:11

actually where it gets so freaking cool.

12:14

Holy cow. So, there's this line inside

12:17

the server. Once it finds a way to

12:19

create a remote shell that it can send

12:21

commands to, it sends this command right

12:23

here. It compiles a very small C program

12:27

on the client. So, I'm going to use the

12:29

term client meaning the thing the worm

12:31

connected to and server being the worm

12:33

itself. So, if you look right here, it

12:36

does the compilation of this little

12:37

script. The next thing it does is it

12:39

actually executes the script and says

12:41

like, "Hey, this is where I'm located as

12:43

the server. This is the port you need to

12:45

connect to, and here's the magic number

12:47

you need to provide me so I know it's

12:49

you and not somebody trying to figure

12:51

out how it all works." When this thing

12:52

gets done executing, it will remove any

12:54

evidence of itself, and then finally, it

12:57

will actually do this little echo done

12:59

right here saying, "Hey, I'm done

13:00

executing." After sending over this

13:02

command, the server, the server worm,

13:05

the one that's spawning the new worm,

13:06

just waits for done to happen, which

13:08

means that this program right here needs

13:10

to get done executing. Now, how does

13:13

that work? This is kind of the confusing

13:15

and also part of the super awesome part.

13:17

So, we jump over to this little worm

13:19

file. This is not the actual worm, it's

13:21

the worm spawning program. This is part

13:23

of the reason why I said it's so

13:24

awesome. So, the first thing it does

13:26

when the worm spawns, is it unlinks the

13:29

executable that created it to run in the

13:31

first place. The next thing it does is

13:33

it forks itself. That way, there's

13:35

actually two of these little header

13:37

programs running to be able to spawn the

13:39

main worm. If it failed forking, it

13:42

exits with an a good exit code. Hey,

13:44

that's good programming right there.

13:45

Just letting everybody know, whoopsie

13:47

poopsies, the worm failed to worm. Else,

13:49

if you're the one that forked the

13:51

program, you'll actually get an I

13:52

greater than one. Therefore, the forker

13:55

is the one that kills itself. Now, by

13:56

killing itself, you may remember the

13:58

waiting for done can happen because this

14:00

little program right here quits running.

14:02

We then delete all the evidence, and

14:03

then we echo done. This thing receives

14:05

the done, and now it can do this wait

14:08

hit part. Wait hit simply already has a

14:11

server running, and it's ready to send

14:13

the worm to whoever asks for it. So, the

14:17

little header worm on the client machine

14:19

goes, connects to the server that it

14:21

received as part of its arguments. It

14:23

then proceeds to zero out all of its

14:25

arguments, so you couldn't just like PS

14:26

aux it, so you wouldn't even know that

14:27

there was arguments there. It then

14:29

connects to the server, and then

14:30

replaces standard in and standard out

14:33

with the TCP in and out. So, it can

14:36

actually communicate to the server via

14:38

its standard out. It then writes out the

14:40

magic string, so that way the server

14:42

goes, oh yeah, okay, you're a real worm.

14:45

I know who you are. And then proceeds to

14:48

read until it receives all the C program

14:51

required to be able to run the real

14:54

worm. And And this is where it does

14:55

something that's so cool. Remember, it

14:58

has a TCP connection. It has then made

15:01

its standard in and standard out hooked

15:03

up to the TCP connection, and then it

15:05

does this exact L. What exact L

15:07

effectively does is it replaces the

15:09

current running process with whatever

15:12

you give it. So, in this case, it

15:13

actually spawns a shell, and this

15:15

process becomes the shell, and then the

15:17

in and out is already hooked up to the

15:19

TCP connection. So, the server can now

15:21

run commands against this running shell.

15:25

Tell me that's not pretty cool. Come on.

15:27

That's pretty dang cool. So, what does

15:29

the server do? Hey, go run that worm I

15:32

sent you, buddy. And boom, we're back

15:35

into the main loop. We're going to go

15:37

check for some remote hosts. We're going

15:38

to go check, do we need to do population

15:40

control? We're going to go call Ernie.

15:43

Poor Ernie just getting absolutely

15:46

bamboozled here, man. Again, pour one

15:48

out for poor Ernie. And that's how the

15:50

worm works. This was just a miracle. I

15:54

cannot believe it works. It is just It's

15:57

like out of science fiction. And the

16:00

code is relatively easy to understand.

16:04

If you want to go check out the code

16:05

itself, you should definitely jump over

16:06

here onto the Morris worm malware. Don't

16:09

ask Fable though to convert it to rust

16:12

for maximum safety because

16:14

that's unsafe to convert the worm that

16:16

everybody knows about from 1988 into

16:18

rust, buddy. What are you, a hacker?

16:21

Huh? You hacking, buddy? Don't make me

16:23

write you a formal citation. A lot of

16:25

the research and understanding of the

16:26

worm actually comes from this beautiful

16:28

PDF, which you can go download and will

16:30

be linked down below, called the tour of

16:32

the worm by Don Seeley. Incredible work.

16:35

Now, if you like this video, then you

16:36

should press the like button or press

16:37

the subscribe button. The reason why is

16:39

that I see metrics and I can see that

16:40

people really enjoy this. I enjoy making

16:42

this video. Do you enjoy watching this

16:44

video? Cuz I enjoy making this video.

16:46

So, send me the signals, people. The

16:48

name is I can't believe the exact L

16:51

part. That part just blew me away the

16:53

most by hooking up the TCP connections,

16:55

wiping out all the previous file

16:56

descriptors, and then converting

16:59

yourself into a shell program, you allow

17:01

the server to effectively have shell

17:03

access. Kaboom! That was absolutely

17:07

incredible.

17:12

Ajen.

Interactive Summary

The video analyzes the technical mechanisms of the infamous 1988 Morris worm, which infected approximately 10% of all connected computers at the time. The author walks through the worm's C-based implementation, including its 'population control' mechanism to prevent runaway replication, its deceptive 'phone-home' functionality that attempted to frame a user named Ernie, and the sophisticated way it exploited trust in systems like remote shell, fingerd, and sendmail to spread. Finally, the host highlights the ingenious use of `exec` to turn process execution into remote shell access.

Suggested questions

3 ready-made prompts