I'm always full again, which means we are ready for the next talk.
We solve our video emergency thanks to the amazing output of Fossdan team.
I have here all of our who is going to talk about a very interesting subject.
He says it isn't interestingly in itself, but I disagree.
Because privilege separation is super difficult, super amazing.
It's probably usually don't see, nothing go, but we have an expert today with
it's going to prove it's wrong, right over plus.
Okay, thanks, you can hear my name is Otto, thanks for the nice introduction, and I want
to talk about privilege separation and go.
So who am I, I said, that's really a matter, I'm just a white guy and tech to talk
about privilege of today.
So as any tech talk, I start with an obligatory xkcd comic, because that's how you do it,
I heard this one is xkcd 1200 authorization, and it shows a nice picture about the user count,
and the user count has access like everything except the admin account.
So the user can access the email, the pictures, the lovings, whatever.
So we start with some kind of implicit recognition for the ledgerist, but how does it reflect
in code on most public, like operating systems, I just stick to this topic, because everything
is not my domain, runs as a user, so code runs with user privileges, and to just tell
it I just try to find the code in here, so we have this, and come on, great success.
So we have this wonderful code, and as we saw just it ran as a user, as you see, running
as other, so we know who does it, and we have privileges, as a user has.
Now you have a privileges to open the file, as you see, and there is open.
So what can else, the code, was running my privileges do, so we can get a bit stupid here,
because we have code running, so this is a good idea, let's find out, oh no, I got
pawned by my presentation, so because we have code here, the code is running with my
user privileges, the code may do something stupid, and leak my credentials, like in this
incident, but okay, so what's all fun and games, but how is it in the real life, I mean
the real-life, no one would do something stupid as have a shell open, where anybody would
code to remote code execution, in the good case, in the reality, in the golden main, we
have lots of lots of lines of code, we include dependencies, those, including dependencies
as well, and as most in this room, when a dependable load comes in, say, if dependency
X was updated, we want to, yeah, it's fine, so maybe for pet release, there were some
7,000 lines of change, I don't know what it does, so my code is running, and maybe do
some things I don't want it to do, so, and this is all just for the good case, maybe
you remember the XZ incident a while back, they were also back down vectors, and just
because none were found, the golden main doesn't mean they aren't any, so for myself
I realized I'm unable to write secure code, I fail at it, and I think down a hard
most of us would fail, so I would say to just go down, that my code only does what
really, only can't do, what's really necessary, so this is like privilege, as I've
seen, the code before could, I don't access my private key, that's my presentation, to
know my private key, I don't think so, so there was once an analogy I heard, it was about
the self-training web-�, like the people who got the web-�, changed themselves before
returns, and back, and so maybe it's impossible to do this code, if there's the question,
yes, I'm going to talk about it today, so yes, in most things, we have an API for that, and
if I say one API, it's like hundreds, we have some different bi-posics, so they're available
in Linux, the BSDs, and other similar operating systems, and we have OS specifics, and
I'm going to talk a bit about those today, but at OS specific, I'm going to limit on Linux,
because I think it affects most people in the rooms, I may say a thing about 2 or 2, about
BSD, about a thing times short, but before actually showing code, talking about, we have
to think about the structure of a code, because if we want to restrict permissions, we may
have to redesign the architecture of a code, like first we start with all the privileges
are possible, and then we try to go down like a cane, and every time we go down, this
is like a barrier, so we drop some privileges, and we drop them for good, so for example,
we say, at first we have to read the configuration file of our software, because there's
everything configured, so we still need the privilege to read files, then after we have
to done, we can say, no, we don't need to read files anymore, and then this is gone,
and so on, and at least we may be run with so little privileges, so that when our software
has a back, it's not bad, and saying when not if, and so, three simple points,
drop a privilege task, drop privileges, that's good, okay, so let's start with the good old
way, which works on everything, projects, and this is, I think most have already got it,
so routing is a code, so routing, and then switching user privileges, so this is the old
way, and that's some things that are so great, but we can get pretty far at it, here I've shown
three code boxes, the first to show you where the input is from, the extended Unix package,
which has the Swiss calls, it differs from operating system on architecture to architecture,
so, but this is almost possible, so this should work on, like everything, except Windows,
I think I'll work Windows, so at first, we see how to change the route, and the change route
means at first, our program can see everything, the route file system sees, and then
but we can say, no, our route shouldn't be the route anymore, we want to run under this directory,
and our empty is one standard directory for that, it should be empty otherwise,
yeah, what's the fun, so we can go into it, and our code now lists in this directory,
but the route isn't actually a security mechanism, so we have to also drop user rights,
and so here we have set groups, so we aren't the group of our user anymore, but only one group,
this group shouldn't be allowed to do anything at the same for the user,
this has set rest UID, because at first we have set UID, but the effect of UID, and so on,
I don't want to go into details, but that's actually how you switch user rights,
the downside is only the route user can do it, so to execute this, you already need extended
privileges, that's the downside, and it was made better with operating specific libraries,
I get two later on, so how to actually use this, I marked the blocks in both, which I showed before,
because otherwise it wouldn't fit on the slides, so first, I would say, show who we are and what
can we do, then I looked up our demo user, it doesn't see user which has any rights,
really where we got where we are going to, then we switch our route and switch our user, so effectively
as a first step, we shouldn't be able to see any files anymore, but we are still a privileged user
and we could theoretically break out, and otherwise as long, we are than a user who can't do anything,
and our code can at least come out access our privacy anymore, so to show it,
okay, okay, at first we see in of all files system, and the end we are running as
either one problem, one and we doesn't see anything, and yes, not presentations are running as
the root user, so as we see, as I said earlier, having to start your application route isn't always
the best thing to do, because for example you have a command line application where you don't
want to have a root user, so there are more modern APIs to restrict file access, and this is
on this is Linux only, and this is the LandLog API, it's quite new in the kernel, but I think
on most of your laptops, if there are Linux device, there should be already available, and LandLog
is a nice API to restrict those files system and network access, to time constraint, I only
will show file system, and this is like the user isn't allowed to view any more, anything,
any more, just a nice package of the GoLandLog project, it's like a go wrapper for this
call, but this is called, and the setup thing is, so I don't have to read any dangerous kernel
APIs, and I can just go, and here we are accessing this API, and say we restrict to passes,
and to know passes, so if we run this, see at first it was the same up before, that was
like we have a root pass system, whatever, afterwards, and we're running it my user other again,
we can't see anything, so this can be done with user privileges, and it's like you see on
the both code, it's three lines, and your code isn't able to access the file system anymore,
in this case we can't pawn ourselves and leak our product key, so this is what the very
true example, but we can't also be a bit more specific, in this case the both lines,
I have restricted the directories to read only for the current directory and see it, just for example,
and even with the right permissions to the temp directory, so in this case if I want to access
as you see it, done there in the loop, the current directory should work because I set the profile
and otherwise if I want to access my dot SSH folder, this should fail because it isn't not in the
allowed part, because it's like an allowance you're going to construct, so yeah great success we see
in the directory there are the first ones slides and but it cannot access my dot SSH folder,
also SSH had earlier, land block can also be used to allow in and out build a bounding TCP connections,
but that gives us a far moment, if it's something you need, take a look into it,
as we're telling earlier, the system calls you're using for example for sure route,
setting user IDs, or land block itself, and system calls are a barrier to privilege, it allows
you to switch your code for just longing user space to get some resource, which is well locked
by the current, and this can be like everything, if you open a file or you open the open or open
at or what else is called, and go you don't use directly, but your code will do it in the end,
and you can't forbid those system calls in, yeah, so let's show it on Linux, on Linux the way to
restrict system calls is a bit complex and it's called SACCOMP BPS, actually it stands for the
package filtering things, so you write a program which inspects every system called your program
makes, and then it says, oh, this is okay, this is not, and you can even access some of the
parameters, you can't do reference pointers, so you can't check strings, but it's very complex,
and this is like the opposite of what I want to show here, that you can do easy things,
this is what we want example of the GoSeccom BPS project, it's a GoRetor, so you don't have to
write BPS code for yourself and your map, and you can write a simple process and go, in this case,
don't, it's in some lines, we say, by default everything's loud, but we forbid the open
says call, and so we can trigger all of this and load this, and afterwards we shouldn't be able
to open this file because, well, it should be open, but this works anyway, and that's the issue
with system codes, because it's on Linux and some other operating systems, system codes aren't
equally for all architectures, for example, if you take a view as a system codes on x86 and
I don't know, some arm, they're quite different and they're all different arm codes, so
in this case, to make this work, it's actually the open access call, we of course all know,
because everyone knows system codes, I don't know, I got this by tracing, and then
it would be forbidding, so what I want to show here, if you want to explicitly filter
system codes, you have to actually trace your program or you write low-level C, and know what you're
doing, but we are in the go-deft room, we write go-code, and we don't want to actually know
what's the compiler does, or it's not my domain, so I looked elsewhere, what to use, and then
well, I stumbled upon system D, actually, because system D, you may know it uses,
has also the possibility to limit system codes, it's called system codes, you write it in
your unit, and then you give some group in it, and they're set like, I like that, system
service is allowed, it's just a collection of my system codes, and you may access some
privilege system codes, and system D automatically uses, creates a second filter, for the one
similar, a familiar with the BSD, especially obviously, it has a similar syntax to the
system code, which is quite nice, but I don't cover here due to time constraints, so I just
did what we do in open-source, I looked at system D code and kind of stolen copy it, and wrote
a small help library, it's over there, it's a source code set, and then you can write a one-line
filter based on groups, in this case, this is actually the system D groups, I have just
always copied around and converted to go, so it's pure go, and then I can say, from now on,
I want to have system codes in the system service group, this is like a fine default,
but can do a lot, but I don't want to have network IO, so I apply this filter, and if I run this,
so yeah, at first, we can open the ETC pass with E, because opening files is in there,
but we shouldn't be able to access the web resource, here we see it exits with that system
code, so in one line, now we were able to say, these kinds of system codes are good, these are
evil, and the evil ones result in your program being shut down, and it's like nothing that
can recover from, in theory, you were able to make it recoverable with second BPS, but in my
small head library, I introduced a lot of my research projects, like tooling programs,
I prefer to say they're actually killed, okay, so far, so far, I just talked about dropping
privileges so far, but I announced something about privilege separation, so what is, if you code
in just one small head project, head of program, but that's one thing, but you want a little
take software, you have running somewhere with thousands of lines, which can do any everything,
if you drop to the union set of everything it needs to be, you have achieved nothing, so this
is where privilege separation comes in, privilege separation means that you take your big
program and separate it into different sub-programs, and now you're able to restrict each sub-program
to its necessary last privileges, these privileges, for example, if you have a tool which needs
that access, because it has some better interface, and it's file access, because it has a
database, you can make two programs out of it, one is only allowed to receive web request, one
with allowed to access a file system for the database, and then you have an IPC or IPC between it,
so how we can do it, at first I just show how one way how to go to do it and go, you just have
some kind of multiple main functions where you jump in, I have brought this fork child helper
method, which is kind of boring, if you look at it, it creates a new process, it's like for
an exec, but we can't actually talk an exec directly in Gales, we use the exec command, which is
quite nice to use, and we just add another flag of the child name, so then we redirect the output
bit boring, one thing which was noting for later, we can go extra files, if you remember,
if you start the process, it's at the SDDM, SDDR, so we have file descriptor 012, but we can give
more for shadowing, so how we do actually use this, here we've got the main function,
below there the parent code, it starts the child, here it's the backcode, and then restrict
itself, so we did a privileged task creating that of child, then we are dropping privileges,
and we're writing for the child to add, the child itself, it starts here, also it drops privileges
to even lower, basically it's just, it just can't write, it can't even open files out of it,
it does the simple hello, it's an exit, so if we run this, okay the output is described
but we have created two processes, one which is allowed to create another process, and another one
which is thus allowed to do some iL same, for example, if we have some library which we don't
trust to parse some input, for example it may be some special yellow case or image manipulation
or whatnot, we can drop this dangerous library, we may have written ourselves, or we got
somewhere from the internet, and we don't really trust in another child's read, we just launch
up the child's read without any privileges, so if there's a vector or resource leak or whatever
in this child's thing it cannot access your files anymore, and then it might die, but your main
program stays safe, so so far we need some communication because mostly we don't just want to
print and have a word to SDD out, but also get some information back, so there's one way
one need way I like to use for communication between processes, and it's a socket pair system
called socket pair 2, it's actually like a bi-duction or pipe, so just two file descriptors,
both can be read and written 2, and it works quite like a unique domain socket which has some
benefits, but it doesn't create any files, so you create a socket pair, and now you give it to the
new child as an extra file descriptor, so you have an additional way of communicating, and just
use it here, I write something in this file descriptor on my side, and the child itself opens this
additional file descriptor, and can read and write into it as well, so we have another pipe
between the parent and the child process, and in this case it's a simple string based
RPC, but you can use the net RPC package over that, you can use GRPC over whatever,
I mean you have a B-directional communication channel now, I just doesn't want to use a full
blown RPC now because I could be overkill, so yeah, I'll send a cello back again, so whatever,
but yeah, I don't want to get into any more details, because otherwise there's definitely
going to be confusing, what I wanted to show so far was, is there more, of course, there's more,
we can also restrict more privileges, more limits, like with the setR limit, there are C groups,
EPPF, which can do a lot of nice things, obviously I haven't covered the previous days,
also nice test account saying, but I don't want to overwhelm you with any much code that doesn't fit
on one slide, my takeaway lesson is think about your code, what can you code through, and how you
can restrict it, how can you bring it down, and there, for example, the second PFF example
I showed of the landlock, it's like a one line you do, because maybe your code only reads
south at one moment and later it shouldn't be, so you can make a one line div and have a great
impact on your program, and then if you want to go farther, then you can think, how can I redesign
a program to make it in the multiple thread or process in this case, and these only go to the
least privileges, so I want to kind of end of this note, reflect on your privileges, what can you
do better, and if you want to have some more information, the specifics had already been there,
on the first, there's a blockpost, the second doesn't exist, because I procrastinated it,
I will make it maybe next week, it's kind of finished, but the repo on codebook exists,
it has examples for everything I showed here, and the way more, for example, how you just
hand actually files over a file descriptor to another program, so if you're interested in the
topic, please check out the demo repo and the first link, the second will work maybe tomorrow,
maybe next year, and get to the same kind of familiar with that, so I think I made it in time,
thanks for your time, a long year, we have talked to him a lot, oh no one off here, okay,
are there any important questions that cannot wait for the whole one track, I got one in
front, please be state silence. Hi, so you can't hear me? Come here, come here mate,
so what I generally don't like about these kind of things, they have a lot of infrastructure codes,
basically in your normal code, the tracks from what you try to do, so when I can see,
they've already asked some very good reasons to do this, and not use like other things like
containers to just, yeah, so when would you actually use this? Okay, yeah, for my perspective,
as a developer, I know what I put to the able to do, if I containerize it, the container
may be running as a very two-proveded user, or otherwise they use something like SA, they don't
have a policy for the whole thing, but I, as an developer, have to inside, so I can say,
at this point, I need this privilege, and at this other point, I don't need them, so I can be
more granular, could be a super-nastrophic, of course, I mean, what do you have to have?
I would have to stay up, stay up, I might run in these separate containers and have a container.
Oh yeah, if you have a moody, Microsoft's singing, yeah, it boils down to the same.
Yeah, but I see BPM power, if you get these close, so.
Yeah, it boils to the same, it's another way to get there, definitely.
Yeah, but I can guess if you run something like
get here, what do you want to say, think something that doesn't run container, yeah, it's run.
Yeah, so yeah, for bigger applications to split them up, because yeah, I look at some things I have
to work with, and for so why are they able to do this, what kind of do it better, and yeah,
so that's all I ended up there.