使用eBPF保护FastAPI安全
利用eBPF保护面向互联网的API:FastAPI、BlackSheep、Flask、Django、aiohttp、Tornado等。
在之前的文章中,我使用secimport保护了PyTorch代码,展示了如何安全地在任何Linux机器上评估来自不可信源的PyTorch模型。
目录
- API安全的重要性
- 如何同时追踪Python和系统调用?
- Secimport介绍
- 追踪应用:secimport trace / trace_pid
- 构建eBPF配置文件(沙箱策略):secimport build
- 在eBPF监管下运行代码:secimport run
- 从交互式shell创建新沙箱:secimport interactive
- 使用secimport阻断攻击
- 阻止RCE的FastAPI沙箱示例
- 使用–kill_on_violation和–stop_on_violation的主动响应
- 结论
为什么需要保护API安全?
FastAPI拥有约24万行代码。API应独立于操作系统运行,避免依赖OS内存或文件系统(大多数情况下)。API被设计为无状态、简单直接,包含应用接口和数据库操作,需要大规模持续通信。
对黑客而言,API因其宽松的一体化特性和重大影响而成为高价值目标。它们主要通过TCP应用协议处理请求并返回各种状态码(表示成功或错误)。
依赖项中的漏洞
2022年,log4shell暴露了一个关键问题。专用于日志记录的Log4j,通过大多数面向互联网的Java服务器中的HTTP头解析漏洞被利用。该漏洞允许攻击者打开本地LDAP服务器并在目标HTTP服务器上执行命令。这引发了一个问题:为什么日志记录库需要具备网络连接和在主机上执行命令的能力?此类功能应仅显式启用,而非默认开启。
PyPi恶意包的便利性
2023年,pypi.org(Python包索引)因安全事件数量超过审核人员处理能力而被迫暂时关闭。虽然我们谨慎选择依赖项,但不应犹豫使用它们。依赖项不应在未经明确许可的情况下具备网络连接或运行进程的能力。Python代码可在安装、导入和运行时执行任意代码。
解释器的主导地位(“解释器为王”)
Python缺乏强大的权限管理令人担忧。由于共享内存(sys.modules)、线程等因素,管理代码中的每个模块可能具有挑战性。
虽然存在争议,但我认为明确定义的能力使程序更具可预测性。
实时追踪Python系统调用
在第一篇博客(第1部分)中,我探索了各种追踪工具。我曾在Mac和Windows上使用DTrace进行追踪和运行时分析,但我渴望更好的解决方案——仅限Linux并使用eBPF。
我将bpftrace集成到secimport,这是一个基于eBPF+LLVM的工具包。bpftrace凭借快速学习曲线和稳健性成为最佳选择。
bpftrace真正卓越之处在于其利用LLVM将用bpftrace语言编写的高级用户定义脚本编译为高效BPF代码的能力。效果令人印象深刻!
Secimport
由eBPF驱动的secimport通过为Python提供安全沙箱来解决这些问题。使用secimport,可以为代码中的每个模块指定特定的系统调用,以极低成本在运行时保护环境。
使用USDT和内核探针,secimport追踪并保护Python运行时。它使开发人员能够重新控制包操作并保护代码。
让我们在主机上安装secimport(本例为Linux):
|
|
可用的secimport命令包括:
secimport trace:通过运行Python程序或指定运行进程ID来追踪其行为。系统调用按模块记录到文件中。secimport trace_pid:通过PID追踪运行中的进程。secimport build:从追踪记录构建新的沙箱环境。secimport run:在沙箱环境中运行Python进程。secimport interactive:通过记录Python解释器行为创建新的定制沙箱。适用于小段代码和评估。它实际上按顺序运行secimport trace、secimport build、secimport run。
从头创建新的secimport沙箱
要从头创建新的沙箱环境,可以使用docker容器:
|
|
您可以使用secimport interactive开始构建沙箱:
|
|
STOP和KILL标志
使用–stop_on_violation和–kill_on_violation阻止执行
如果您知道自己在做什么,并且定义了足够好的策略,我鼓励您使用这两个非常有用的标志:
|
|
如何保护API免受远程代码执行?
让我们尝试保护给定代码免受此类场景影响。我将快速使用FastAPI程序作为示例(来自他们的快速入门):
|
|
步骤1:追踪您的应用程序
您可以使用以下方法之一来追踪Python应用程序:
secimport trace将使用eBPF追踪脚本运行您的应用程序以追踪系统调用:1secimport trace main.pysecimport trace_pid将追踪事先启动的运行中进程:1secimport trace_pid 28 # 其中28是已运行的python进程secimport interactive可以追踪交互式shell,适用于中小型代码片段(代替像main.py这样的入口点):1 2 3 4 5 6root@0584e98a4b5c:/workspace# secimport interactive 让我们用secimport创建第一个定制沙箱! - 将打开一个python shell - 行为将被记录 确定?(y): y ...
高测试覆盖率很有帮助,因为我们可以运行测试套件,如果逻辑被覆盖,期望相同的系统调用。
您还可以使用eBPF安全地在生产环境中记录行为,使用secimport trace_pid 123。它附加到运行中的进程,能够记录所有系统调用,按代码中的模块分类。
我们已经追踪了程序。让我们从这个追踪记录构建沙箱!
步骤2:从追踪记录创建YAML/JSON策略
我们构建一个bpftrace脚本,该脚本被转换为监督进程的eBPF代码:
|
|
步骤3:在eBPF沙箱内运行Python应用程序
|
|
处理违规
我们使用secimport运行main.py,它运行良好。让我们看看如果添加以下恶意行会发生什么:
|
|
默认情况下,secimport将记录违规——因为我们使用"os.system"运行命令。
如果我们希望在检测到违规时终止或停止应用程序,secimport可以在系统调用实际执行之前向受监督的子进程发送信号——SIGSTOP或SIGTERM!
secimport能够干扰进程并在违反您定义的策略时阻止它。
违规时停止进程
|
|
如日志所示——通过向"secimport run"添加"–stop_on_violation"标志,沙箱停止了进程,根本没有发送HTTP响应:页面未加载!空响应。这是我们预期的,因为策略被违反了。
违规时终止进程
如果我们想终止进程而不是停止它怎么办?
|
|
进程按预期被终止。在我看来这太棒了!
如何处理错误?
我建议有一个宽限期,在此期间所有"错误"都被记录而不是主动响应——这是默认行为。如果您知道自己在做什么,并且覆盖了所有想要允许的用例,请使用stop_on_violation或kill_on_violation不安全标志来阻止攻击,而不是记录它们。
结论
想象一下在每个Python存储库中都有一个公共的"capabilities.txt"文件,定义模块可以执行的系统调用。
当然,当前解释器不支持这一点,但这种精确的规范将阐明模块的行为,不留歧义空间。
程序员应清楚了解其代码的操作,包括网络通信、文件系统访问、sudo权限、套接字绑定、进程管理(fork/spawn)、内存操作(mmap、unshare、shm)等。
感谢您阅读至此。希望我鼓励您使用secimport保护当前应用程序。我可以帮助这个过程,只需在GitHub上提出问题。
第1部分:在代码中沙箱化Python模块 第2部分:使用eBPF保护PyTorch模型
源代码和示例:https://github.com/avilum/secimport
顺便说一句,我是在业余时间做这件事的。我也真的很喜欢咖啡!
Avi在业余时间让互联网更安全 我是一名注重业务的工程师,热爱安全和AI,具有深刻的安全洞察力。我喜欢破解云… www.buymeacoffee.com
查看我之前的发布: 使用eBPF保护PyTorch模型 本文并非由GPT生成
我如何发现AWS上的数千个开放数据库 我在寻找和报告有关财富500强公司、医院、加密平台的敏感数据数据库的旅程… infosecwriteups.com
10分钟内实现Google网络钓鱼POC:ɢoogletranslate.com 早在2016年,我遇到一篇关于有人购买ɢoogle.com的帖子。它被用于网络钓鱼目的(注意第一个字母… infosecwriteups.com
通过客户端端口扫描识别网站用户——使用WebAssembly和Go 网站倾向于从浏览器扫描用户的开放端口,以更好地识别新/返回用户。localhost能否被滥用… infosecwriteups.com
Facebook知道您吃什么:逐步发现Facebook收集的关于您的全部数据 我如何以编程方式探索https://facebook.com/dyi的故事。 medium.com