Esempio n. 1
0
def test_net_taint(bpf_program: BPFProgram, caplog):
    Commands.add_profile(NET_PATH, False)
    Commands.add_net_rule(NET_PATH, NET_ACCESS.CREATE, NET_FAMILY.INET,
                          BPFBOX_ACTION.TAINT)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([NET_PATH, 'create-inet6'])
Esempio n. 2
0
    def load(self, bpf):
        """
        Load policy into the kernel.
        """

        Commands.add_profile(self.profile, self.taint_on_exec)

        for rule in self.rules:
            rule.load(self)

        for (sym, is_kfunc), state_idx in self.funcs.items():
            fn_name = f'bpfbox_state_probe_{state_idx}'
            ret_fn_name = f'bpfbox_state_retprobe_{state_idx}'
            if is_kfunc:
                bpf.attach_kprobe(
                    sym=sym, fn_name=fn_name,
                )
                bpf.attach_kretprobe(
                    sym=sym, fn_name=ret_fn_name,
                )
            else:
                bpf.attach_uprobe(
                    name=self.profile, sym=sym, fn_name=fn_name,
                )
                bpf.attach_uretprobe(
                    name=self.profile, sym=sym, fn_name=ret_fn_name,
                )
Esempio n. 3
0
def test_non_malicious_symlink_can_read_original(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.WRITE)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.LINK)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ)

    subprocess.check_call([OPEN_PATH, 'malicious-symlink-read'])
Esempio n. 4
0
def test_rename_allowed(bpf_program: BPFProgram, caplog, setup_testdir):
    os.mkdir('/tmp/bpfbox/new_dir')
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.WRITE)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/new_dir', FS_ACCESS.WRITE | FS_ACCESS.EXEC)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.RM)

    subprocess.check_call([OPEN_PATH, 'rename'])
Esempio n. 5
0
def test_rename_no_newdir_write(bpf_program: BPFProgram, caplog, setup_testdir):
    os.mkdir('/tmp/bpfbox/new_dir')
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.WRITE)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/new_dir', FS_ACCESS.EXEC)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.RM)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([OPEN_PATH, 'rename'])
Esempio n. 6
0
 def load(self, policy: Policy):
     super().load(policy)
     state = self.calculate_state_number(policy)
     for _file in self.file:
         Commands.add_fs_rule(
             policy.profile,
             _file,
             FS_ACCESS.from_list(self.access),
             BPFBOX_ACTION.from_list(self.action),
             state=state,
         )
Esempio n. 7
0
 def load(self, policy: Policy):
     super().load(policy)
     state = self.calculate_state_number(policy)
     for target in self.target:
         Commands.add_ipc_rule(
             policy.profile,
             target,
             IPC_ACCESS.from_list(self.signal),
             BPFBOX_ACTION.from_list(self.action),
             state,
         )
Esempio n. 8
0
 def load(self, policy: Policy):
     super().load(policy)
     state = self.calculate_state_number(policy)
     for family in self.family:
         Commands.add_net_rule(
             policy.profile,
             NET_ACCESS.from_list(self.operation),
             NET_FAMILY.from_string(family),
             BPFBOX_ACTION.from_list(self.action),
             state,
         )
Esempio n. 9
0
File: dsl.py Progetto: keyolk/bpfbox
    def process_policy_text(cls, txt: str):
        policy = cls.parse_policy_text(txt)

        try:
            Commands.add_profile(policy.profile, True)
        except Exception as e:
            logger.error('Failed to create profile for {policy.profile}',
                         exc_info=e)

        for rule in policy.rules:
            try:
                rule(policy.profile)
            except Exception as e:
                logger.error(f'Error applying rule {rule}', exc_info=e)
Esempio n. 10
0
def test_net_create_rules(bpf_program: BPFProgram, caplog):
    Commands.add_profile(NET_PATH, False)
    Commands.add_net_rule(NET_PATH, NET_ACCESS.CREATE, NET_FAMILY.INET,
                          BPFBOX_ACTION.TAINT)

    # Creating an INET6 socket should fail
    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([NET_PATH, 'create-inet6'])

    # Creating a UNIX socket should fail
    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([NET_PATH, 'create-unix'])

    # Allow the creation of an INET6 socket
    Commands.add_net_rule(NET_PATH, NET_ACCESS.CREATE, NET_FAMILY.INET6,
                          BPFBOX_ACTION.ALLOW)

    # Creating an INET6 socket should succeed
    subprocess.check_call([NET_PATH, 'create-inet6'])

    # Creating a UNIX socket should still fail
    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([NET_PATH, 'create-unix'])

    # Allow the creation of a UNIX socket
    Commands.add_net_rule(NET_PATH, NET_ACCESS.CREATE, NET_FAMILY.UNIX,
                          BPFBOX_ACTION.ALLOW)

    # Both should now succeed
    subprocess.check_call([NET_PATH, 'create-inet6'])
    subprocess.check_call([NET_PATH, 'create-unix'])
