跳转到主要内容

在决定是否真的想让程序发生之前,先看看程序会做什么。

项目描述

Release Tests codecov Commit activity License


rm -rf pic*

你确定吗?你真的 百分之一百 确定?

可能不适用...

... 允许你在实际上不执行的情况下运行一个命令并查看它对你的文件做了什么!在查看列出的操作后,你可以决定你是否真的想让这些事情发生。

Screenshot

这是什么魔法?!?

可能不适用ptrace(借助出色的 python-ptrace 库)的控制下运行进程。当它拦截即将对文件系统进行更改的系统调用时,它会记录该调用,然后修改CPU寄存器,将调用重定向到无效的系统调用ID(实际上将其转换为无操作),并将该无操作调用的返回值设置为表示原始调用成功的值。

因此,该进程认为它正在尝试做的一切实际上正在发生,而实际上什么都没有发生。

话虽如此,maybenot 不应 :warning: 永远 :warning: 用于在您关心的系统上运行不受信任的代码!在 maybenot 下运行的进程仍然可以对您的系统造成严重损害,因为只有少数系统调用被阻止。它还可以使用只读系统调用检查诸如删除文件等操作是否成功,并相应地改变其行为。因此,没有限制的重试并不保证总是产生显示的操作。

目前,可以将 maybenot 理解为一种(alpha版本质量)的“我输入的这个命令到底会做什么?”工具。

安装

maybenot 在 Linux :penguin: 上运行,需要 Python 3.8+ :snake:. 如果您有 pip 软件包管理器,只需运行

pip install maybe

作为超级用户或从 virtualenv 环境运行。要开发 maybenot,克隆存储库并在其主要目录中运行

pip install -e .

以可编辑模式安装包。

用法

maybenot [options] command [argument ...]

位置参数

参数 描述
command maybenot 的控制下运行的命令
argument ... 传递给 command 的参数

可选参数

参数 描述
-a OPERATION ...,
--allow OPERATION ...
                                             
允许命令执行指定的操作。所有其他操作将被拒绝。可能的 OPERATION 值为:change_ownerchange_permissionscreate_directorycreate_linkcreate_write_filedeletemove;以及由加载的插件定义的任何筛选范围。
-d OPERATION ...,
--deny OPERATION ...
拒绝命令执行指定的操作。所有其他操作将被允许。有关 OPERATION 可能值的列表,请参阅 --allow--allow--deny 不能同时使用。
-p FILE ...,
--plugin FILE ...
加载指定的 插件 脚本
-l--list-only 不带标题、缩进和重试提示的列表操作
--style-output {yes,no,auto} 使用 ANSI 转义序列对输出进行着色(yes/no)或根据 stdout 是否为终端自动决定(auto,默认值)
-v--verbose 如果指定一次,打印每个过滤的系统调用。如果指定两次,打印每个系统调用,并突出显示过滤的系统调用
--version 显示程序的版本号并退出
-h--help 显示帮助消息并退出

插件 API

默认情况下,maybenot 会拦截并阻止所有可以对系统进行永久修改的系统调用。对于更专业的系统调用筛选需求,maybenot 提供了一个简单而强大的插件 API。筛选插件是用纯 Python 编写的,并使用与 maybenot 内置筛选器 相同的接口。

公共 API 由以下两个成员组成

maybenot.T

A Blessings Terminal 对象,可以用于格式化控制台输出(如以下文档中所述的 operation)。使用此对象格式化的输出自动符合 --style-output 命令行参数。

maybenot.register_filter(syscall, filter_function, filter_scope=None)

将过滤器 filter_function 添加到过滤器注册表中。如果过滤器已启用(这是默认设置,但可以通过 --allow--deny 命令行参数进行更改),则它会拦截由受控进程发出的所有对 syscall 的调用。filter_scope 确定与 --allow--deny 一起使用的密钥以启用/禁用过滤器(多个过滤器可以共享相同的密钥)。如果省略 filter_scope 或为 None,则使用插件模块名的最后一部分。

filter_function 本身必须符合签名 filter_function(process, args)process 是一个 Process 控制对象,可以用来检查和操作进程,而 args 是传递给 syscall 的参数列表,顺序与 syscall 签名中的顺序相同。如果一个参数表示(指向)文件名,则该参数将类型为 str 并包含文件名,否则它将类型为 int 并包含参数的数值。

调用 filter_function 时,必须返回一个元组 (operation, return_value)operation 可以是描述被过滤器阻止的操作的字符串,在进程终止后打印,也可以是 None,在这种情况下不会打印任何内容。return_value 可以是一个数值,在这种情况下将阻止 syscall 调用并将调用者收到的返回值设置为该值,也可以是 None,在这种情况下调用将允许正常进行。

示例

在这里,使用 maybenot 的插件 API 实现了一种外型的访问控制:根据文件的 内容 限制读取访问。如果打开读取的文件包含单词 SECRET,则插件将阻止 open/openat syscall 并返回错误。

read_secret_file.py

from os import O_WRONLY
from os.path import isfile
from maybenot import T, register_filter

def filter_open(path, flags):
    if path.startswith("/home/") and isfile(path) and not (flags & O_WRONLY):
        with open(path, "r") as f:
            if "SECRET" in f.read():
                return "%s %s" % (T.red("read secret file"), T.underline(path)), -1
            else:
                return None, None
    else:
        return None, None

register_filter("open", lambda process, args:
                filter_open(process.full_path(args[0]), args[1]))
register_filter("openat", lambda process, args:
                filter_open(process.full_path(args[1], args[0]), args[2]))

确实,插件按预期工作

[user@localhost]$ maybenot --plugin read_secret_file.py --deny read_secret_file -- bash
$ echo "This is a normal file." > file_1
$ echo "This is a SECRET file." > file_2
$ cat file_1
This is a normal file.
$ cat file_2
cat: file_2: Operation not permitted

许可证

版权所有 © 2016-2017 Philipp Emanuel Weidmann (pew@worldwidemann.com) 版权所有 © 2023 Rinat Sabitov (rinat.sabitov@gmail.com)

GNU 通用公共许可证版本 3 的条款下发布

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码发行版

maybenot-0.5.0rc1.tar.gz (25.8 kB 查看哈希值)

上传时间 源代码

构建发行版

maybenot-0.5.0rc1-py3-none-any.whl (28.2 kB 查看哈希值)

上传时间 Python 3

由以下支持