Now, this all seems very nice and handy.
But, I want to show you some of the security problems
that can arise.
If you're not careful
and I should add these are all very well known.
If they are not fixed on your system,
you have much more serious things
to worry about than Secure Programming.
Let's go to the next slide.
This was called Shellshock and
it created quite a stir when it was released.
This is peculiar to the bash shell.
As I mentioned earlier,
it accepts definitions in environment variables.
For example, here gleep
is a function that will simply print OOPS.
In your environment variable list,
you define gleep as is shown there.
() { echo OOPS;
} Then you type
export-F gleep to make it available to the environment.
When you type gleep,
it will simply print
OOPS because that's what the function tells it to do.
But it turns out the next slide
describes a very bad bug and bash.
On startup, it loads
all environment variables which are defined
in a startup file typically
but may also be defined elsewhere.
Then it looks for things that look like functions,
and then it interprets functions in that way.
It evaluates the value, the whole value.
In this case, the export,
the line that begins with export shows the definition
of gleep that also has Gotcha after it.
If you'll notice that.
When you execute gleep,
it first evaluates the whole line and says,
"Okay, the echo "Gotcha!" I print gotcha."
Then, I will go ahead and execute
the function which is OOPS.
It does what follows
the definition before it executes the function.
Yeah and that's problem.
It turns out by appropriately setting
the second part- the instead of saying echo "Gotcha!"
By setting it to other things.
You can cause the shell to do things
that's not expected when some poor innocent victim
executes F function.
This is similar to changing
the value of a variable from something that's
expected to something that's not.
The next slide shows a much more direct example of this.
Essentially, what you do as an attacker,
or what an attacker will do is say,
"Well, what does the program expect?"
Then, if I give it something else, what happens?
Here's a very good example of it.
You'll notice here that PATH is set with
dot as the first element- first value.
PATH here has four directories in its list
when its value..:/ bin/usr/bin:/etc;
and they're separated by colons.
In some shells, notably the seashell,
it would simply have these as a list with spaces
between them but bash SH and other shells use colons.
The export says, "Make these available to sub-commands."
I think create a file called Mail.
In this file called mail,
I simply have it copy the shell
to have that file known as.xxx.
Then, the chmod changes
the protection mode so that anyone can execute it.
It sets your ID to me.
Which if you recall from our earlier discussion,
means that whoever executes that program,
it will run with my rights.
Now, when I execute the program mail,
it will run my version of the program.
What will happen is,
it will go ahead and create
this privileged command environment.
Now the trick here is to place this
somewhere where an administrative user would
normally look and have them
and check to be sure that
their environment variable path begins with a dot.
In that case,
I'll get a command interpreter
that gives me their privileges.
By the way, an interesting variant
of this is simply to misspell the name.
The reason that works is that dot is often
put in this path but at the end.
On the theory that,
if I put a program like
this mail into the current directory
and the administrator is in that directory.
If the administrator types mail,
they'll get the system version rather than mine.
But suppose the administrator is
a lousy typist and switches the I and the L,
so it comes out M-A-L-I.
If I happen to have that program,
instead of saying no such program,
it'll go ahead and execute mine.
LS is the one that is most commonly done for because
that's the easy one to mistype this SL.
You can also ask well,
"What is the interesting variables?"
Here's a good one for X windowing environment.
For example, norm uses it anything that uses X11.
The value of display is the name of
the display that X will do its magic on.
That it will draw windows on and accept commands from.
Now, the way it's used is typically you'll
read a value into that display. You'll set it.
Then, you'll export it and run
the X program and the X program in this case,
xload which shows you the load average of the system,
would simply write its output
to whatever display was set to.
This is often used in remote execution
where you supply the display
and the program will then execute.
But instead of just supplying a display,
let's supply something a little
more interesting and useful.
If you'll notice what the line with DISPLAY= is set to,
if first of all it would set the displayed to
zero and then execute
the command mail me@remote copy of
your.rhosts file or.shosts file or whatever file.
In any case, what happens is,
when the X environment loads display,
if it executes- if it's going to put that into
a command line which it typically
doesn't then execute the program,
I'll get a copy of the file you named.
With.rhosts or.shosts now we know which hosts you trust,
and if I can impersonate them, I would get in.
Now, the next slide points out
an interesting quirk of
environment variables and how they're handled.
Let's say you have two
environment variables with the same name.
In other words, path occurs
twice in the environment
variable list with two different values.
I'll show you how to do this in a moment.
But let's just say for the moment that's done,
which one does the shell use when it looks for commands?
The first one or the last one?
That's an interesting question.
Again, we'll get back to that in a moment.
But basically difference in command interpreters.
Some go from the front and get the first one,
others go from the back and get the last one.
Now, how do you do this?
If you try to do it from the command interpreter,
when you enter the new value,
it'll wipe out the old value.
So, that doesn't work.
But what you can do is write
a program and set the environment variables that way.
Now, if you use getenv,
you're going to have the same problem.
It'll wipe out the previous value.
But what you can do is use one of
the exact family of functions system calls,
and that allows you to
specify the environment variable list.
So, when you specify that list,
put the same variable name in there
twice and just give them different values.
That's what this slide does suggest.
The next slide shows exactly what the problem is.
Some shells use the last value.
So, if you scan from
the beginning and stop at the first match,
you may think value uses one thing,
but the command interpreter may use
the value for something else.
So, again, the confusion
here sometimes allows you to insert
bad values for environment variables
and depending on which shell
or which program you look at,
you may not see it.
Now, how do you use environment variables?
Well, here's a fun little attack
that was launched I think in the '80s,
but anyway, it's rather fun.
Vi is an old version of them.
It's actually the ancestor to them.
It had a very nice feature.
If you were editing a file
and the line dropped, in other words,
for example you disconnected from
the network session in which you
were doing the editing or in those days,
if you connected over the phone lines
and sometimes phone lines just disconnected,
well, vi would say,
"Well, I don't want you to lose your work.
So, what I'm gonna do is save it in
a buffer that you can later recover from."
So, it would run a privilege program
called expreserve that would grab
the contents of the buffer
you were editing and save it in
a protected area that only
the administrator could access.
It would then run the mail program and send you
a letter which said in essence, "Hi.
I'm your friendly vi editor.
You disconnected or something went wrong.
But don't worry, I've saved
everything you've done and to recover it,
type vi dash r and then the name of the"- it'll
give you the buffer name. So, that was a good thing.
Well, a couple of us ask, "Where's the privilege?"
The editor is not setuid to root.
So, the editor runs with
your privileges not the administrator's,
and a fun question to think about is, why?
What would happen if the editor
ran with the administrator's privilege?
It doesn't. No editor does
unless the administrator is running it, of course.
So, in order to write the buffer to that protected area,
expreserve had to be privileged.
It had to be setuid to
root and mail is run by expreserve.
So, if you remember from the previous lesson,
unless expreserve reset its ids,
mail runs also with root privileges.
So, on the next slide,
we show the first attack.
You create as earlier,
a program called mail in the current working directory.
In this case, we copied
the command interpreter and then made it privileged so
that it would run setuid to the owner.
Then what we did was we made
the mail file executable
and put dot at the beginning of the path,
made that available to the command interpreter,
and then we ran vi and disconnected.
So what happens? Expreserve fires up and it saves
the file that we had been editing in
the buffer area in the protected area,
and then it executes the mail program.
Well, since dot is the first thing in the path,
unless expreserve resets that path,
it's going to get the mail file we just created.
The mail file copies the shell into
the local area and makes it setuid to the owner.
Well, expreserve is running as the administrator,
so mail will run as the administrator so that shell will
be copied by the administrator
and owned by the administrator.
So, the second line in that mail program,
the third line rather,
will make the shell setuid
to root so now I have administrator privileges.
Not a good thing to do.
So, the way we fixed it initially was,
we went into the source code for vi and found the line,
went to expreserve rather, not vi,
and found the line where it
actually issued the mail command,
and that was the popen one shown on the next slide here.
Now, if you'll notice,
the first argument to popen is simply mail user.
Well, that gets given to
the shell so it looks for mail using the path.
So, if you change it to bin mail with the slashes,
that causes the shell to ignore
the path and it will go ahead and
execute the system mail program.
Done. Not quite.
It still uses the Bourne shell to do this.
So, the next thing we asked was, well,
can we change the meaning of that string,
bin mail, so it means something else?
And we looked and we found an environment variable called
IFS which stands for Internal Field Separator.
The basic idea there of
IFS is to make P programmers' lives easier.
For example, if you're reading
a file where the fields are separated by
colons and it's sometimes much
easier to work with blanks as
separators rather than colons,
you can set IFS to be colon.
Then when you read the various fields one at
a time or you read the words of that line one at a time,
instead of giving you everything up to the next blank,
it'll give you everything up to the next colon.
So, in essence, it's a word separator.
It separates words on a command line.
Well, that seems tailor-made for this.
What happens if you put IFS
equal to slash as well as space,
newline, and so forth?
Well, the next slide shows exactly what we did.
Same program as before,
but instead of calling it mail, we called it b.
What we then did was set IFS to be slash i,
then tab, new line,
and blank, and saved.
Then, we made sure path had dot as
the first thing in the path.
So, now when you run vi and hang up, it calls expreserve,
expreserve calls mail using
the string slash bin slash mail.
But slash is now treated as
a word separator and i is as well.
So, that's seen as b,
the command b followed by nma,
and the next i separates the word,
and so the third one is l. When
the expreserve runs to save the buffer and send me mail,
it of course gets my program b.
So, let's move on here to
another type of attack that caused
a major change to many
of the kernels but it will show you
exactly what happens when you're not careful.