Site update
This commit is contained in:
parent
224a442800
commit
82a2d5f717
13 changed files with 1412 additions and 6 deletions
|
@ -76,6 +76,8 @@ and perform an action on it.</p>
|
||||||
<nav id="tags">
|
<nav id="tags">
|
||||||
<h1>Tags</h1>
|
<h1>Tags</h1>
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
|
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
|
||||||
|
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
|
@ -67,9 +67,9 @@ directory on the root filesystem. This was done to make getting them to work in
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="next">
|
<li class="next">
|
||||||
<button disabled>
|
<a class="button button-primary" href="/blog/2017/10/10/seccomp-and-you/index.html" rel="next">
|
||||||
Newer →
|
Newer →
|
||||||
</button>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -83,6 +83,8 @@ directory on the root filesystem. This was done to make getting them to work in
|
||||||
<nav id="tags">
|
<nav id="tags">
|
||||||
<h1>Tags</h1>
|
<h1>Tags</h1>
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
|
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
|
||||||
|
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
184
blog/2017/10/10/seccomp-and-you/index.html
Normal file
184
blog/2017/10/10/seccomp-and-you/index.html
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||||
|
<link href="/theme/css/normalize.css" rel="stylesheet">
|
||||||
|
<link href="/theme/css/skeleton.css" rel="stylesheet">
|
||||||
|
<link href="/theme/css/statocles-default.css" rel="stylesheet">
|
||||||
|
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
<title>Seccomp and you - Perlbot.pl pastebin</title>
|
||||||
|
<meta content="Statocles 0.086" name="generator">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<nav class="navbar">
|
||||||
|
<div class="container">
|
||||||
|
<a class="brand" href="/">Perlbot.pl pastebin</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/blog">Blog</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
<div class="main container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="nine columns">
|
||||||
|
<main>
|
||||||
|
<header>
|
||||||
|
<h1>Seccomp and you</h1>
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
<time datetime="2017-10-10">
|
||||||
|
Posted on 2017-10-10
|
||||||
|
</time>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<p class="tags">Tags:
|
||||||
|
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
|
||||||
|
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</header>
|
||||||
|
<section id="section-1">
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<ul class="pager">
|
||||||
|
<li class="prev">
|
||||||
|
<a class="button button-primary" href="/blog/2017/10/02/new-old-perls/index.html" rel="prev">
|
||||||
|
← Older
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="next">
|
||||||
|
<button disabled>
|
||||||
|
Newer →
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="three columns sidebar">
|
||||||
|
|
||||||
|
<nav id="tags">
|
||||||
|
<h1>Tags</h1>
|
||||||
|
<ul class="list-inline">
|
||||||
|
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
|
||||||
|
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
|
||||||
|
<div class="container tagline">
|
||||||
|
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
|
||||||
|
<a href="http://www.perl.org">Powered by Perl</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
108
blog/index.atom
108
blog/index.atom
|
@ -2,11 +2,117 @@
|
||||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
<id>https://perlbot.pl/blog/</id>
|
<id>https://perlbot.pl/blog/</id>
|
||||||
<title>Perlbot.pl pastebin</title>
|
<title>Perlbot.pl pastebin</title>
|
||||||
<updated>2017-10-02T00:00:00Z</updated>
|
<updated>2017-10-10T00:00:00Z</updated>
|
||||||
<link href="https://perlbot.pl/blog/index.atom" rel="self" />
|
<link href="https://perlbot.pl/blog/index.atom" rel="self" />
|
||||||
<link href="https://perlbot.pl/blog/" rel="alternate" />
|
<link href="https://perlbot.pl/blog/" rel="alternate" />
|
||||||
<generator version="0.086">Statocles</generator>
|
<generator version="0.086">Statocles</generator>
|
||||||
|
|
||||||
|
<entry>
|
||||||
|
<id>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</id>
|
||||||
|
<title>Seccomp and you</title>
|
||||||
|
<link href="https://perlbot.pl/blog/2017/10/10/seccomp-and-you/" rel="alternate" />
|
||||||
|
<content type="html"><![CDATA[
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Tags:
|
||||||
|
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
|
||||||
|
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
]]></content>
|
||||||
|
<updated>2017-10-10T00:00:00Z</updated>
|
||||||
|
<category term="evalserver" />
|
||||||
|
<category term="seccomp" />
|
||||||
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
<id>https://perlbot.pl/blog/2017/10/02/new-old-perls/</id>
|
<id>https://perlbot.pl/blog/2017/10/02/new-old-perls/</id>
|
||||||
<title>New old perls</title>
|
<title>New old perls</title>
|
||||||
|
|
112
blog/index.html
112
blog/index.html
|
@ -34,6 +34,116 @@
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h1><a href="/blog/2017/10/10/seccomp-and-you/">Seccomp and you</a></h1>
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
<time datetime="2017-10-10">
|
||||||
|
Posted on 2017-10-10
|
||||||
|
</time>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<p class="tags">Tags:
|
||||||
|
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
|
||||||
|
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</article>
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h1><a href="/blog/2017/10/02/new-old-perls/">New old perls</a></h1>
|
<h1><a href="/blog/2017/10/02/new-old-perls/">New old perls</a></h1>
|
||||||
|
@ -114,6 +224,8 @@ and perform an action on it.</p>
|
||||||
<nav id="tags">
|
<nav id="tags">
|
||||||
<h1>Tags</h1>
|
<h1>Tags</h1>
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
|
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
|
||||||
|
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
106
blog/index.rss
106
blog/index.rss
|
@ -6,6 +6,112 @@
|
||||||
<atom:link href="https://perlbot.pl/blog/index.rss" rel="self" type="application/rss+xml" />
|
<atom:link href="https://perlbot.pl/blog/index.rss" rel="self" type="application/rss+xml" />
|
||||||
<description>Blog feed of Perlbot.pl pastebin</description>
|
<description>Blog feed of Perlbot.pl pastebin</description>
|
||||||
<generator>Statocles 0.086</generator>
|
<generator>Statocles 0.086</generator>
|
||||||
|
<item>
|
||||||
|
<title>Seccomp and you</title>
|
||||||
|
<link>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</link>
|
||||||
|
<guid>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</guid>
|
||||||
|
<description><![CDATA[
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Tags:
|
||||||
|
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
|
||||||
|
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
]]></description>
|
||||||
|
<pubDate>
|
||||||
|
Tue, 10 Oct 2017 00:00:00 +0000
|
||||||
|
</pubDate>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>New old perls</title>
|
<title>New old perls</title>
|
||||||
<link>https://perlbot.pl/blog/2017/10/02/new-old-perls/</link>
|
<link>https://perlbot.pl/blog/2017/10/02/new-old-perls/</link>
|
||||||
|
|
117
blog/tag/evalserver.atom
Normal file
117
blog/tag/evalserver.atom
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
<id>https://perlbot.pl/blog/tag/evalserver/</id>
|
||||||
|
<title>Perlbot.pl pastebin</title>
|
||||||
|
<updated>2017-10-10T00:00:00Z</updated>
|
||||||
|
<link href="https://perlbot.pl/blog/tag/evalserver.atom" rel="self" />
|
||||||
|
<link href="https://perlbot.pl/blog/tag/evalserver/" rel="alternate" />
|
||||||
|
<generator version="0.086">Statocles</generator>
|
||||||
|
|
||||||
|
<entry>
|
||||||
|
<id>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</id>
|
||||||
|
<title>Seccomp and you</title>
|
||||||
|
<link href="https://perlbot.pl/blog/2017/10/10/seccomp-and-you/" rel="alternate" />
|
||||||
|
<content type="html"><![CDATA[
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Tags:
|
||||||
|
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
|
||||||
|
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
]]></content>
|
||||||
|
<updated>2017-10-10T00:00:00Z</updated>
|
||||||
|
<category term="evalserver" />
|
||||||
|
<category term="seccomp" />
|
||||||
|
</entry>
|
||||||
|
</feed>
|
||||||
|
|
117
blog/tag/evalserver.rss
Normal file
117
blog/tag/evalserver.rss
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
|
<channel>
|
||||||
|
<title>Perlbot.pl pastebin</title>
|
||||||
|
<link>https://perlbot.pl/blog/tag/evalserver/</link>
|
||||||
|
<atom:link href="https://perlbot.pl/blog/tag/evalserver.rss" rel="self" type="application/rss+xml" />
|
||||||
|
<description>Blog feed of Perlbot.pl pastebin</description>
|
||||||
|
<generator>Statocles 0.086</generator>
|
||||||
|
<item>
|
||||||
|
<title>Seccomp and you</title>
|
||||||
|
<link>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</link>
|
||||||
|
<guid>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</guid>
|
||||||
|
<description><![CDATA[
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Tags:
|
||||||
|
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
|
||||||
|
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
]]></description>
|
||||||
|
<pubDate>
|
||||||
|
Tue, 10 Oct 2017 00:00:00 +0000
|
||||||
|
</pubDate>
|
||||||
|
</item>
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
|
|
204
blog/tag/evalserver/index.html
Normal file
204
blog/tag/evalserver/index.html
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||||
|
<link href="/theme/css/normalize.css" rel="stylesheet">
|
||||||
|
<link href="/theme/css/skeleton.css" rel="stylesheet">
|
||||||
|
<link href="/theme/css/statocles-default.css" rel="stylesheet">
|
||||||
|
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
<title>Perlbot.pl pastebin</title>
|
||||||
|
<meta content="Statocles 0.086" name="generator">
|
||||||
|
<link href="/blog/tag/evalserver.atom" rel="alternate" type="application/atom+xml">
|
||||||
|
<link href="/blog/tag/evalserver.rss" rel="alternate" type="application/rss+xml">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<nav class="navbar">
|
||||||
|
<div class="container">
|
||||||
|
<a class="brand" href="/">Perlbot.pl pastebin</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/blog">Blog</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
<div class="main container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="nine columns">
|
||||||
|
<main>
|
||||||
|
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h1><a href="/blog/2017/10/10/seccomp-and-you/">Seccomp and you</a></h1>
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
<time datetime="2017-10-10">
|
||||||
|
Posted on 2017-10-10
|
||||||
|
</time>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<p class="tags">Tags:
|
||||||
|
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
|
||||||
|
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<ul class="pager">
|
||||||
|
<li class="prev">
|
||||||
|
<button disabled>
|
||||||
|
← Older
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="next">
|
||||||
|
<button disabled>
|
||||||
|
Newer →
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="three columns sidebar">
|
||||||
|
|
||||||
|
<nav id="tags">
|
||||||
|
<h1>Tags</h1>
|
||||||
|
<ul class="list-inline">
|
||||||
|
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
|
||||||
|
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<h1>Feeds</h1>
|
||||||
|
<ul class="list-inline">
|
||||||
|
<li>
|
||||||
|
<a href="/blog/tag/evalserver.atom" rel="alternate" type="application/atom+xml">
|
||||||
|
Atom
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/blog/tag/evalserver.rss" rel="alternate" type="application/rss+xml">
|
||||||
|
RSS
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
|
||||||
|
<div class="container tagline">
|
||||||
|
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
|
||||||
|
<a href="http://www.perl.org">Powered by Perl</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
117
blog/tag/seccomp.atom
Normal file
117
blog/tag/seccomp.atom
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
<id>https://perlbot.pl/blog/tag/seccomp/</id>
|
||||||
|
<title>Perlbot.pl pastebin</title>
|
||||||
|
<updated>2017-10-10T00:00:00Z</updated>
|
||||||
|
<link href="https://perlbot.pl/blog/tag/seccomp.atom" rel="self" />
|
||||||
|
<link href="https://perlbot.pl/blog/tag/seccomp/" rel="alternate" />
|
||||||
|
<generator version="0.086">Statocles</generator>
|
||||||
|
|
||||||
|
<entry>
|
||||||
|
<id>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</id>
|
||||||
|
<title>Seccomp and you</title>
|
||||||
|
<link href="https://perlbot.pl/blog/2017/10/10/seccomp-and-you/" rel="alternate" />
|
||||||
|
<content type="html"><![CDATA[
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Tags:
|
||||||
|
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
|
||||||
|
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
]]></content>
|
||||||
|
<updated>2017-10-10T00:00:00Z</updated>
|
||||||
|
<category term="evalserver" />
|
||||||
|
<category term="seccomp" />
|
||||||
|
</entry>
|
||||||
|
</feed>
|
||||||
|
|
117
blog/tag/seccomp.rss
Normal file
117
blog/tag/seccomp.rss
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
|
<channel>
|
||||||
|
<title>Perlbot.pl pastebin</title>
|
||||||
|
<link>https://perlbot.pl/blog/tag/seccomp/</link>
|
||||||
|
<atom:link href="https://perlbot.pl/blog/tag/seccomp.rss" rel="self" type="application/rss+xml" />
|
||||||
|
<description>Blog feed of Perlbot.pl pastebin</description>
|
||||||
|
<generator>Statocles 0.086</generator>
|
||||||
|
<item>
|
||||||
|
<title>Seccomp and you</title>
|
||||||
|
<link>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</link>
|
||||||
|
<guid>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</guid>
|
||||||
|
<description><![CDATA[
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Tags:
|
||||||
|
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
|
||||||
|
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
]]></description>
|
||||||
|
<pubDate>
|
||||||
|
Tue, 10 Oct 2017 00:00:00 +0000
|
||||||
|
</pubDate>
|
||||||
|
</item>
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
|
|
204
blog/tag/seccomp/index.html
Normal file
204
blog/tag/seccomp/index.html
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||||
|
<link href="/theme/css/normalize.css" rel="stylesheet">
|
||||||
|
<link href="/theme/css/skeleton.css" rel="stylesheet">
|
||||||
|
<link href="/theme/css/statocles-default.css" rel="stylesheet">
|
||||||
|
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
<title>Perlbot.pl pastebin</title>
|
||||||
|
<meta content="Statocles 0.086" name="generator">
|
||||||
|
<link href="/blog/tag/seccomp.atom" rel="alternate" type="application/atom+xml">
|
||||||
|
<link href="/blog/tag/seccomp.rss" rel="alternate" type="application/rss+xml">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<nav class="navbar">
|
||||||
|
<div class="container">
|
||||||
|
<a class="brand" href="/">Perlbot.pl pastebin</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/blog">Blog</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
<div class="main container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="nine columns">
|
||||||
|
<main>
|
||||||
|
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h1><a href="/blog/2017/10/10/seccomp-and-you/">Seccomp and you</a></h1>
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
<time datetime="2017-10-10">
|
||||||
|
Posted on 2017-10-10
|
||||||
|
</time>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<p class="tags">Tags:
|
||||||
|
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
|
||||||
|
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
|
||||||
|
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
|
||||||
|
(heretofore refered to as seccomp).</p>
|
||||||
|
|
||||||
|
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
|
||||||
|
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
|
||||||
|
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
|
||||||
|
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
|
||||||
|
systrace—which seems to be no longer supported for Linux).
|
||||||
|
-- https://en.wikipedia.org/wiki/Seccomp
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
|
||||||
|
predefined rules, organized into 'profiles'. Each profile is intended to represent a
|
||||||
|
single kind of action that a program could do, such as open a file for reading, open a
|
||||||
|
file for writing, etc.</p>
|
||||||
|
|
||||||
|
<p>I've created a few profiles to start with</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><p>stdio
|
||||||
|
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
|
||||||
|
<li><p>file_open
|
||||||
|
Allows calling some file related system calls, such as: open, openat, close, select,
|
||||||
|
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
|
||||||
|
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
|
||||||
|
rules that will be covered later</p></li>
|
||||||
|
<li><p>file_opendir
|
||||||
|
Allows opening a directory to get a list of files, and also includes the file_open
|
||||||
|
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
|
||||||
|
or similar programs</p></li>
|
||||||
|
<li><p>file_tty
|
||||||
|
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
|
||||||
|
<li><p>file_readonly
|
||||||
|
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
|
||||||
|
similar calls</p></li>
|
||||||
|
<li><p>file_write
|
||||||
|
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
|
||||||
|
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
|
||||||
|
<li><p>time_calls
|
||||||
|
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
|
||||||
|
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
|
||||||
|
<li><p>ruby_timer_thread
|
||||||
|
This one is a special ruby specific profile. It allows ruby to create a thread that
|
||||||
|
it uses internally, and only allows that thread creation with a specific set of flags,
|
||||||
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
|
||||||
|
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
|
||||||
|
to run. It also allows for pipe2 to be called to create communication between the two
|
||||||
|
threads.</p></li>
|
||||||
|
<li><p>perl_file_temp
|
||||||
|
This was added specifically for behavior of File::Temp, and might get folded into a
|
||||||
|
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
|
||||||
|
<li><p>exec_wrapper
|
||||||
|
This one is seriously special. It's not a predefined set of rules, but in fact
|
||||||
|
generates the rules at runtime. This is because of limitations of seccomp. Since
|
||||||
|
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
|
||||||
|
string being passed to execve(), instead we create a white-list of strings that can be
|
||||||
|
passed to it, and only allow calls to execve that are passed pointers to this syscall.
|
||||||
|
This isn't perfectly secure since someone could overwrite the contents at a later point
|
||||||
|
but it's safe enough because an attacker can't view the generated BPF to extract the
|
||||||
|
addresses, and the strings themselves should be gone from memory by the time their code
|
||||||
|
runs, preventing them from recreating the original addresses. This requires ASLR in order
|
||||||
|
to be effective at preventing an attacker from derriving the address of the strings from
|
||||||
|
previous runs.</p></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>There's also some other profiles like ruby_timer_thread specifically for allowing node.js
|
||||||
|
to do similar things to ruby (create a thread, use epoll, etc.).</p>
|
||||||
|
|
||||||
|
<p>=== Handling flags to syscalls</p>
|
||||||
|
|
||||||
|
<p>The way the rules are defined allow syscalls like open() to not need special handling.
|
||||||
|
Since many syscalls can take flags, it's useful to be able to limit the flags they can
|
||||||
|
take.</p>
|
||||||
|
|
||||||
|
<p>{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},</p>
|
||||||
|
|
||||||
|
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
|
||||||
|
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
|
||||||
|
A profile can add (but not remove) values to the permutation rules, and then when the
|
||||||
|
whole BPF program gets compiled it'll generate all the applicable rules for you. This
|
||||||
|
makes setting up calls like open much much simpler since you don't have to write out all
|
||||||
|
possible modes yourself. This is also an area where I could be doing better to optimize
|
||||||
|
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
|
||||||
|
operations that could make this more effective but they were not well exposed through
|
||||||
|
Linux::Seccomp when this was originally designed.</p>
|
||||||
|
|
||||||
|
<p>In the second part of this blog I'll document the proposed configuration
|
||||||
|
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<ul class="pager">
|
||||||
|
<li class="prev">
|
||||||
|
<button disabled>
|
||||||
|
← Older
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="next">
|
||||||
|
<button disabled>
|
||||||
|
Newer →
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="three columns sidebar">
|
||||||
|
|
||||||
|
<nav id="tags">
|
||||||
|
<h1>Tags</h1>
|
||||||
|
<ul class="list-inline">
|
||||||
|
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
|
||||||
|
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<h1>Feeds</h1>
|
||||||
|
<ul class="list-inline">
|
||||||
|
<li>
|
||||||
|
<a href="/blog/tag/seccomp.atom" rel="alternate" type="application/atom+xml">
|
||||||
|
Atom
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/blog/tag/seccomp.rss" rel="alternate" type="application/rss+xml">
|
||||||
|
RSS
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
|
||||||
|
<div class="container tagline">
|
||||||
|
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
|
||||||
|
<a href="http://www.perl.org">Powered by Perl</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
24
sitemap.xml
24
sitemap.xml
|
@ -4,13 +4,13 @@
|
||||||
<loc>https://perlbot.pl/</loc>
|
<loc>https://perlbot.pl/</loc>
|
||||||
<changefreq>weekly</changefreq>
|
<changefreq>weekly</changefreq>
|
||||||
<priority>0.5</priority>
|
<priority>0.5</priority>
|
||||||
<lastmod>2017-10-02</lastmod>
|
<lastmod>2017-10-23</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://perlbot.pl/blog/</loc>
|
<loc>https://perlbot.pl/blog/</loc>
|
||||||
<changefreq>daily</changefreq>
|
<changefreq>daily</changefreq>
|
||||||
<priority>0.3</priority>
|
<priority>0.3</priority>
|
||||||
<lastmod>2017-10-02</lastmod>
|
<lastmod>2017-10-10</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://perlbot.pl/blog/2017/09/28/new-blog/</loc>
|
<loc>https://perlbot.pl/blog/2017/09/28/new-blog/</loc>
|
||||||
|
@ -24,11 +24,29 @@
|
||||||
<priority>0.5</priority>
|
<priority>0.5</priority>
|
||||||
<lastmod>2017-10-02</lastmod>
|
<lastmod>2017-10-02</lastmod>
|
||||||
</url>
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://perlbot.pl/blog/2017/10/10/seccomp-and-you/</loc>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>0.5</priority>
|
||||||
|
<lastmod>2017-10-10</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://perlbot.pl/blog/tag/evalserver/</loc>
|
||||||
|
<changefreq>daily</changefreq>
|
||||||
|
<priority>0.3</priority>
|
||||||
|
<lastmod>2017-10-10</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://perlbot.pl/blog/tag/seccomp/</loc>
|
||||||
|
<changefreq>daily</changefreq>
|
||||||
|
<priority>0.3</priority>
|
||||||
|
<lastmod>2017-10-10</lastmod>
|
||||||
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://perlbot.pl/page/seccomp/</loc>
|
<loc>https://perlbot.pl/page/seccomp/</loc>
|
||||||
<changefreq>weekly</changefreq>
|
<changefreq>weekly</changefreq>
|
||||||
<priority>0.5</priority>
|
<priority>0.5</priority>
|
||||||
<lastmod>2017-10-02</lastmod>
|
<lastmod>2017-10-23</lastmod>
|
||||||
</url>
|
</url>
|
||||||
</urlset>
|
</urlset>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue