1
0
Fork 0
mirror of https://github.com/perlbot/perlbuut synced 2025-06-08 00:15:42 -04:00

Now use the awesome power of SECCOMP to secure the eval, and enable new functionality

This commit is contained in:
Ryan Voots 2016-10-15 08:04:58 -04:00
parent d4e272c467
commit 66bc4ad0e9
5 changed files with 150 additions and 138 deletions

8
bin/makejail.sh Executable file
View file

@ -0,0 +1,8 @@
#!/bin/bash
mkdir -p jail
mkdir -p jail/perl5
mkdir -p jail/lib
mkdir -p jail/usr/lib
mkdir -p jail/dev
mknod jail/dev/urandom c 1 9

5
bin/mountjail.sh Normal file
View file

@ -0,0 +1,5 @@
#!/bin/bash
mount -o bind /home/ryan/perl5 jail/perl5
mount -o bind /lib jail/lib
mount -o bind /usr/lib jail/usr/lib

View file

@ -68,3 +68,10 @@ requires 'Math::BigRat' => 0;
requires 'indirect' => 0; requires 'indirect' => 0;
requires 'Moo' => 0; requires 'Moo' => 0;
requires 'autovivification' => 0; requires 'autovivification' => 0;
requires 'Linux::Seccomp' => 0;
requires 'Cwd' => 0;
# requires 'Algorithm::Permute' => 0;
requires 'File::Slurper' => 0;
requires 'Path::Tiny' => 0;

View file