Esempio n. 11
0
def test_link_allowed(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.WRITE)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.LINK)

    subprocess.check_call([OPEN_PATH, 'link'])
Esempio n. 12
0
def test_unlink_allowed(bpf_program: BPFProgram, caplog, setup_testdir):
    open('/tmp/bpfbox/e', 'a').close()
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.WRITE | FS_ACCESS.EXEC)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/e', FS_ACCESS.RM)

    subprocess.check_call([OPEN_PATH, 'unlink'])
Esempio n. 13
0
File: dsl.py Progetto: keyolk/bpfbox
 def __call__(self, profile: str) -> int:
     if self.other_exe == 'self':
         other_exe = profile
     else:
         other_exe = self.other_exe
     return Commands.add_ipc_rule(profile, other_exe, self.access,
                                  self.action)
Esempio n. 14
0
def test_unlink_no_write(bpf_program: BPFProgram, caplog, setup_testdir):
    open('/tmp/bpfbox/e', 'a').close()
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.EXEC)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/e', FS_ACCESS.RM)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([OPEN_PATH, 'unlink'])
Esempio n. 15
0
def test_procfs_other_process(bpf_program: BPFProgram, caplog, setup_testdir):
    sleep_path = which('sleep')
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/proc', FS_ACCESS.EXEC)
    Commands.add_procfs_rule(OPEN_PATH, sleep_path, FS_ACCESS.READ | FS_ACCESS.EXEC)

    subprocess.check_call([OPEN_PATH, 'proc-self'])

    sleep_pid = subprocess.Popen([sleep_path, '10']).pid
    subprocess.check_call([OPEN_PATH, 'proc-other', str(sleep_pid)])
