被企业禁用的,那些python中的内置强大函数( 三 )


在python中,内建函数都在__builtins__模块中,在启动python时,python解释器就直接导入了__builtins__模块中的函数 。__import__()函数就是__builtins__模块中的一员,也就是说,python解释器默认导入了__import__()函数,用户可以直接调用 。
上面的代码在globals参数中将__builtins__设置成None,eval()函数就获取不到__import__()函数了,无法自己导包,执行代码报错 。
但是,限制用户导包,恶意用户还可以通过其他途径获取到os库 。
s = '[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__ == "zipimporter"][0]("C:/Users/xxx/Lib/site-packages/setuptools-28.8.0-py3.6.egg").load_module("setuptools").os.system("whoami")' eval(s, {"__builtins__": None}) 1212
Output:
desktop-xxxxxx 11
上面这种方式也可以成功执行系统命令 。代码中利用__class__和__subclasses__动态加载了基类object的所有子类(可以执行下面这行代码查看当前环境中基类都有哪些子类),然后找到了zipimporter,用zipimporter动态加载setuptools库的 .egg包,再链式调用load_module()成功导入setuptools库,从而成功调用os库执行系统命令 。

被企业禁用的,那些python中的内置强大函数

文章插图
 
print([x.__name__ for x in ().__class__.__bases__[0].__subclasses__()]) 11
在python中,有一些库中内置了os库,导入这些库后就能调用os库,其中就包含setuptools,此外还有configobj、urllib、urllib2等 。
当然,执行上面的代码需要有对应的.egg包,如果你也想演示看效果,你可以先在自己的电脑磁盘中全局搜一下,找不到再到网络下载 。
以上是eval()函数的一些安全隐患,可谓是防不胜防,在写代码时无形中就需要和恶意用户进行很多回合的思维对抗,假如有哪个细节稍微考虑不周,就会留下很大的隐患 。而且,关于eval(),恶意用户还有很多可以利用的方法,如删数据、暴力占满服务器的CPU资源等 。
既然用了就防不胜防,那只有不用才不会留下隐患,所以,在一些企业和项目中就禁用了eval()函数 。
(当然,python中也有替代方案,那就是ast.literal_eval()函数,ast.literal_eval()函数会判断字符串内容去掉首尾的引号后是不是合法的python类型,如果不是就报错,因此ast.literal_eval()函数也只能进行类型转换 。)




推荐阅读