在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库执行系统命令 。
文章插图
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()函数也只能进行类型转换 。)
推荐阅读
- 陈赫|李铁被调查原因曝光!低估了身价152亿富豪的能量,背后有人保他
- 夜城赋|《夜城赋》首播,角色人设佳,主演演技好,被流量耽误的好剧
- |企业职工教育培训经费列支范围有哪些?
- 禁止燃放烟花爆竹的通告?禁止燃放烟花爆竹内容有哪些?
- 陈道明|《庆余年2》启动!曝肖战李沁被换、陈道明辞演,新人选引热议
- 阿娇|郑钧老婆曝光娱乐圈“五角恋”,阿娇、谢娜、胡可都被卷入
- 身份证放洗衣机里洗了还能用吗?身份证被洗衣机洗过后还能用吗?
- 梁靖康|“美作”梁靖康后援会永关,不需要粉丝言论被爆,网友:是条汉子
- 谢娜|谢娜外出就餐被认出,却拒不承认超幽默,还自称曾被说像林青霞
- 小S|小S黔驴技穷,又来“坑姐”了?前一天还被蔡康永说:你真落寞了