Esempio n. 16
0
def test_parent_child(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([OPEN_PATH, 'parent-child'])
Esempio n. 17
0
def test_malicious_symlink_cannot_add_link(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.WRITE)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([OPEN_PATH, 'malicious-symlink-read'])
Esempio n. 18
0
def test_symlink_disallowed(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.READ | FS_ACCESS.EXEC)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([OPEN_PATH, 'symlink'])
Esempio n. 19
0
def test_create_dir_no_write(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox', FS_ACCESS.EXEC)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([OPEN_PATH, 'create-dir'])
Esempio n. 20
0
def test_fs_allow_write_and_append(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.WRITE | FS_ACCESS.APPEND)

    subprocess.check_call([OPEN_PATH, 'simple-write-append'])

    subprocess.check_call([OPEN_PATH, 'simple-write-no-append'])
Esempio n. 21
0
def test_fs_allow_append_only(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.APPEND)

    subprocess.check_call([OPEN_PATH, 'simple-write-append'])

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([OPEN_PATH, 'simple-write-no-append'])
Esempio n. 22
0
def test_procfs(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/proc', FS_ACCESS.EXEC)

    subprocess.check_call([OPEN_PATH, 'proc-self'])

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([OPEN_PATH, 'proc-other', '1'])
Esempio n. 23
0
def test_fs_allow_read_write(bpf_program: BPFProgram, caplog, setup_testdir):
    Commands.add_profile(OPEN_PATH, False)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ, BPFBOX_ACTION.TAINT)
    Commands.add_fs_rule(OPEN_PATH, '/tmp/bpfbox/a', FS_ACCESS.READ | FS_ACCESS.WRITE)

    subprocess.check_call([OPEN_PATH, 'simple-read'])

    subprocess.check_call([OPEN_PATH, 'simple-read-and-write'])

    subprocess.check_call([OPEN_PATH, 'simple-read-and-readwrite'])
Esempio n. 24
0
def test_ipc_usr1_self(bpf_program: BPFProgram, caplog):
    Commands.add_profile(IPC_PATH, False)
    Commands.add_ipc_rule(IPC_PATH, IPC_PATH, IPC_ACCESS.SIGCHECK, BPFBOX_ACTION.TAINT)

    rc = subprocess.Popen([IPC_PATH, 'usr1-self']).wait()
    assert rc == 1

    Commands.add_ipc_rule(IPC_PATH, IPC_PATH, IPC_ACCESS.SIGMISC)
    rc = subprocess.Popen([IPC_PATH, 'usr1-self']).wait()
    assert rc == -signal.SIGUSR1
Esempio n. 25
0
def test_ipc_check_self(bpf_program: BPFProgram, caplog):
    Commands.add_profile(IPC_PATH, False)
    Commands.add_ipc_rule(IPC_PATH, IPC_PATH, IPC_ACCESS.SIGCHECK, BPFBOX_ACTION.TAINT)

    rc = subprocess.Popen([IPC_PATH, 'check-self']).wait()
    assert rc == 1

    Commands.add_ipc_rule(IPC_PATH, IPC_PATH, IPC_ACCESS.SIGCHECK)
    rc = subprocess.Popen([IPC_PATH, 'check-self']).wait()
    assert rc == 0
Esempio n. 26
0
def test_net_connect_rules(bpf_program: BPFProgram, caplog):
    Commands.add_profile(NET_PATH, False)
    Commands.add_net_rule(NET_PATH, NET_ACCESS.CREATE, NET_FAMILY.INET,
                          BPFBOX_ACTION.TAINT)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([NET_PATH, 'inet-create-and-connect'])

    Commands.add_net_rule(NET_PATH, NET_ACCESS.CREATE, NET_FAMILY.INET6,
                          BPFBOX_ACTION.ALLOW)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([NET_PATH, 'inet-create-and-connect'])

    Commands.add_net_rule(NET_PATH, NET_ACCESS.CONNECT, NET_FAMILY.INET6,
                          BPFBOX_ACTION.ALLOW)

    subprocess.check_call([NET_PATH, 'inet-create-and-connect'])
Esempio n. 27
0
def test_net_socketpair(bpf_program: BPFProgram, caplog):
    Commands.add_profile(NET_PATH, False)
    Commands.add_net_rule(NET_PATH, NET_ACCESS.CREATE, NET_FAMILY.INET,
                          BPFBOX_ACTION.TAINT)

    with pytest.raises(subprocess.CalledProcessError):
        subprocess.check_call([NET_PATH, 'create-unix-socketpair'])

    Commands.add_net_rule(NET_PATH, NET_ACCESS.CREATE, NET_FAMILY.UNIX,
                          BPFBOX_ACTION.ALLOW)

    subprocess.check_call([NET_PATH, 'create-unix-socketpair'])
Esempio n. 28
0
def test_ipc_check_target(bpf_program: BPFProgram, caplog):
    sleep_path = which('sleep')
    Commands.add_profile(IPC_PATH, False)
    Commands.add_ipc_rule(IPC_PATH, IPC_PATH, IPC_ACCESS.SIGCHECK, BPFBOX_ACTION.TAINT)

    target_pid = subprocess.Popen([sleep_path, '10']).pid
    rc = subprocess.Popen([IPC_PATH, 'check-target', str(target_pid)]).wait()
    assert rc == 1

    Commands.add_ipc_rule(IPC_PATH, sleep_path, IPC_ACCESS.SIGCHECK)
    target_pid = subprocess.Popen([sleep_path, '10']).pid
    rc = subprocess.Popen([IPC_PATH, 'check-target', str(target_pid)]).wait()
    assert rc == 0
Esempio n. 29
0
def test_ipc_stop_self(bpf_program: BPFProgram, caplog):
    Commands.add_profile(IPC_PATH, False)
    Commands.add_ipc_rule(IPC_PATH, IPC_PATH, IPC_ACCESS.SIGCHECK, BPFBOX_ACTION.TAINT)

    p = subprocess.Popen([IPC_PATH, 'stop-self'])
    try:
        rc = p.wait(1)
    except subprocess.TimeoutExpired:
        os.kill(p.pid, signal.SIGCONT)
        rc = p.wait(1)
    assert rc == 1

    Commands.add_ipc_rule(IPC_PATH, IPC_PATH, IPC_ACCESS.SIGSTOP)
    p = subprocess.Popen([IPC_PATH, 'stop-self'])
    try:
        rc = p.wait(1)
    except subprocess.TimeoutExpired:
        os.kill(p.pid, signal.SIGCONT)
        rc = p.wait(1)
    assert rc == 0
Esempio n. 30
0
def test_ipc_stop_target(bpf_program: BPFProgram, caplog):
    sleep_path = which('sleep')
    Commands.add_profile(IPC_PATH, False)
    Commands.add_ipc_rule(IPC_PATH, IPC_PATH, IPC_ACCESS.SIGCHECK, BPFBOX_ACTION.TAINT)

    target_pid = subprocess.Popen([sleep_path, '10']).pid
    rc = subprocess.Popen([IPC_PATH, 'stop-target', str(target_pid)]).wait()
    try:
        os.kill(target_pid, signal.SIGCONT)
    except:
        pass
    assert rc == 1

    Commands.add_ipc_rule(IPC_PATH, sleep_path, IPC_ACCESS.SIGSTOP)
    target_pid = subprocess.Popen([sleep_path, '10']).pid
    rc = subprocess.Popen([IPC_PATH, 'stop-target', str(target_pid)]).wait()
    try:
        os.kill(target_pid, signal.SIGCONT)
    except:
        pass
    assert rc == 0