eval補(bǔ)充
系統(tǒng)攻擊
res = eval(input('請輸入>>>'))
print(res, type(res))
'''
請輸入>>>12
12 <class 'int'>
'''
?可以直接拿到關(guān)鍵信息,,這里是不是看著沒啥,那么在控制臺輸入呢:
?
(venv) E:\selenium_test\def_test>python toml_read.py
請輸入>>>__import__('os').system('dir')
驅(qū)動器 E 中的卷是 Job
卷的序列號是 4653-5263
E:\selenium_test\def_test 的目錄
2022/11/14 19:56 <DIR> .
2022/11/14 19:56 <DIR> ..
2022/10/15 13:09 555 csv_read.py
2022/11/03 23:32 18 log.txt
2022/11/14 19:56 1,803 toml_read.py
2022/11/07 22:39 996 Yaml_read.py
2022/11/14 16:08 <DIR> __pycache__
2022/09/17 10:56 95 作用域.py
2022/10/13 21:44 2,348 閉包.py
14 個文件 6,623 字節(jié)
3 個目錄 205,870,223,360 可用字節(jié)
0 <class 'int'>
?既然可以都到文件信息,,那么我直接打開呢:
?
def func():
return '我是清安'
res = eval(input('請輸入>>>'))
print(res, type(res))
?我的Py文件內(nèi)容??刂婆_讀取這個文件:
?
(venv) E:\selenium_test\def_test>python toml_read.py
請輸入>>>print(open('toml_read.py','rt',encoding='utf8').read())
# # -*- coding: utf-8 -*-
# ----清安—---
# 微信:qing_an_an
# 公眾號:測個der
def func():
return '我是清安'
res = eval(input('請輸入>>>'))
print(res, type(res))
None <class 'NoneType'>
?可別小看這open函數(shù),,配合eval可以直接在控制臺把你整個Py文件一字不落的都讀出來
?
限制
?之前是提到過一點點,現(xiàn)在來說說:
?
l = {}
l['__builtins__'] = None
res = eval(input('請輸入>>>'),l)
print(res, type(res))
?再次讀?。?/p>?
(venv) E:\selenium_test\def_test>python toml_read.py
請輸入>>>print(__import__('os').system('dir'))
Traceback (most recent call last):
File 'E:\selenium_test\def_test\toml_read.py', line 57, in <module>
res = eval(input('請輸入>>>'),l)
File '<string>', line 1, in <module>
TypeError: 'NoneType' object is not subscriptable
?報錯了,,就不被允許讀取了。
它與eval()類似
?
源碼
def exec(
__source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, Any] | None = ...
) -> Any: ...
?1,、源可以是表示Python表達(dá)式的字符串或編譯器()返回的代碼對象
2,、全局:全局必須是字典
3,、局部變量:局部可以是任何映射***
?
小例子
q = 3
g = {'n':9}
l = {}
exec('a=1+1', g, l)
print(l)
?i是全局名稱空間,g是局部名稱空間,。它會將第一個參數(shù)產(chǎn)生的值存入到局部中,我們可以通過打印局部得到結(jié)果,。
?
?如果沒有a亦或者局部中本來就存在一個鍵值對呢,,一起看看:
?
'''g中有值'''
q = 3
g = {'n': 9}
l = {'b': 1}
exec('1+1', g, l)
print(l)
# {'b': 1}
'''g中無值'''
q = 3
g = {'n': 9}
l = {}
exec('1+1', g, l)
print(l)
# {}
全局
?當(dāng)我不定義全局以及局部的時候:
?
q = 3
g = {'n': 9}
l = {}
exec('a=1+1')
print(l)
print(a)
'''
{}
2
'''
?在編譯器上a會提示你有誤(紅色下劃線)。但是依然可以輸出,。
前面說了,,是默認(rèn)傳入局部的,但是上述錯處本身就在全局,,所以全局打印是可以得到結(jié)果的,。
?
局部
def func():
q = 3
g = {'n': 9}
l = {}
exec('a=1+1')
print(l)
print(a)
func()
?這樣是不被允許的。錯誤提示:NameError: name 'a' is not defined,,名字沒有定義,。為什么呢?
在上述中,,全局中使用局部是被允許的,,那是因為在這背后有一個綁定的過程,全局使用locals等同于使用globals,。
exec('a=1+1'),,其默認(rèn)是:exec('a=1+1',globals(),locals())。在上述中,,需要分清的是,,locals的值并未與當(dāng)前的局部空間綁定,所以func函數(shù)不認(rèn)識a,。所以我們可以傳入g,,l進(jìn)去綁定一下:
?
def func():
q = 3
g = {'n': 9}
l = {}
exec('a=1+1',g,l)
print(l)
func()