@ -1,4 +1,4 @@
#!perl #!/usr/bin/env perl
#use lib '/home/ryan/perl5/lib/perl5/i686-linux'; #use lib '/home/ryan/perl5/lib/perl5/i686-linux';
#use lib '/home/ryan/perl5/lib/perl5'; #use lib '/home/ryan/perl5/lib/perl5';
@ -9,64 +9,14 @@ use Scalar::Util; #Required by Data::Dumper
use BSD::Resource; use BSD::Resource;
use File::Glob; use File::Glob;
use POSIX; use POSIX;
use List::Util qw/reduce/;
use Cwd;
use FindBin;
use List::Util; # Modules expected by many evals, load them now to avoid typing in channel
use List::MoreUtils; use Encode qw/encode decode/;
use List::UtilsBy; use IO::String;
use Data::Munge; use File::Slurper qw/read_text/;
use Scalar::MoreUtils;
use Regexp::Common;
use Encode;
use Digest::MD5;
use Digest::SHA;
use DateTime;
# use DateTimeX::Easy;
use Date::Parse;
use Time::Piece;
use Time::HiRes;
use URI;
use URI::Encode;
# use Rand::MersenneTwister;
use Mojo::DOM;
use Mojo::DOM::HTML;
use Mojo::DOM::CSS;
#use Mojo::Collection;
#use YAPE::Regex::Explain;
require Function::Parameters;
require experimental;
#require "if.pm";
#use JSON;
#use JSON::XS;
require Cpanel::JSON::XS;
require JSON::MaybeXS;
require JSON::XS;
require JSON;
require Moo;
require Moo::Object;
require Moo::Role;
require Moose;
require Moose::Role;
require Method::Generate::Accessor;
require Method::Generate::Constructor;
require MooseX::Declare;
# eval "use MooseX::Declare; class LoadAllMooseXDeclare { has dongs => ( is => ro, isa => 'Int' ); };";
require "utf8_heavy.pl";
use arybase;
use Errno;
require indirect;
eval 'use bigint; use Math::BigInt; 1e1000';
eval 'use Math::BigFloat; 1.1e1000';
eval 'use Math::BigRat; 1e1000';
require autovivification;
{
my $len = eval "lc 'ẞ'";
warn $@ if $@;
}
# save the old stdout, we're going to clobber it soon. STDOUT # save the old stdout, we're going to clobber it soon. STDOUT
my $oldout; my $oldout;
@ -78,6 +28,79 @@ select($stdh);
$|++; $|++;
#*STDOUT = $stdh; #*STDOUT = $stdh;
sub get_seccomp {
use Linux::Seccomp ':all';
my $seccomp = Linux::Seccomp->new(SCMP_ACT_KILL);
##### set seccomp
#
# Rules should only allow:
# 1. open as read
# 2. write to stderr/stdout
# 3. exit
# 4. close file handle
# 5. random syscall
# 6. read
# 7. seek
# 8. fstat/fcntl
# 9. brk
# 10.
my $rule_add = sub {
my $name = shift;
$seccomp->rule_add(SCMP_ACT_ALLOW, syscall_resolve_name($name), @_);
};
$rule_add->(write => [0, '==', 2]); # STDERR
$rule_add->(write => [0, '==', 1]); # STDOUT
#mmap(NULL, 2112544, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 7, 0) = 0x7efedad0e000
#mprotect(0x7efedad12000, 2093056, PROT_NONE) = 0
#mmap(0x7efedaf11000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 7, 0x3000) = 0x7efedaf11000
## MMAP? I don't know what it's being used for exactly. I'll leave it out and see what happens
# Used when loading executable code. Might need to figure out what to do to make it more secure?
# also seems to be used when freeing/allocating large blocks of memory, as you'd expect
$rule_add->(mmap => );
$rule_add->(munmap => );
$rule_add->(mprotect =>);
# These are the allowed modes on open, allow that to work in any combo
my ($O_DIRECTORY, $O_CLOEXEC, $O_NOCTTY) = (00200000, 02000000, 00000400);
my @allowed_open_modes = (&POSIX::O_RDONLY, &POSIX::O_NONBLOCK, $O_DIRECTORY, $O_CLOEXEC, $O_NOCTTY);
# this annoying bitch of code is because Algorithm::Permute doesn't work with newer perls
# Also this ends up more efficient. We skip 0 because it's redundant
for my $b (1..(2**@allowed_open_modes) - 1) {
my $q = 1;
my $mode = 0;
#printf "%04b: ", $b;
do {
if ($q & $b) {
my $r = int(log($q)/log(2)+0.5); # get the thing
$mode |= $allowed_open_modes[$r];
#print "$r";
}
$q <<= 1;
} while ($q <= $b);
$rule_add->(open => [1, '==', $mode]);
$rule_add->(openat => [2, '==', $mode]);
#print " => $mode\n";
}
# 4352 ioctl(4, TCGETS, 0x7ffd10963820) = -1 ENOTTY (Inappropriate ioctl for device)
$rule_add->(ioctl => [1, '==', 0x5401]); # This happens on opened files for some reason? wtf
my @blind_syscalls = qw/read exit exit_group brk lseek fstat fcntl stat rt_sigaction rt_sigprocmask geteuid getuid getcwd close getdents getgid getegid getgroups lstat/;
for my $syscall (@blind_syscalls) {
$rule_add->($syscall);
}
$seccomp->load;
}
no warnings; no warnings;
# This sub is defined here so that it is defined before the 'use charnames' # This sub is defined here so that it is defined before the 'use charnames'
@ -166,9 +189,6 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
my $code = do { local $/; <STDIN> }; my $code = do { local $/; <STDIN> };
# Kill @INC to shorten errors;
@INC = ('.');
# Close every other filehandle we may have open # Close every other filehandle we may have open
# this is probably legacy code at this point since it was used # this is probably legacy code at this point since it was used
# inside the original bb2 which forked to execute this code. # inside the original bb2 which forked to execute this code.
@ -193,11 +213,7 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
} }
# The chroot section # The chroot section
chdir("./jail") or chdir($FindBin::Bin."/../jail") or die "Jail not made, see bin/makejail.sh";
do {
mkdir "./jail";
chdir "./jail" or die "Failed to find a jail live in, couldn't make one either: $!\n";
};
# redirect STDIN to /dev/null, to avoid warnings in convoluted cases. # redirect STDIN to /dev/null, to avoid warnings in convoluted cases.
open STDIN, '<', '/dev/null' or die "Can't open /dev/null: $!"; open STDIN, '<', '/dev/null' or die "Can't open /dev/null: $!";
@ -210,6 +226,7 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
$<=$>=$nobody_uid; $<=$>=$nobody_uid;
POSIX::setgid($nobody_uid); #We just assume the uid is the same as the gid. Hot. POSIX::setgid($nobody_uid); #We just assume the uid is the same as the gid. Hot.
die "Failed to drop to nobody" die "Failed to drop to nobody"
if $> != $nobody_uid if $> != $nobody_uid
or $< != $nobody_uid; or $< != $nobody_uid;
@ -227,11 +244,11 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
and and
setrlimit(RLIMIT_NPROC, 1,1) setrlimit(RLIMIT_NPROC, 1,1)
and and
setrlimit(RLIMIT_NOFILE, 0,0) setrlimit(RLIMIT_NOFILE, 20,20)
and and
setrlimit(RLIMIT_OFILE, 0,0) setrlimit(RLIMIT_OFILE, 20,20)
and and
setrlimit(RLIMIT_OPEN_MAX,0,0) setrlimit(RLIMIT_OPEN_MAX,20,20)
and and
setrlimit(RLIMIT_LOCKS, 0,0) setrlimit(RLIMIT_LOCKS, 0,0)
and and
@ -249,6 +266,9 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
die "Failed to drop root: $<" if $< == 0; die "Failed to drop root: $<" if $< == 0;
# close STDIN; # close STDIN;
# Setup SECCOMP for us
get_seccomp();
$code =~ s/^\s*(\w+)\s*// $code =~ s/^\s*(\w+)\s*//
or die "Failed to parse code type! $code"; or die "Failed to parse code type! $code";
my $type = $1; my $type = $1;
@ -299,7 +319,7 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
sub perl_code { sub perl_code {
my( $code ) = @_; my( $code ) = @_;
local $@; local $@;
local @INC = ('.'); local @INC = map {s|/home/ryan||r} @INC;
local $_; local $_;

View file

@ -1,28 +0,0 @@
10
dir
475
svn://erxz.com/bb3/branches/perlbuut/lib/jail
svn://erxz.com/bb3
2009-10-03T22:53:42.528878Z
475
simcop
dcb1cea6-7f7e-4c78-8a22-148ace8ce36e