
Python应用程序使用许多脚本。这就是网络罪犯用来在我们身上放“猪”的地方-我们最不希望看到它的地方。
Python的优点之一是易于使用:要运行脚本,只需将其保存在
.py
文件中并执行命令python (, python my_file.py)
。破坏我们的文件(例如模块)my_app.py
并my_lib.py
继续连接模块以使用design也是很容易的import...from: import my_lib from my_app.py
。
但是,这种简单明了的缺点是:您从不同位置执行代码越容易,攻击者就越有机会进行干预。
将Python代码放在安全的地方
Python安全模型基于以下三个原则:
- , sys.path , .
- , (main), sys.path.
-
python
,-c
-m
.
假设您要运行已“正确”安装在计算机上的Python应用程序。在这种情况下,默认情况下唯一会自动添加到sys.path的位置(安装了Python的文件夹除外)是带有主脚本或可执行文件的文件夹。
例如,如果
pip
在中/usr/bin
,并且您运行/usr/bin/pip
,则sys.path
只会添加/usr/bin
。只有root可以将文件写入/ usr / bin,因此该位置被认为是安全的。
然而,协议要求我们这样做:
/path/to/python -m pip
。这样可以避免$PATH
Windows文档的问题和冲突。
通常,如果只有您一个人有权在Python导入模块的目录中添加和编辑文件,那么一切都会好起来的。
下载文件夹-易受攻击的位置
有很多方法可以迫使浏览器(有时甚至是其他软件)在用户不知情的情况下将任意命名的文件放置在Downloads文件夹中。此漏洞被称为DLL欺骗的攻击所利用。在我们的案例中,我们将讨论Python脚本,但是想法是相同的。
浏览器对此已经变得越来越认真,并正在逐步尝试确保用户访问的站点不能将文件秘密地放入其“下载”文件夹中。
但是,要完全解决此问题将非常困难:例如,仍然有一个选项可供
Content-Disposition HTTP header’s filename*
站点选择放置上载文件的目录。
攻击如何进行
您运行安装:
python -m pip
。您正在从一个完全值得信赖的网站上下载Python软件包,但是出于某些原因,该网站提供的是直接下载而不是PyPI。也许它是某种内部版本,也许是初步版本-没什么不同。所以这取决于你totally-legit-package.whl
:
~$ cd Downloads
~/Downloads$ python -m pip install ./totally-legit-package.whl
似乎还可以,但是事实证明,两个星期前,在您访问的一个完全不同的站点上,一些XSS JavaScript在不知情的情况下将带有恶意软件的pip.py下载到了Downloads文件夹中。
繁荣!
崩溃!
~$ mkdir attacker_dir
~$ cd attacker_dir
~/attacker_dir$ echo 'print("lol ur pwnt")' > pip.py
~/attacker_dir$ python -m pip install requests
lol ur pwnt
奇怪的行为 PYTHONPATH
我在上面的几段中写道:
默认情况下,唯一会自动添加到sys.path的位置(Python安装文件夹除外)是主脚本或可执行文件文件夹。
那么“默认”在这里做什么?您还可以添加其他哪些位置?
基本上,
$PYTHONPATH
您可以将任何内容写入环境变量。但是您不会在中写下您的当前位置$PYTHONPATH
,对吗?
不幸的是,在某些情况下,您可能会意外地这样做。
让我们来画一个“脆弱的” Python应用程序来进行说明:
# tool.py
try:
import optional_extra
except ImportError:
print("extra not found, that's fine")
让我们创建2个目录:
install_dir
和attacker_dir
。让我们陷入install_dir
,然后执行cd attacker_dir
恶意代码并将其放置在此处tool.py
:
# optional_extra.py
print("lol ur pwnt")
剩下的就是运行它:
~/attacker_dir$ python ../install_dir/tool.py
extra not found, that's fine
到目前为止,一切进展顺利。
但是现在我们将看到一个常见的错误。许多建议增加一个
$PYTHONPATH
更多的事情:
export PYTHONPATH="/new/useful/stuff:$PYTHONPATH";
乍一看,这是有道理的:如果将项目X添加到中
$PYTHONPATH
,也许根据项目Y,是否也添加了某些内容;无论如何,您都不想覆盖与其他项目关联的更改。当您编写许多人会使用的文档时,这一点尤其重要。
现在,我们面临着“奇怪”的行为
$PYTHONPATH
。如果它$PYTHONPATH
是空的或在第一次启动之前未安装,则其中将出现一个空行,它将被识别为当前目录。让我们检查一下:
~/attacker_dir$ export PYTHONPATH="/a/perfectly/safe/place:$PYTHONPATH";
~/attacker_dir$ python ../install_dir/tool.py
lol ur pwnt
为了增强安全性,让我们将其设置为
$PYTHONPATH
空,然后重试:
~/attacker_dir$ export PYTHONPATH="";
~/attacker_dir$ python ../install_dir/tool.py
lol ur pwnt
确实,这根本不安全!
还有一件事情:事实证明,变量为
$PYTHONPATH
空和$PYTHONPATH
未设置变量的情况有两种不同的情况:
os.environ.get("PYTHONPATH") == ""</code> <code>os.environ.get("PYTHONPATH") == None.
如果要确保清理
$PYTHONPATH
,请使用以下命令unset
:
~/attacker_dir$ python ../install_dir/tool.py
extra not found, that's fine
通常,写入变量
$PYTHONPATH
是设置环境以运行Python应用程序的最常见方法。幸运的是,随着虚拟环境和virtualenv的出现,它已经过时了。如果您有一个向写入内容的旧配置$PYTHONPATH
,但是您可以不用它,那么现在是时候删除它了。
如果由于某种原因您不能执行此操作,请使用生活技巧:
export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}new_entry_1"
export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}new_entry_2"
在bash和zsh中,这将给出以下输出:
$ echo "${PYTHONPATH}"
new_entry_1:new_entry_2
好了,现在没有多余的冒号和空条目。
最后,如果您仍在使用
$PYTHONPATH
,请使用绝对路径。总是!
问题更加严重
与从Downloads文件夹启动Python文件相关的事件的危险开发有多种选择:
- 运行python
~/Downloads/anything.py
(即使它本身anything.py
是安全的)。您的下载文件夹将添加到中sys.path
。 - 启动后,“
jupyter notebook ~/Downloads/anything.ipynb
下载”文件夹也将添加到中sys.path
。
因此,最好在运行之前从此文件夹中删除.py和.ipynb文件。如果导入的文件位于Downloads文件夹中,则
执行
cd Downloads
和内部启动python -c
并附带说明启动import
或交互式启动python
并随后导入均不能完全解决问题。
不幸的是,这
~/Downloads/
不是可能包含恶意文件的唯一位置。例如,如果要管理用户可以向其上载文件的服务器,请cd public_uploads
在运行命令之前确保没有人可以启动python
。
在这种情况下,可能值得考虑的是,用于处理文件上传的代码将附加到其名称之后
.uploaded
。这将有助于避免计划外的脚本执行.py
。
注意事项
如果您要在“下载”文件夹中使用Python应用程序,则将输入脚本(
/ path / to / venv / bin / pip
)而不是模块(/ path / to / venv / bin / python -m pip
)的路径作为规则。
通常,只需避免将“下载”用作当前工作目录,并在开始之前将要使用的所有脚本移动到更合适的位置。
了解Python从何处获取将要执行的代码非常重要。让某人执行左手Python脚本的哪一行,都等于完全控制了您的计算机!
根据需要
阅读有关安全性的“技巧和生活技巧”的文章,可以很容易地认为作者非常聪明,知道其他人应该知道的一堆小事情,并不断思考。但是实际上,这并非完全正确。我会解释。
多年来,我以令人羡慕的频率观察到用户如何不理解Python从何处下载代码。例如,人们将使用Twisted的第一个程序放置在名为twisted.py的文件中。但是在这种情况下,根本不可能导入该库!
如果网络罪犯能够成功地攻击系统管理员或开发人员,他们会感到非常高兴。如果您入侵某个用户,您将获得该用户的数据。但是,如果您黑掉了管理员或开发人员并正确执行了操作,则可以访问系统受管理员控制的数千名用户,甚至使用开发人员软件的数百万用户。
因此,“始终保持谨慎”并不是一个可靠的方法。那些负责大量用户产品的IT专业人员确实需要格外小心。至少,应该告知他们某些开发工具的工作特性。
错误或功能...
我上面描述的内容实际上都不是真正的“错误”或“漏洞”。我认为Python或Jupyter开发人员不会错误地做任何事情。该系统按照其设计方式工作,并且可能可以解释。就我个人而言,我不知道如何在不减少Python功能的情况下对其进行更改,而我们对此非常重视。
我最喜欢的发明之一是SawStop,这是用于台锯的独特安全系统。与人体接触后,您可以在5毫秒内停止锯片的旋转。在该系统发明之前,台锯是非常危险的工具,但它们起着重要的生产功能。在台锯上已经完成了许多非常有用和重要的事情。但是,在木工车间中,台锯在事故中所占的比例也确实很高。现在,SawStop每年可以节省很多手指。
因此,通过详细介绍Python脚本编写的复杂性,我也希望对一些安全工程师有所考虑。可以使SawStop执行用于交互式解释程序的任意代码吗?哪种解决方案可以防止上述某些问题?
保持安全的朋友。
广告
VDSina在Linux或Windows上提供安全的服务器-选择预安装的操作系统之一,或从映像中安装。
