近期遇到Python模板注入問題,故在此整理,便於後期回顧。html
首先什麼是「Python模板」呢?Python有不少模板引擎能夠幫助咱們構建完善的Web應用程序。這裏將要討論的就是jinja2。而「模板注入」就是在模板中注入特定的代碼,這裏的模板多是文件,也多是字符串。python
在Jinja2中,使用{%...%}
執行for循環或賦值語句,使用{{...}}
把表達的結果打印到模板上。更具體的內容可直接查看Jinja2中文文檔。flask
# template.py from flask import from flask import Flask, request app = Flask(__name__) def exp(): input = request.args.get('input') result = Template("This is {{thing}}") return result.render(thing=input)
從{{}}
看出,這裏的thing就是一個變量,咱們能夠在url中能夠將期待的值輸入到input交給flask給到thing渲染。可是這裏的thing就是個字符串,若是傳入表達式,它並不能作出相應的執行。
app
對代碼進行如下修改,發現表達式被執行url
from jinja2 import Template from flask import Flask, request app = Flask(__name__) @app.route('/') def exp(): input = request.args.get('input') result = Template("This is " + input) return result.render()
咱們拿到這個漏洞天然想要更多的權限對系統或文件進行操做,這須要利用Python的特性,Python能夠利用os或subprocess模塊執行系統命令。code
那咱們怎麼找到os模塊呢?
能夠利用[].__class__
隨便肯定一個類,.__class__
前面的這個[]
一樣能夠換成''
或""
等。由於咱們的目的是肯定基類。
orm
那基類怎麼找呢?[].__class__.__base__
htm
找到基類了,就完成了第一步,接下來,咱們須要知道其直接子類的弱引用列表,方便咱們找到os模塊。那這個直接子類的弱引用列表怎麼找呢?[].__class__.__base__.__subclasses__()
。下圖僅做示意
blog
爲了更好的理解這個問題,仍是藉助攻防世界的題目Web_python_template_injection來作模板引擎
· 在題目場景連接後加上/{{[].__class__.__base__.__subclasses__()}}
便可查看列表
· 如何從這個列表中,找到os相關的類?
窮舉這個列表,若是os
在列表元素.__init__.__globals__
中,就print該元素及其位置。剩下的之後再補充吧。。
https://www.freebuf.com/column/187845.html
https://docs.python.org/release/3.8.3/library/stdtypes.html#special-attributes