Python Fake Package引发的任意代码执行风险
本文将结合一个实例讲解安装Fake Python Package时可能引起的任意代码执行风险(原理同Package 钓鱼,所以安装Python Package 一定要小心哦)以及相应的缓解办法。
一般来说,利用Python Package执行一些特定代码有两种途径:
在Package 执行的时候,称为运行时任意代码执行;
在Package 安装时就触发任意代码执行, 称为安装时任意代码执行。
本文以后者为例进行演示与说明。
0×01 实验与分析
1、演示
恶意的Package构造如下:
非常简单,就是一个安装入口文件setup.py (setup.cfg用于预先设置一些安装选项)。
当我们执行python setup.py install 或者 更常用的命令 pip install freebuf/ (这里freebuf后加上一个’/'表示安装本地名为freebuf 文件中的源码,如果freebuf这个包通过源码包形式上传至Pypi的后,便可省略‘/’) 的时候便会触发预先设置好的恶意代码,演示如下:
注意到上图中的Running setup.py了吗,这代表这时恶意代码已经开始执行,恶意代码会在/ 目录下写入一个明文Freebuf的文件,内容为:“欢迎大家来Freebuf投稿!”
2、分析
这是怎么实现的呢? 答案就是Hook setup.py install 过程 ,原理如下:
setuptools 包提供了一个安装类 : setuptools.command.install.install,只要继承这个类,然后重写其run方法,那么就可以达到hook pip install xxx/ 或 python setup.py install 行为的目的。
完整hook 需要2步。
第一步,重写安装类,即重写原生install 类的ru 方法:
class CustomInstallCommand(install):
重写setuptools.command.install.install 的run方法,可以实现调用自定义函数,在pip install 的时候触发
def run(self):
custom_function()
install.run(self)
这里的custom_function 就可以用来执行一些羞羞的操作(比如本例中的在/ 目录下写入一个Freebuf的文件,内容为: 欢迎大家到Freebuf投稿!),你懂得。
第二步,在setuptools.setup 设置中指明重写后的安装类:
setuptools.setup(
...
,
cmdclass={
'install': CustomInstallCommand,
},
)
0×02 如何防范
1、对于习惯下载源码包,然后本地安装的同学
在安装前检查一下setup.py中是否有恶意代码。 当然这可能难为一些同学了,那就建议你不要以root权限进行安装,比如普通用户可使用pip –user 来避免使用root权限安装包,然后从靠谱的站点下载Python Package 源码包。
2、对于使用pip 进行Package安装的同学
仅安装二进制的包,即采用wheels机制分发的源码包,后缀为.whl, 可以通过–only-binary 指定仅安装二进制软件包,比如:
pip install --only-binary :all: Django
如果不加–only-binary,则下载的是源码包,如下:
这里补充一下关于wheels的说明(详情点击0×03中的参考链接):
简单的讲,通过wheels机制分发的软件包,可以理解为在上传package时将已经在本地执行过setup.py的结果,然后打包上传了。
下载后再次安装的时候就不会再执行setup.py了,故也就无法通过setup.py执行恶意代码了。
pip 现在支持源码包(.tar.gz后缀,里面包含setup.py文件,安装时会执行setup.py)安装和whl二进制包安装,所以得小心点。
校验下软件包的hash
–require-hashes ,加上这个安装选项
擦亮双眼,别被披着羊皮的狼给骗了(比如相似名字或者同形异议字的包给骗了)
3、建议Pypi 加大审核力度,尽可能减少恶意软件包的上传
0×03 参考资料
https://blog.zengrong.net/post/2169.html
https://packaging.python.org/discussions/wheel-vs-egg/
https://paper.seebug.org/326/
https://pythonwheels.com/
https://github.com/pypa/pip/issues/4735
https://cuyu.github.io/python/2017/08/07/%E4%BD%BF%E7%94%A8setuptools%E5%AE%9E%E7%8E%B0pip-install%E6%97%B6%E6%89%A7%E8%A1%8C%E6%8C%87%E5%AE%9A%E8%84%9A%E6%9C%AC
本文将结合一个实例讲解安装Fake Python Package时可能引起的任意代码执行风险(原理同Package 钓鱼,所以安装Python Package 一定要小心哦)以及相应的缓解办法。
一般来说,利用Python Package执行一些特定代码有两种途径:
在Package 执行的时候,称为运行时任意代码执行;
在Package 安装时就触发任意代码执行, 称为安装时任意代码执行。
本文以后者为例进行演示与说明。
0×01 实验与分析
1、演示
恶意的Package构造如下:
非常简单,就是一个安装入口文件setup.py (setup.cfg用于预先设置一些安装选项)。
当我们执行python setup.py install 或者 更常用的命令 pip install freebuf/ (这里freebuf后加上一个’/'表示安装本地名为freebuf 文件中的源码,如果freebuf这个包通过源码包形式上传至Pypi的后,便可省略‘/’) 的时候便会触发预先设置好的恶意代码,演示如下:
注意到上图中的Running setup.py了吗,这代表这时恶意代码已经开始执行,恶意代码会在/ 目录下写入一个明文Freebuf的文件,内容为:“欢迎大家来Freebuf投稿!”
2、分析
这是怎么实现的呢? 答案就是Hook setup.py install 过程 ,原理如下:
setuptools 包提供了一个安装类 : setuptools.command.install.install,只要继承这个类,然后重写其run方法,那么就可以达到hook pip install xxx/ 或 python setup.py install 行为的目的。
完整hook 需要2步。
第一步,重写安装类,即重写原生install 类的ru 方法:
class CustomInstallCommand(install):
重写setuptools.command.install.install 的run方法,可以实现调用自定义函数,在pip install 的时候触发
def run(self):
无奈人生安全网
custom_function()
install.run(self)
这里的custom_function 就可以用来执行一些羞羞的操作(比如本例中的在/ 目录下写入一个Freebuf的文件,内容为: 欢迎大家到Freebuf投稿!),你懂得。
第二步,在setuptools.setup 设置中指明重写后的安装类:
setuptools.setup(
...
,
cmdclass={
'install': CustomInstallCommand,
},
)
0×02 如何防范
1、对于习惯下载源码包,然后本地安装的同学
在安装前检查一下setup.py中是否有恶意代码。 当然这可能难为一些同学了,那就建议你不要以root权限进行安装,比如普通用户可使用pip –user 来避免使用root权限安装包,然后从靠谱的站点下载Python Package 源码包。
2、对于使用pip 进行Package安装的同学
仅安装二进制的包,即采用wheels机制分发的源码包,后缀为.whl, 可以通过–only-binary 指定仅安装二进制软件包,比如:
pip install --only-binary :all: Django
无奈人生安全网
如果不加–only-binary,则下载的是源码包,如下:
这里补充一下关于wheels的说明(详情点击0×03中的参考链接):
简单的讲,通过wheels机制分发的软件包,可以理解为在上传package时将已经在本地执行过setup.py的结果,然后打包上传了。
下载后再次安装的时候就不会再执行setup.py了,故也就无法通过setup.py执行恶意代码了。
pip 现在支持源码包(.tar.gz后缀,里面包含setup.py文件,安装时会执行setup.py)安装和whl二进制包安装,所以得小心点。
校验下软件包的hash
–require-hashes ,加上这个安装选项
擦亮双眼,别被披着羊皮的狼给骗了(比如相似名字或者同形异议字的包给骗了)
3、建议Pypi 加大审核力度,尽可能减少恶意软件包的上传
内容来自无奈安全网
0×03 参考资料
https://blog.zengrong.net/post/2169.html
https://packaging.python.org/discussions/wheel-vs-egg/
https://paper.seebug.org/326/
https://pythonwheels.com/
https://github.com/pypa/pip/issues/4735
https://cuyu.github.io/python/2017/08/07/%E4%BD%BF%E7%94%A8setuptools%E5%AE%9E%E7%8E%B0pip-install%E6%97%B6%E6%89%A7%E8%A1%8C%E6%8C%87%E5%AE%9A%E8%84%9A%E6%9C%AC
www.wnhack.com