社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

震惊!别这样直接运行 Python 命令,否则电脑等于“裸奔”

菜鸟学Python • 4 年前 • 409 次点击  
编译整理:晓查   报道:量子位
原文链接:http://dwz.date/dnz

Python 已经成为全球最受欢迎的编程语言之一。原因当然是 Python 简明易用的脚本语法,只需把一段程序放入 .py 文件中,就能快速运行

而且 Python 语言很容易上手模块。比如你编写了一个模块my_lib.py,只需在调用这个模块的程序中加入一行import my_lib即可

这样设计的好处是,初学者能够非常方便地执行命令。但是对攻击者来说,这等于是为恶意程序大开后门

尤其是一些初学者将网上的 Python 软件包、代码下载的到本地~/Downloads文件夹后,就直接在此路径下运行 python 命令,这样做会给电脑带来极大的隐患

别再图方便了

为何这样做会有危险?首先,我们要了解 Python 程序安全运行需要满足的三个条件:

  1. 系统路径上的每个条目都处于安全的位置

  2. “主脚本” 所在的目录始终位于系统路径中

  3. 若 python 命令使用 -c 和 -m 选项,调用程序的目录也必须是安全的

如果你运行的是正确安装的 Python,那么Python 安装目录和 virtualenv 之外唯一会自动添加到系统路径的位置,就是当前主程序的安装目录

这就是安全隐患的来源,下面用一个实例告诉你为什么

如果你把 pip 安装在 /usr/bin文件夹下,并运行 pip 命令,由于/usr/bin是系统路径,因此这是一个非常安全的地方

但是,有些人并不喜欢直接使用 pip,而是更喜欢调用 /path/to/python -m pip

这样做的好处是可以避免环境变量 $PATH 设置的复杂性,而且对于 Windows 用户来说,也可以避免处理安装各种 exe 脚本和文档

所以问题就来了,如果你的下载文件中有一个叫做 pip.py 的文件,那么你将它将取代系统自带的 pip,接管你的程序

下载文件夹并不安全

比如你不是从 PyPI,而是直接从网上直接下载了一个 Python wheel 文件,你很自然地输入以下命令来安装它:

$ cd ~/Downloads
$ python -m pip install ./totally-legit-package.whl

这似乎是一件很合理的事情

但你不知道的是,这么操作很有可能访问带有 XSS JavaScript 的站点,并将带有恶意软件的的pip.py到下载文件夹中

下面是一个恶意攻击软件的演示实例:

~$ mkdir attacker_dir
~$ cd attacker_dir

$
 echo 'print("lol ur pwnt")' > pip.py
$ python -m pip install requests
lol ur pwnt

看到了吗?这段代码生成了一个 pip.py,并且代替系统的 pip 接管了程序

设置$PYTHONPATH也不安全

前面已经说过,Python 只会调用系统路径、virtualenv 虚拟环境路径以及当前主程序路径

你也许会说,那我手动设置一下 $PYTHONPATH 环境变量,不把当前目录放在环境变量里,这样不就安全了吗?

非也!不幸的是,你可能会遭遇另一种攻击方式。下面让我们模拟一个“脆弱的” Python 程序:

# tool.py
try:
      import optional_extra
except ImportError:
      print("extra not found, that's fine")

然后创建 2 个目录:install_dirattacker_dir。将上面的程序放在 install_dir 中

然后 cd attacker_dir 将复杂的恶意软件放在这里,并把它的名字改成 tool.py 调用的 optional_extra 模块:

# optional_extra.py
print("lol ur pwnt")

我们运行一下它:

$ cd ~/attacker_dir
$ python ../install_dir/tool.py
extra not found, that's fine

到这里还很好,没有出现任何问题

但是这个习惯用法有一个严重的缺陷:第一次调用它时,如果 $PYTHONPATH 以前是空的或者未设置,那么它会包含一个空字符串,该字符串被解析为当前目录

让我们再尝试一下:

~/attacker_dir$ export PYTHONPATH="/a/perfectly/safe/place:$PYTHONPATH";
~/attacker_dir$ python ../install_dir/tool.py
lol ur pwnt

看到了吗?恶意脚本接管了程序

为了安全起见,你可能会认为,清空 $PYTHONPATH总该没问题了吧?Naive!还是不安全!

~/attacker_dir$ export PYTHONPATH="";
~/attacker_dir$ python ../install_dir/tool.py
lol ur pwnt

这里发生的事情是,$PYTHONPATH变成空的了,这和 unset 是不一样的

因为在Python里,os.environ.get(“PYTHONPATH”) == “”os.environ.get(“PYTHONPATH”) == None是不一样的

如果要确保 $PYTHONPATH 已从 shell 中清除,则需要使用 unset 命令处理一遍,然后就正常了

设置$PYTHONPATH曾经是设置 Python 开发环境的最常用方法。但你以后最好别再用它了,virtualenv 可以更好地满足开发者需求。如果你过去设置了一个$PYTHONPATH,现在是很好的机会,把它删除了吧

如果你确实需要在 shell 中使用 PYTHONPATH,请用以下方法:

export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}new_entry_1"
export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}new_entry_2"

在bash和zsh中,$PYTHONPATH 变量的值会变成:

$ echo "${PYTHONPATH}"
new_entry_1:new_entry_2

如此便保证了环境变量 $PYTHONPATH 中没有空格和多余的冒号。

如果你仍在使用 $PYTHONPATH,请确保始终使用绝对路径

另外,在下载文件夹中直接运行 Jupyter Notebook 也是一样危险的,比如jupyter notebook ~/Downloads/anything.ipynb也有可能将恶意程序引入到代码中。

预防措施

最后总结一下要点。

  1. 如果要在下载文件夹 ~/Downloads 中使用 Python 编写的工具,请养成良好习惯,使用pip所在路径 /path/to/venv/bin/pip,而不是输入/path/to/venv/bin/python -m pip

  2. 避免将 ~/Downloads 作为当前工作目录,并在启动之前将要使用的任何软件移至更合适的位置

了解 Python 从何处获取执行代码非常重要,赋予其他人执行任意 Python 命令的能力等同于赋予他对你电脑的完全控制权

希望以上文字对初学 Python 的你有所帮助!




年度爆款文案

1).卧槽!Pdf转Word用Python轻松搞定

2).学Python真香!我用100行代码做了个网站,帮人PS旅行图片,赚个鸡腿吃

3).首播过亿,火爆全网,我分析了《乘风破浪的姐姐》,发现了这些秘密  

4).80行代码!用Python做一个哆来A梦分身 

5).你必须掌握的20个python代码,短小精悍,用处无穷 

6).30个Python奇淫技巧集 

7).我总结的80页《菜鸟学Python精选干货.pdf》,都是干货 

8).再见Python!我要学Go了!2500字深度分析

9).发现一个舔狗福利!这个Python爬虫神器太爽了,自动下载妹子图片


每个程序员都是从菜鸟开始成长起来的,没有人生下来就是程序员高手。菜鸟编程大本营,专注于分享趣味的编程技巧,不限于Java, Python ,Go, Javascript等语言,让菜鸟爱上编程,进阶成为高手。




    
菜鸟编程本营,从菜鸟进阶高手

点这里,获取新手福利

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/105690
 
409 次点击