Dear viewer, these subtitles were generated by a machine via the service Trint and therefore are (very) buggy. If you are capable, please help us to create good quality subtitles: https://c3subtitles.de/talk/567 Thanks!
Welcome, everyone, to this talk.
Welcome to everyone who is watching on
the livestream or listening, it's great
to see you in this big hole.
Our next guest is FIFA.
FIFA is a security consultant.
Security consultant.
He's also the co-founder of
the company called Plower, it's
specializing in security concepts
and favor belongs to the CCC
inventory, kind of like the down time
of the wiki
for those who are not from Germany.
FIFA has a little blog
in Germany,
a little and pretty
really tiny, really tiny.
Not many people read that.
Or
can we change the subject?
I do want to say, though, that this blog
is the only Web site that comes up
when you and you when you go into
the Berlin Ubon in the Metro.
So this is the fastest loading time of
all Web sites.
And will talk today about
programs that sandbox themselves
and why that is a good idea.
So in this talk check, your privilege
is how to drop more of your privileges
to reduce attack surface.
Please help me welcome FIFA.
Good morning, everyone, thanks for
showing up.
So this talks about how
you can write your own programs,
so even if they are exploited
because you have a bug in them, the
damage is still limited.
And the idea for this is pretty old.
It's probably older than than
when I blogged it in 2007.
But this is the first mention of it I
found in my own blog.
So I've been I've been working on this
for a while or at least thinking about
it. And now the
building blocks have come into place.
So I can show you how
to do this now.
But before we start, let me make one
thing clear.
This is not something you do instead of
making your code good in the first place.
This is something you do after you
make sure the code is good.
It's it's like an insurance.
It can save your ass.
But if you're negligent, then
they won't pay. All right.
So basically,
I'm trying to to show the
problem I'm trying to solve first.
So basically, when you plan software, you
think of it like this and
when it's written, it's more like this.
Basically, we depend on lots of code with
bugs in our daily lives,
and many of those bugs are security
bugs.
And if and if someone tries to
attack something, it's usually something
that has more access rights
than the attacker in the first place.
And when the attack succeeds,
the attacker has gained some privileges
in the system.
So how can we solve
this problem?
And the the obvious idea is that while
make sure there are no bugs in the code.
It's not that simple, it turns out.
The second obvious idea is to
reduce the exposure of your code, make
sure it's on the Internet as a typical
thing people used to say for a while
and make sure it's only reachable
via https after authentication.
So, you know, only people with accounts
can attack you,
which may not
lessen the burden.
A lot of just say, an email provider,
because, you know, everyone can have an
account or maybe
it's an internal micro service and it's
not visible from the Internet
or, you know, it's behind seven proxy's.
Or, you know, people can come up with
pretty wild scenarios.
But no matter what you do, all you can do
is reduce probability of
a hack. You don't rule it
out entirely.
So even if you do all this,
you can still get exploited.
So what can we do to make exploitation
harder?
This is where most of the research right
now is focused.
You can have unexcusable stack, which
is pretty standard these days,
you can have cookies on the stack,
you can have a hardened teeb all those
are standards to SLR
and position independent executables.
Rod protection is kind of the new thing
that people are trying to
make a standard.
You can ban dangerous APIs, which is a
good idea. You can train developers
can have a bug bounty.
That is a good idea too.
If you have them cash lying around,
you can run the code on some architecture
that you hope nobody knows how to
exploit.
But in the end of the day, it's just the
reduction of the risk, it's not actually
you can't really sleep sound.
And the idea I'm going to talk about
today is that maybe you can put your coat
in a straight jacket and draw privileges
so much that even if someone can
find the bug and exploited the excess,
they gain is minimal or nonexistent.
Basically, the less the court can do,
the less the attacker can gain by
attacking.
However, there is a massive difference
between what the court can do and what
the court actually does.
So I'm talking about what the court can
do.
This is not about well, I'm not I'm not
writing files anywhere, so I should be
safe.
No, if someone gets killed execution in
your process and that process can write
somewhere, then that's a problem.
So this is not about what your court
actually tries to do, but
what it could do with the privilege
level. It's running us in the operating
system.
The Paul sexploitation attack is not
limited by what the court was trying to
do. This is very important to understand.
Basically, if you run something like,
say, Ping, it's a satellite program
on your next, then
the service or like an HGP demon
or any any system service, basically,
it's usually running a super user
traditionally, and the
super user has all the access in the
system. So this is really bad.
The obvious first step is to reduce
this a bit.
So this is what the super user can do.
The next step is you drop privileges.
So you run as a normal user in
the system and you still have a lot of
privileges.
But it's better.
And this talk is about maybe we can drop
privileges some more.
And the service can only really do
very tiny things in the system.
That's the idea.
Common patterns for achieving this are
the drugs privileges and then you do all
the really hard and dangerous stuff in
the beginning. Then you drop privileges
and you hope that the buck that the
attacker will find in the cold after your
drug privileges.
And this may be a sound assumption, but
it may not be.
So this is kind of risky.
But it's a common it's a common way to
approach this and the next way
to approach this, I'm going to talk about
all of this in detail.
It's called privilege separation.
When you split up your process and
you remove the dangerous part in a
separate process and make sure that
process can't really do anything.
And another thing that's usually done
is if if you're really helpless because
the you can't trust the app and it's
really big, you put it in AVM or
maybe a container or a jail
and you hope that these mechanisms will
constrain the explosion of it.
But maybe the app can confine itself to
and this is an idea that's pretty new.
I think it's only been
gaining traction in the last few years,
as far as I know.
Oh, and there's a broken service, which
is a common, common idiom.
You split up your due process
and you make sure, for example, the left
half of the process can
open files, but it can talk
to the right half and the right half can
open files. And if the left half wants to
open and file, it asks the right half.
And this is very small piece of
code. So it can be more
sure that it's safe.
Dropping privileges is generally
understood as dropping them for good.
So the idea is you can only go down and
privileges, you cannot go up again and
practice. That's not as easy as
you would think.
So traditionally, what we did
is we only look at dropping privileges
for privilege processes, we say,
well, if it's running as some use I.D.,
we don't care, that's already pretty
safe.
So this is where traditionally the idea
of dropping privileges comes from, that
you I.D. programs or programs
starting as rules and common examples
of this are paying because it needs raw
succored access and that's restricted to
the super user and the service
used to be running security.
Nowadays, there's other ways to do this
because it needs access to the raw
graphics hardware.
And the third is, extern, which
used to be Sajadi route because it needs
to create to try.
And not only the super user should be
allowed to do this.
Basically the idea, again, is to do the
privilege stuff first and then
drop privileges and hope that all the
attacker can do is attack you after that.
Privilege, separation.
I think the term comes from the
openness of people or basically
the open vista
community has has
imprinted this term.
They invented the concept.
As far as I know.
The idea is to split up your process.
So let's say you have this hugely complex
crypto and passing code that does the
access age low LOW-LEVEL protocol
parsing. And you don't you think it's
safe, but you're not really sure.
So you put this in a separate process
and that process is confined to
a small, empty part in the file system
and you make sure it can't
do anything except passing the protocol.
And then if anything blows up, it's only
that part that blows up and not the whole
thing. The whole thing can do diagnostics
and say, oh, someone tried to hack
me.
The other idea was the the admin
confining a nap in a jail
container or a VM, and
basically this works
on a on the whole system level.
There can be more granularity.
But usually what you do is you take the
whole thing and put it in some kind of
environment, restricted environment.
And this is done by the admin, not by the
app itself.
The problem is, if you have some kind of
rules that several implementations for
this that I'm going to show, if you have
a rule set, this program
can do this and this and this, but
nothing else.
How do you get that rule?
This is surprisingly difficult if it's
not a trivial program
and for easy for
simple processes that can be done.
And it's reasonably easy, but
that's not the ones we're worried about.
Right. So we think about stuff like
Firefox.
Also, in my opinion,
you can't expect the admin to come up
with a set of rules to confine
a program.
It's not the admins job to understand
what every eventuality,
every error code path and this app
does. You don't even know
if you use all the regular functionality
in the program usually.
Are you sure you clicked on every button
and Firefox in your lifetime
and you would have to do that to make
sure that your profile is complete?
So usually what happens in this kind of
scenario is that there are some obscure
error paths you haven't seen yet that
the program would have been able to
handle gracefully.
For example, just for memory
allocation fails and then suddenly
the program behaves differently.
And that's a violation of your profile
and the whole thing blows up.
So this is it's very hard to come up with
this profile. That's why I think it's
it's a misguided idea to do this.
You can still do this on top of
actually having the program sandbox
itself. It's it's an
orthogonal idea,
but I don't think this should be the only
thing we do to constrain applications.
The the other idea is that, well, maybe
not the admin is doing this, but the
distro guy, you know, the Debian package
maintainer does this.
And I don't think that's a good idea to
you can't really expect them to do this.
They're basically, you know, students
doing this in their spare time.
But how would they have a year
to study Firefox and come up with a
profile?
So the the central idea of
all of my talk is the confining itself,
basically, I think it's a werewolf
chaining itself to the wall before
a full moon to make sure that even
if something happens, you know, I'm still
confined here and don't do damage.
So basically what you do is you make sure
there's a little part in the file system,
only the stuff you really need, and
you can only access that part.
There's several ways to do this, to talk
about them.
You cannot open files outside this
part of the file system or maybe you can
open any files at all.
If you don't need doesn't need to open
files, you would think, but it turns out
it does for DNS lookup.
So it's all the devil's in the details
here. It's not it's easier to talk about
it than to actually do it.
Another thing that's usually overlooked
is that even if you can't access the file
system, there's still lots of stuff you
can do.
System five VPC is its own namespace,
for example, which means you could
access shared memory from other processes
if they use System five IPC
or you can send signals, just kill
processes.
Or you could use Petreus, which
is the Unix debug API, to
attach yourself as a debugger to some
process outside of your environment.
So it's not just it's not enough to
limit the filesystem access.
There's more stuff you can do.
So the the
main thing you should take away from
this is that you probably have to
restructure your application the way it
works.
You limit what the main application can
do to reduce the part.
You really have to be sure about to the
broker service. And the broker service
gets messages from the main program,
stuff like I want to open this file
for reading or I want to open
that file for writing in.
The broker service can do additional
checking aside from what the operating
system is doing anyway.
And to make this worthwhile,
you have to make sure that the main
process does not have any way
to actually or any any access rights
to access the file system itself.
And there are several ways to do this I'm
going to talk about.
The problem is that sometimes
there's ways for
the main program to
trick the broker.
So if you do if you just do a
separate process and it's running under
the same user ID, for example,
then you could attach a debugger to it.
One, the main program, if it's being
hacked, could just use Petrelis
to override the
code of code execution flaw in the broker
and just make it to anything at once.
So this is more tricky than I'm
letting on here.
So let's get to the dirty details
first. The old school way.
This is what Ping is supposed
to do. I'm like, let's let's
say in the 90s, this is
what we used to do in the 90s.
Basically what you have is you have two
ideas in the process,
data structure in the operating system
and like some structure somewhere in the
kernel. And it says, well, you have the
real idea and you have the effect of your
ID.
And if the program is run,
it's trading, then the effective
user ID is the one
that the binary is situated to.
So that means if the program does
anything, the kernel doesn't actually
look at the real you.
It looks at the effect of your I.D.
So let's say you understand this
and you want to drop your privileges,
then you could just say set
effective your I.D.
to get your ID, to drop back to
the the actual the real user
ID. And you would think that's enough,
right.
And it turns out, no, it's not enough,
because at some point there's
a start to ID that allows you to
go back even after someone tried
to draw privileges and
this is at some point
the various versions of Unix
and BSD diverged on
this point.
So it was for a time, it was pretty hard
to write code that does it right
at some point in your API was invented.
It's called said Residente.
You can said all three user
IDs with this, and that's actually
OK. That's a good way to draw privileges.
However, it's not enough to do
this.
You need to check the return value
and if you don't, things
can go badly.
Also, it may not be enough to
to reset the user I.D.
There may be group pages that are
privileged too.
So the devil is all in the details
here. So what can happen if
I'm the super user and I want to set
Razu ideas with some user idea?
How can this ever fail?
There is system wide, limited
resource limits for you ID.
So there could be a limit that
there can only be 10 processes for giving
you I.D.
and if that your I.D.
already has 10 processes running and
routers trying to draw privileges to that
your ID, then that will fail.
And if you don't check the return value
at that point, you might as well not have
dropped privileges in the first place.
So if you do any of this, be very
careful to understand
all side effects and things you have to
watch out for.
It actually used to be even worse than
that because there was different
calls that refuted that
looked like it was the right thing, but
it doesn't.
And in many programs today,
you'll find backwards compatibility
code if said reside is not found
by configure.
And in many cases that code path is
pretty bad. So my advice
is if if someone tries to build
your program on a system that doesn't
have said raise your ID and just fail to
build, we need to get this everywhere.
There's no way even so.
Well, let me give you an example.
This is from an airport security advisory
a while ago.
It says, basically, the issue was
that the set rigid
system called fail to drop privileges.
Well, that's that's what it's there for.
Right. So very careful
with this actually test that works
and make sure
you check all the return values.
So what have we actually dropped
privileges, let's say we are paying
and we get a raw socket
in the beginning and then we drop
privileges and then someone attacks us
successfully, then
maybe we're not running as rude anymore.
But
what is what happens if all the attacker
wanted was the wrong socket?
We still have that.
So dropping privileges more
than than going back to you.
Also, the
concept of, well, we do the dangerous
stuff first may be more difficult than
it looks like. So, for example, what
about passing command line arguments?
You can have bugs. They're actually the
you served back there and they said,
well, we have to do that first and
then we do the hardware and stuff
and then we do our privileges.
So this is dangerous to pass in command
line arguments.
And what if if the
attacker is using environment variables,
what if the bug is in the dynamic link or
the very examples of this tool?
So that's before even your man is
running.
So dropping privileges is
it's a harder concept than it looks like.
And if all the attacker wanted, as I
said, is the wrong socket, then there's
not much you can do.
The code still has to be good.
So let's talk about privilege,
separation.
Let's say you have Web servers and it
wants to convert uploaded images
to, let's say, create thumbnails or
make sure it's all a JPEG without
metadata or whatever you want
to remove EXIF, something
like that.
But the way to do that would be to
support all these image formats and
nobody wants to write that code.
So what people do is download libraries
to do that. And those are big pieces of
code. Many of them have had security
problems in the past.
There is basically not many reasons
to trust them now.
So that might be a good idea
for privilege separation.
You move that in a separate process
and that process has no privileges and
it doesn't have to access the file system
in any way because it gets the
image or some socket or pipe or whatever
and gives you the result back of another
socket. So this could be locked down.
There's a difference between using all
the libraries directly and using some
kind of wrapper around them, which is
even more popular or something like image
magic, in any case,
no matter how you do it, that's a huge
code base that shouldn't really be
trusted. So if you do this
at some point, that might be a good idea
to think about separation.
So the idea is to move all that image
manipulation stuff in a separate process
and lock that process down.
So by locking down, what do we mean by
that? And so the
obvious things are the filesystem access
obviously system five IPC other
processes into process communications,
make sure no new
channels of IPC can be opened.
Only the ones you gave the process when
you created it can still be used
if you want to limit network access,
because if the attacker can get
a shell, then maybe
it wants to create a little shell
and a network socket, even if it doesn't
have access to bin Shell.
And that might still be bad that you
need. That needs to go away.
Maybe there's a routing problem.
So the service is only supposed to be a
micro service that's visible from
your one holes in the DMZ,
but it has a default route somewhere that
doesn't need to be there.
So maybe that's that could be locked
down. Too many
ideas.
What you could try to lock down
common approaches for this is either name
spaces or a
prison in the guard.
So the namespace ideas
that you put together, some kind of fake
file system that looks
like a real file system but only has the
parts in it that the process really
needs.
And that fake file system then
becomes the actual file system that that
processes.
This is one of the ways you can do this.
And usually
stuff like ATC hosts
or ATC resolved dot
com and stuff like that could be used if
you're the process you're trying to lock
down, uses DNS lookups, for example.
So these kind of files you would need in
your fake file system, too.
And if your fake file
system is an average one, you would
have a file like var
J one etsi holst's.
The namespace concept can also be used
for you I.D. and PED's, so
the difference here would be if you have
something like a container and
in that container there's an inert
running with that in it, have
the PID one or
not, if you have more than one jail,
can you have more than one one?
So this is a detail question
that may not matter.
Maybe you don't even need an in it in
your in your jail.
But if you have a namespace and every
every container has its own
PID namespace, then there is no risk
that any interaction like kill
or any signals,
any trace and anything
that takes a pad could ever affect
anything outside the jail.
The other approaches to have some kind
of prison, the
best FreeBSD, he came up with the
name jail for this, you have some kind
of unique permission checks during
open. This is done on Windows the same
way. This is an old concept.
If you can do open, you get a file
descriptor back. And when you do read and
write on that file descriptor, even if
you at that point you couldn't do the
open again because your
drug privileges, if you have a file
descriptor, you can still do what you
were allowed to do at the time of the
open. So all the access checks are
actually done and open and not read
or write, all read or write checks
if the Open asked for permission.
So the idea would be that
you disallow the open in the first place
in the part you want to restrict, and
then you have some kind of guard.
And if the code that you want to restrict
means and open it can talk to the guard
and the guard or the broker service
says, well, let's open holes
for reading, that's OK.
But it is Yoho's for writing.
That's not OK.
So this is the other way to do this.
You can do pretty much the same thing for
four sockets, and
as long as the end result is a file
descriptor, it can be passed between
processes using Unix domain sockets.
So descriptive, passing
the concept is easy, but how to do
it is actually pretty crafty and
I would advise against trying to do this
yourself.
Go find some code that doesn't
for example, you can use mine.
It's it's available in this library.
This is pretty hairy. You can look at it.
It's like an effective desert.
It's really horrible.
I mean, you can try, but you probably
won't run on some kind of operating
system you never heard of.
And it's bad.
So this these
it's just three lines of
code, basically, but it's different.
Three lines of code for almost every
flavor of Unix out there.
So it's pretty hairy.
But if we abstract that away, then it
should be OK.
So how do we restrict filesystem access?
The old solution is
called change route.
What you do is you create an empty route
andred only directory evangel or
VMT or whatever you want to call it,
and then in the service you say changed
gear to that route, that empty
directory. Then you close all the open
files.
You say change routes to the same
directory and then you drop privileges
because if you drop privileges, first
change route cannot be done, change what
needs to and privileges.
So this is part of the stuff that needs
to be done before dropping privileges.
So let's say you do this and then the
process tries to open food,
then this food will be relative to the
current path.
That is obvious.
But if you tried to open the door to
slash food, that
doesn't work because that's the one thing
change route. Make sure it doesn't work
or if it's a symbolic link that contains
dot, dot, slash, that also doesn't work
so that you can't escape
from this part of the food system unless
you have an open descriptor that already
points outside the food system.
So that sounds pretty peachy, it's
all rainbows and unicorns, but no, it's
not, you can escape a change, ROGELL
if you are rude yourself,
because then change route doesn't does
not nest on your earnings.
So if you would do a different change
route while holding a file descriptor
to your change route,
you're out.
This is the code that doesn't just so
you've seen it once.
Um.
So if you process inside the change
room, environment can or can obtain
it has or can obtain a handle or
descriptor to a directory outside the
jail, it can escape the change route,
either with change there or if changed
or in this case.
So that's the change there is
the second way.
Change route itself does not change
there, you have to do both if
you don't do both and it's ineffective
and you need to check the return values
again,
even if you are confined to a change
route.
All it does is limit filesystem access
succored and
signals and stuff still works.
So it's not a good solution and only is
for filesystem. It's not comprehensive.
You need to do more.
More trouble with change route is that
a library functions might access
files without telling you first.
The most notorious is the DNS
APIs get hosted by name
depending on the operating system.
They may try to open a ton of files
like resolve dot com and
resolve conflicts of interest
or whatever.
So you have to look at what
the lipsey you're using actually tried to
open here to and make sure those files
are in the change from jail to.
Particularly troublesome for this is if
the program you're trying to jail isn't
written in a compiled language,
but, say Perl and Perl
may try to open some other like
modules if the program starts
with you, something something some kind
of power module, then probably try to
load that or Python is the same thing.
So scripting languages are pretty tricky.
You would have to have all this Perl code
in the jail in the change food
environment to Sjoberg and loaded.
And at that point, the risk that
someone in the jail could modify those
files.
Right. So the file permissions have to be
carefully watched.
And even worse, usually the
way to to put the files in the
jail is to hotlink them.
So if you do a hard link and someone
modifies the file in the
change jail, that also modifies the file
outside the jail.
So even if they don't manage to leave the
jail, they might still
compromise your system.
So you have to be very careful about
this.
So let's get to the solutions different
operating systems have for this,
one of the first ideas, and I think
it's a pretty good idea, is to be a
secure level.
So it basically the same the same idea
as I talked
about inside the process.
You do the dangerous stuff first, like
mounting filesystems and doing
a filesystem check.
Those need to be able to access a raw
device, a block device.
But after you do filesystem check, maybe
you don't need it anymore. It's a
production server, so you might as well
turn off the the capability in
the whole system to open ROBLOX
block devices and secure that.
We can do this basically.
You can only increase it, only RWD can
increase it and nobody can decrease
it without rebooting.
That's the idea.
That also means you have to disallow
access to def came and stuff
like that and secured
evidence that you.
Then I talked about change jail,
something like Change Ruth on steroids,
Israel has their own filesystem rules
and additionally, you can set IP
addresses for different jails.
So in the end, you can have a root
user in the jail.
But without the problems that
are interchangeable, environment has
solved. The root in the jail isn't
actually considered rude in the whole
system.
It's like a middle thing and there is
some kind of namespace stuff.
This is still in progress.
Jails are being extended
right now, basically.
So keep keep a watch on the
capabilities of jails.
They're still being worked on.
The admin that sets up those jails can
specify, for example, if System five
IPC access is allowed
or sockets are allowed
and things like that.
So this is a pretty good thing.
And it has been used for building
a container style
hosting on on privacy
for a while now.
The one of the problems with
well, maybe it's not a problem, but it's
it's it makes me feel a bit uneasy is
that there is no actual names faces.
It's like a flag on
the process.
They extended the structure
in Crono for a process to say this is
relative to J5.
So theoretically, you could still
say kill five and
five is outside your jail.
But there is a check for that.
But it still means there has to be a
check at every place where you do
something with Paddys in the ground.
So that's I think it's a bit risky, but
apparently it's pretty stable and I'm not
aware of any issues they had
there.
Paddy, one is always in it
in the the whole not in
any of the jails.
If you tried to kill one inside
the jail, that fails because
Paddy one does not belong to that jail.
That's not work. So it's it's like a
namespace light, you could say maybe.
But it means if if
there is two processes in
different jails, they can't have the same
pide.
That's like a slide in Foley.
No, it's not clear how much of
a problem that is, but, you know, just to
understand how that works.
So let's get to the APIs to restrict
what a process can do,
capsicum, the freebasing way for
this and this is actually
a pretty neat API.
The whole idea is that you split
off the broker service
and you use capsicum to make sure that
all global namespace accesses
like open file or
create succored fail.
And the only way to get descriptors
to files you want to open is by going
through the broker.
I have to make sure that
the there are some more restrictions,
actually in capsicums.
For example, you can say Petrus
is not allowed or
you can say succored operations
are only the only succored operations are
allowed. So you can have some more
fine grained control.
But it's not completely fine-grained.
You can say, for example, Mr.
Zijlaard, if you wanted to.
OpenBSD came up with an API call
team.
The idea is similar to
to capsicum, but it restricts
some some more.
My problem with this API is that
they have these flags that they needed.
And if you need some other way to
restrict the process, you can.
All you have is the flags
that they provide
for you.
So it's not it's not programable.
And you could say it's not as flexible as
Linux, but if
all you need is those flags and for most
people that should be enough, then it's
actually not that bad.
The problem is that these are defined.
So if you want to support different
versions of Open BSD, then you
have an effective hell.
If this flag is available, then use
it otherwise not so.
It's portability is a bit bad.
It feels a bit like a crutch to me.
And the open Binsey people agreed.
So they have a new API now.
It's called Pledge.
And what do you do with pledges?
You basically the same as the flags, but
you put it in a string and that
string is then passed by the coroner.
And if you try to pledge
something that the coroner doesn't
understand, then there is no effective
help. However, the coroner needs to power
strings now, which is also dangerous.
So
I'm not sure if this is actually an
advancement of our time.
But, you know, and it's there there
is one pretty good idea in pledge
that is in no other system.
You can also give a list of
paths and fire system
accesses will only succeed
if the finding them you're trying to open
is in one of those paths.
So you don't need to set up a jail
or a change room environment.
You can say, you know, ATC
host is OK, otherwise,
you know, my home directory is OK,
but all other slash temp
is OK, I guess that kind of
list.
But my program never needs to
look into, you know, user being,
for example. You could say that in place.
That's a pretty neat thing I would like
to see in the other airports still.
So let's come to Linux,
Linux as a as a pretty early
concept of capabilities, that was
from the time when we didn't think about
restricting more than
dropping privileges.
So the idea with capabilities is instead
of dropping privileges, we make sure we
don't give you a privilege you don't need
in the first place.
It never really took off.
So the idea was you could have a
ping that doesn't really have super user
privileges. It just has the part
it needs to create real sockets.
It could, for example,
access the
disk device or something.
Never really got anywhere, as far as I
know, there's a combined thing
that's available in the U.S.
and then of is called trace, it's also
pretty old.
The idea is that you have a wide profile
that says, for example, that Eskandar
opened your retail reading.
These are system calls and
write because it needs to to
write the output to send it out.
But if it tries to do anything aside from
that, an alarm is raised.
That's the idea with stress.
However, the profile does not
come with the program and the program
cannot set its own profile.
This is something the admin provides or
that it's provided at installation time.
This is what a profile looks like in
practice.
You don't need to read the fine print
just to show you basically what
kind of what to expect.
It's it's a text file.
So stress, the problem
is where does the profit come from?
So in the answer as well, the EDVIN has
some kind of training training mode.
And I talked about the problems with
that earlier.
I don't think that's a good solution
because you don't getting coverage
from a program.
Your road yourself is already hard
and most people can never get full
coverage with their unit tests.
How do you expect the admin that doesn't
know the code to do it?
So I think it's a it's a bad idea.
Then there is Colonel Patch
series called G.R.
Security that offers
features that are
conceptually similar to strains.
It's not part of the kernel, so I'm not
advocating it here.
I think if you want to have
this kind of thing, it should
be in the stock system and
not need any external stuff.
And it cannot be used to serve
SoundWorks.
And then there's AC Linux that's also
pretty well known, it's conceptually the
same as history, it's a little more
powerful, but again, can be used
to Sandburg's yourself
up.
Armor is a little it's another not
invented here type of thing.
Does a similar thing also not used
for self sandboxing.
And the actual API for leniency
would use to sell itself is called second
filter. It's based on Secombe.
And this is a start up business model
from 2005 when someone said, well,
you could sell your specific cycles
for, say, scientific computing
and cloud computing or something.
But since you can trust foreign
code, we'll make sure that the phone
code can do anything
and didn't catch on.
But on this basis, they invented
mold to our second filter
and it uses Berkely packet filters with
who knows what the Berkeley packet filter
is.
OK, pretty much more than I expected.
It's a bytecode VM basically is really
horrible.
It's a step machine, very limited
instruction set.
There is tooling, but you have to look
for it and it's still pretty horrible.
But Linux kind of recently got agit
for it, so they figured it's fast.
We should use it more.
This is what the program looks like
in.
In DCPI dump, which is what it was
actually intended for, if you say
Port 22, then there's a little
bytecode compiled that looks at
the packet and says, OK, this is i.p,
this is TCP or UDP
and there is a port 22.
So it's pretty gross.
And the idea with Secombe of
psychomotor mature second filter is that
instead of a packet, you
give a memory buffer that contains
the Cisco number and
all the arguments to the Sasko.
And then you can write a little program
or bytecode that looks at these arguments
and says, no, this is called no, it's
not allowed.
There are some more details
going on.
But if it boils down
to this, you have some it's macro
hell and it's really horrible.
But I thought you should see it at least
once.
You would do something like allow
us to called open, allows us to call
exit. And that's it is the easy
mode. When you don't look at the
arguments, there's some trickery
that was
a security problem.
And second filter initially where
you would have a platform that allows
different kinds of binaries, 32
and 64 bit. So you have to do an
additional check. But never mind that
here.
And then you construct a program like
this, you have all
these jumpers or BBF
statement, you see Valdese,
for example, is a load and
jump as a condition of jump.
Fred says, OK, program is finished here.
And you set it up with PR control, which
is, as far as I know, nonspecific
sitcom.
The plus side is that it works,
and if you abstract it away, it doesn't
even smell that bad.
It's actually quite efficient because of
the jet and it's reasonably
powerful on
on the control side.
What the hell were they thinking?
I mean, if you expect people to write
code like this, then the complexity of
the checking code shouldn't
approach the complexity of the code
you're trying to lock down.
Otherwise, you know, there will be bugs
in there.
There's all kinds of words if you try to
use it, because for it,
for historic reasons, there's
different ways to do many things.
For example, exit versus exit group
or a map and map to
all kinds of stuff.
And in the end, what you usually do
is you allow both, even if only one of
them is called because they do the same
thing. But it's all the stuff you need to
know to use a computer.
And for a map, there's an actual
that's the worst problem because MB has
more arguments than there were free
registers, i.e.
386.
So the first MB version of the
first version of the maps is called
didn't actually use the registers,
but it used a pointer to a buffer
and you can't inspect that buffer
from second filter.
So if someone uses the old map,
there's no way to to
use a computer to restrict that.
Look at the argument. So this is bad.
Unfortunately, you can use this in a
while, so you should be okay.
If you want to inspect arguments, it
looks like this, so in this case,
we have open and we want to make sure
only open for reading is allowed.
So, I mean, it's pretty ugly.
You can see that. But you can you can
attempt to extract anyway.
So let's say I want to allow open, but
only for ATC resolved, which
is a common thing you want to do,
can be done with a computer because you
can inspect memory
and you may be asking why, why
don't they allow that? And even if
it could be done, it will still be
insecure.
And think of the scene
if you do the check first and say, OK,
this is resolved
and then you allow the opensource call
to happen, then there's a time between
your check and the open where another
thread of the same process could change
the buffer.
So even if they allowed this check,
this wouldn't work.
So you can't inspect Buffer's
with second filter.
And it's a good thing if you need
to do that, you need to do a broker
service, basically.
Um.
So you could there's some things you
could attempt.
So, for example, you could look down a
map and say it
has to be a read only page
for the argument or only
this address is allowed.
And when I set up the second filter, then
only that address is allowed as an
argument, but it gets
really hairy and I wouldn't
advise for it.
So if we think about this, for example,
and protect what be this is called to
change read only map to a
map. So we would have to disallow that
too.
But you would have to make sure that if
someone calls an unmap on an overlapping
area, that doesn't work.
So it gets really hairy really fast.
So let's say don't do this.
However, fortunately,
Linux is not Unix and doing this in the
broker is comparatively easy because
you can just do an open in
the broker and then look at the
full path of the file
via the file system.
So that would be one way to do it,
basically, or you knew his name Space's,
which is probably the better way.
So, yeah, basically, this
is how you would deal with a broker,
you have to ask yourself the question,
have we really locked anything down if
we do all this trouble?
Because let's say in the end, you have
something like Firefox
and there's a safe as
function in Firefox, and
the idea of that is to allow writing
anywhere in the file system.
How do you lock that down?
So even if you even if you put that
on the broker service, someone who
attacks Firefox could still
well, couldn't write, but it can ask
the broker service for writing.
And since it's the idea to
allow writing everywhere to
broker service will allow it or
let's say not us, but open
local files, you
are allowed to say open
and give a file to Firefox.
So the broker would have to allow opening
files.
And that means even files
that may not be suitable for
Firefox, like your SDH Private key
Firefox can open those right.
So even if you lock down Firefox
and Firefox is just a
metaphor here for complex processes.
Let's say my sequel is the same thing.
My secret should have permissions
to open files because it's needed for
some functionality.
You may be able to lock that away in
special cases when you don't need it, but
you can't just do that, you know, for
everyone. So
it's it's a problem that may you
may be able to lock down more if you know
more details about your application.
And that's one of my arguments, because
the admin usually doesn't.
The programmer does.
The big elephant in the room is kind of
bugs.
We have a high profile kernel back around
every six to 12 months.
And if we rely on some
security mechanism like namespace
as our second filter,
the next vulnerability might be in there.
It's complex code.
Complex code has bugs, right?
So the expectation is
most unfond bugs are
in obscure places.
So my example for this would be X 25
succored handling because nobody uses
that anymore.
There are probably still bugs in there
because nobody cares if we lock that
away, we gain something.
So there is a value not just in
restricting permissions and there's also
value on top of that in
restricting kind of APIs that
are visible to the program and locking
away APIs that might have
a problem in the future.
That is also when even if we don't
gain anything tangible now, it's
insurance against the future.
So the first rule of second
filter is block future calls to second
filter.
So as an example, I try to
lock down my ping implementations to get
a handle on all this functionality.
And so the first thing you do is you get
a raw socket and you drop privileges
and after that you want to want to lock
down what the attacker can do.
So before you do command line passing.
Right. So you lock that down.
The documentation says if you apply to
filters with second filter and then both
are applied.
So I thought, oh, that's good.
Um, I can do several
stages. The first stage drops stuff
I never need, but
filesystem access I can only block after
I did the DNS lock up and that I can
only do after I pass the command line.
So I have more privilege than
I really need during the time I
pass the command line.
So I did several calls to Second Filter
and I found out that it didn't
work as advertised.
So this is a caveat
that you should know I could install
a filter that this allowed further
calls to second filter twice, so
obviously didn't get applied.
So check your have a unit test for your
lockdown mechanisms to.
On Windows, that theoretically
you can do this, but it's so hard
that I would recommend against it if you
are really dead set on trying to do this
on Windows. Go read the chrome sandbox
implementation. It's open source.
It's really hairy.
And I wouldn't feel safe
if I had any of that cold, to
be honest, in my project.
So if you can at all
to avoid windows for that, for this
you might the way to do this might
be to use their Eppalock down.
Then it's not your fault if the lock down
isn't good, but trying to do
this yourself is. But it's not a good
idea, I think.
So to sum it up,
I think we're in a pretty good place from
the functionality because we can do most
of the stuff we want to do
on Linux previously and open Vista at
least.
Fine-grained lockdown is possible,
but it's very hard and fidgety.
On the other hand, if we write code,
that code is usually also hard and
fidgety, so I don't think that's much of
an argument.
If you are a paranoid software, paranoid
software author, you can sacrifice some
performance to gain more security.
The trailblazer here is open
at this age and their sandbox
source code is should be
something you study if you want to
find out how to do this.
Personally, I feel I can sleep well at
night knowing that I logged on my code
with the stuff and tested that the
lockdown actually works.
Your mileage may vary.
Closing words,
use this in your own code, I think
this should be the shipping or deployment
equivalent of having unit tests,
everyone should have this.
If your process is too big to apply
this reasonably, then split it up.
We I think we shouldn't and we should
strive for a future in 10
years or something when nobody ships
software that has doesn't have some
kind of lock down mechanism like this.
If your code fails after updates
because you locked down tightly
and it needs more permissions now than
you were doing it right,
because that means your lockdown was very
precise, that's how it should be.
So this is there is work involved.
Don't get me wrong, this is hard work.
And you need to be very concentrated
and you need to check whether you
actually achieved what you wanted.
But you can do it and I think you should
do it.
Any questions, I think we
only have five minutes, OK?
So we have about
eight minutes, you can always
send me an email or I would be available.
You're in the front.
Let's start with a question
from the Internet.
OK, the first question from the Internet
is if you saw the
talk on cloud, Abbi, and
what are your thoughts on this?
On what we talk on Cloud
Abai
or Cloud API, I didn't actually see the
talk, I'm sorry, but I will look at the
video.
I think they're basically using the same
mechanisms.
I still wouldn't trust the
the announcement they make that you can
run untrusted code if you lock it down.
I wouldn't go that far.
But basically what they do is the same
thing. They use these mechanisms to lock
down and that's the way you have to go if
you do cloud computing
requirements better.
So what was your exact criticism
of the second two?
Is that the design of the virtual
machine, the instruction set, or the fact
that you have to use these macros to
write your code?
Well, actually, it turns out you don't
need to use the macros.
There's a library that abstracts it.
But since the whole reason to use
this stuff is because you don't trust
your libraries. I didn't mention it.
I think you shouldn't be using libraries
to abstract this away.
My criticism is that you need too much
context to use it.
So the open Vista API is
pretty good in this respect.
You have it's very easy to use
and there's not much you can fuck up.
And I would I would hope I would
hope that there's some way to do
this more easily in Linux to.
We could survive it.
What is your take on GFR
application sandboxing
on which one is
the one the clone project is doing for
larger applications that normally
don't run this route?
But as a normal user, I haven't
actually looked at the details.
I don't know. Sorry.
OK, microphone
four, please.
So my question is, are these
privileged dropping happens at runtime?
You have to code it into the binary
yourself. Now, there are some
processes, tools where you
know that right from the beginning
you don't need to certain kinds of
excesses. Wouldn't it make sense to have
a kind of like the Satcom binary code
being a special section in the ILF binary
and half loaded by the kernel right
from the beginning?
Yeah, yeah. That would be awesome.
But we don't have the tooling yet.
So if someone would hack that, that would
be nice.
Another question from the Internet,
please, yet the question is,
what do you think about running a target
application in like hardened, dorky words
like LSM second see groups?
Yeah, I mean, that's the it's a
good idea. However,
how do you know that.
I mean it doesn't really lock down
everything they use names, faces, which
is good, but
if you have a kernel back there's more
you can do to to avoid
it. I mean not in all cases but
I don't feel as safe
with Dukkha then I would feel with
Dukkha and an application that also does
second filter to restrict itself more.
Microphone three, thank you, everything
you explained.
Looks like I need to call all these
features from see, is there
some way to call those restriction
APIs from some high level types of
memory safe languages?
Probably, however, you need insight
in what the runtime of those languages
does, and that's a whole other can of
worms,
usually from high level, more high level
languages. You can always call C code in
some way or other.
So it should be possible
microphone to please.
And my question kind of
relates to the previous one.
So when you mentioned results
of being
read, your names on them look
up. So is there any attempt
to kind of make this modular when
you have a library and
you at least need to document or
specify in some way what
this and that call needs in terms
of operating system services?
So you can do it?
I'm not aware of any of those, but
most operating systems document
this in some way or another in their own
documentation.
However, if you write software usually
wanted to be more portable and
you know, it works with this version of
Lipsey. So there's a tradeoff here
to be more precise in your blocking
or to be more portable.
And I think that's a bad thing to have.
It gives the wrong incentive.
And in question from the Internet,
please.
Yes, it's not really from the Internet,
but from one of the agents down here.
So I'm going to hand him the microphone.
Yeah.
So you mentioned that
you mentioned using Brockhurst services
to actually hand off opening
files and how it doesn't help with
sorry, with processes
that might need to open arbitrary files,
something we are doing with our
Pomeroy's. We are working on using Brocco
services where it's actually a broadcast
service which prompts a user fall,
which files need to be open,
which avoids having
the service lied about needing to open
the file.
When I say broker servers, I didn't mean
it in a way that the operating system
started something, but I meant it that
the application of Faulkes in the
beginning and then one of the
two processes is the broker
for the other half. So I'm I don't
mean I think if you want the admin
to install anything so your app is more
secure, you shouldn't rely on that
because there will be mistakes made and
you want your app to be secure in any
event. So you should do it yourself as
the programmer.
Microphone eight, please.
So isn't it a problem
that most of these privileged dropping
mechanisms require you to
have super user privileges, doesn't
create an additional time of
vulnerability for a program
that never actually needs super
user privileges, but would like to lock
itself down?
I don't think most of the the API
is to require a super user.
So the second filter doesn't I think
Taman pledged and I'm not sure about
capsicum, but I don't think it does
change routers in jail does because
those are meant for different things.
But if you write something
like Paing and
you have an exterior mechanism
to get your socket and you don't need to
run his route, then you can use most of
these APIs without being
rude.
Thank you very much in favor.
Thank you very much for this talk.