Diventa Autore per CoreTech | Scopri di più





Sfruttare SSTI in Thymeleaf

20/07/20 CoreTech Blog

Uno dei modi più comodi per creare pagine Web consiste nell'utilizzare modelli lato server. Tali modelli consentono di creare pagine HTML che includono elementi speciali che è possibile riempire e modificare in modo dinamico. Sono facili da capire per i progettisti e facili da mantenere per gli sviluppatori. Esistono molti motori di modelli lato server per diverse lingue e ambienti lato server. Uno di questi è Thymeleaf , che funziona con Java.

Le iniezioni di modelli lato server (SSTI) sono vulnerabilità che consentono all'attaccante di immettere codice in tali modelli lato server. In termini semplici, l'utente malintenzionato può introdurre il codice che viene effettivamente elaborato dal modello lato server. Ciò può comportare l'esecuzione di codice in modalità remota (RCE) , che rappresenta una vulnerabilità molto grave. In molti casi, tale RCE si verifica in un ambiente sandbox fornito dal motore modello, ma molte volte è possibile sfuggire a questo sandbox, il che può consentire all'attaccante di assumere il pieno controllo del web server.

Inizialmente SSTI fu studiato da James Kettle e successivamente da Emilio Pinna . Tuttavia, nessuno di questi autori ha incluso Thymeleaf nella sua ricerca SSTI. Vediamo quali opportunità RCE esistono in questo motore di template.

Introduzione a Thymeleaf

Thymeleaf è un moderno motore di template lato server per Java, basato sulla sintassi XML / XHTML / HTML5. Uno dei principali vantaggi di questo motore è il modello naturale . Ciò significa che un modello HTML Thymeleaf ha l'aspetto e il funzionamento esattamente come HTML. Ciò si ottiene principalmente utilizzando attributi aggiuntivi nei tag HTML. Ecco un esempio ufficiale:

<table>

  <thead>

    <tr>

      <th th:text="#{msgs.headers.name}">Name</th>

      <th th:text="#{msgs.headers.price}">Price</th>

    </tr>

  </thead>

Banner

  <tbody>

    <tr th:each="prod: ${allProducts}">

      <td th:text="${prod.name}">Oranges</td>

Banner

      <td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>

    </tr>

  </tbody>

</table>

Se apri una pagina con questo codice usando un browser, vedrai una tabella riempita e tutti gli attributi specifici di Thymeleaf verranno semplicemente ignorati. Tuttavia, quando Thymeleaf elabora questo modello, sostituisce il testo del tag con i valori passati al modello.

Hacking Thymeleaf

Per tentare un SSTI in Thymeleaf, dobbiamo prima comprendere le espressioni che compaiono negli attributi di Thymeleaf. Le espressioni di thymeleaf possono avere i seguenti tipi:

  • ${...}: Espressioni variabili: in pratica si tratta di espressioni OGNL o Spring EL.
  • *{...}: Espressioni di selezione - simili alle espressioni variabili ma utilizzate per scopi specifici.
  • #{...}: Espressioni di messaggi (i18n) - utilizzate per l'internazionalizzazione.
  • @{...}: Espressioni di link (URL): utilizzate per impostare URL / percorsi corretti nell'applicazione.
  • ~{...}: Espressioni di frammenti: ti consentono di riutilizzare parti di modelli.

Il tipo di espressione più importante per un tentativo di SSTI è il primo: espressioni variabili. Se l'applicazione Web si basa su Spring, Thymeleaf utilizza Spring EL. In caso contrario, Thymeleaf utilizza OGNL.

L'espressione di test tipica per SSTI è ${7*7}. Questa espressione funziona anche in Thymeleaf. Se si desidera ottenere l'esecuzione di codice in modalità remota, è possibile utilizzare una delle seguenti espressioni di test:

  • Springel: ${T(java.lang.Runtime).getRuntime().exec('calc')}
  • OGNL: ${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}

Tuttavia, come accennato in precedenza, le espressioni funzionano solo con attributi speciali di Thymeleaf. Se è necessario utilizzare un'espressione in una posizione diversa nel modello, Thymeleaf supporta l' inserimento di espressioni . Per utilizzare questa funzione, è necessario inserire un'espressione all'interno di [[...]] o [(...)] (selezionare l'una o l'altra a seconda se è necessario uscire da simboli speciali). Pertanto, sarebbe un semplice payload di rilevamento SSTI per Thymeleaf [[${7*7}]].

Le probabilità che il payload di rilevamento di cui sopra funzioni, tuttavia, sono molto basse. Le vulnerabilità SSTI si verificano in genere quando un modello viene generato dinamicamente nel codice. Thymeleaf, per impostazione predefinita, non consente tali modelli generati dinamicamente e tutti i modelli devono essere creati in precedenza. Pertanto, se uno sviluppatore desidera creare un modello da una stringa al volo , dovrà creare il proprio TemplateResolver. Questo è possibile ma accade molto raramente.

Una caratteristica pericolosa

Se esaminiamo più a fondo la documentazione del motore di template di Thymeleaf, troveremo un'interessante funzione chiamata pre-elaborazione delle espressioni . Le espressioni inserite tra i trattini bassi ( __...__) sono preelaborate e il risultato della preelaborazione viene utilizzato come parte dell'espressione durante l'elaborazione regolare. Ecco un esempio ufficiale dalla documentazione di Thymeleaf:

#{selection.__${sel.code}__}

Primi preprocessi di Thymelead ${sel.code}. Quindi, utilizza il risultato (in questo esempio è un valore memorizzato TUTTO ) come parte di un'espressione reale valutata in seguito ( #{selection.ALL}).

Questa funzionalità introduce un grande potenziale per una vulnerabilità SSTI. Se l'attaccante può controllare il contenuto del valore preelaborato, può eseguire un'espressione arbitraria. Più precisamente, si tratta di una vulnerabilità a doppia valutazione, ma questo è difficile da riconoscere usando un approccio black-box.

Un esempio reale di SSTI in Thymeleaf

PetClinic è un'applicazione demo ufficiale basata sul framework Spring. Utilizza Thymeleaf come motore modello.

La maggior parte dei modelli in questa applicazione riutilizza parti del modello layout.html , che include una barra di navigazione. Ha un frammento speciale (funzione), che genera il menu .

<li th:fragment="menuItem (path,active,title,glyph,text)" class="active" th:class="${active==menu ? 'active' : ''}">

      <a th:href="@{__${path}__}" th:title="${title}">

Come puoi vedere, l'applicazione preelabora ${path}, che viene quindi utilizzata per impostare un collegamento corretto ( @{}). Tuttavia, questo valore proviene da altre parti del modello:

<li th:replace="::menuItem ('/owners/find','owners','find owners','search','Find owners')">

Sfortunatamente, tutti i parametri sono statici e incontrollabili dall'attaccante.

Tuttavia, se proviamo ad accedere a una route che non esiste, l'applicazione restituisce il modello error.html , che riutilizza anche questa parte di layout.html . Nel caso di un'eccezione (e l'accesso a una route che non esiste è un'eccezione), Spring aggiunge automaticamente variabili al contesto corrente (attributi del modello). Una di queste variabili è di percorso (altri includono timestamp , traccia , un messaggio , e altro ancora).

La variabile path è una parte del percorso (senza decodifica URL) dell'URL della richiesta corrente. Ancora più importante, questo percorso viene utilizzato all'interno del menuItemframmento. Pertanto, __${path}__preelabora il percorso dalla richiesta. E l'attaccante può controllare questo percorso per raggiungere SSTI e, di conseguenza, RCE.

Come semplice test, possiamo inviare una richiesta a http: // petclinic / (7 * 7) e ottenere 49 come risposta.

Tuttavia, nonostante questo effetto, non siamo riusciti a trovare un modo per ottenere RCE in questa situazione quando l'applicazione viene eseguita su Tomcat. Questo perché è necessario utilizzare Spring EL, quindi è necessario utilizzare ${}. Tuttavia, Tomcat non consente i caratteri { e } nel percorso senza codifica URL. E non possiamo usare la codifica, perché ${path} restituisce il percorso senza decodifica. Per provare questi presupposti, abbiamo eseguito PetClinic su Jetty anziché Tomcat e ottenuto RCE perché Jetty non limita l'uso di { e } caratteri nel percorso:

http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})

Abbiamo dovuto usare i caratteri ( e ) perché dopo la preelaborazione l'@{} espressione riceve una stringa che inizia con / (ad esempio, /${7*7}), quindi l'espressione non viene trattata come espressione. L' @{} espressione consente di aggiungere parametri all'URL inserendoli tra parentesi. Possiamo usare questa funzione in modo improprio per cancellare il contesto e ottenere la nostra espressione eseguita.

Conclusione

L'iniezione di modelli sul lato server è molto più problematica di quanto sembri perché i modelli sul lato server vengono utilizzati sempre più spesso. Esistono molti di questi motori di template e molti di essi rimangono non sfruttati ma possono introdurre vulnerabilità SSTI se utilizzati in modo improprio. C'è molto da fare ${7*7}per raggiungere l'RCE, ma in molti casi, come puoi vedere, è possibile.

Come ricercatori di sicurezza, troviamo sempre interessante vedere come le tecnologie complesse si scontrano e si influenzano a vicenda e quanto rimane ancora inesplorato.


Articoli su Acunetix

Trovare le vulnerabilità dei siti web prima degli HackerL'importanza della convalida delle correzioni: lezioni da GoogleSDLC agile e sicuro - Best practiceIn che misura le aziende gestiscono la sicurezza delle applicazioni Web?Cross-Origin Resource Sharing (CORS) e intestazione Access-Control-Allow-OriginCosa sono i reindirizzamenti aperti?DevSecOps: come arrivarci da DevOpsIl bigino su SQL Injection per sviluppatoriSfruttare SSTI in ThymeleafSicurezza nginx: come proteggere la configurazione del serverRafforzamento del sistema Web in 5 semplici passaggiCos'è la sicurezza del sito Web - Come proteggere il tuo sito Web dall'hackingRapporto sulle vulnerabilità delle applicazioni Web Acunetix 2020Perché l'elenco delle directory è pericoloso?Cosa sono gli hack di Google?Cosa è l'attacco BEASTWeb Shells in Action - Rilevazione e prevenzione - parte 5Web Shells in Action - parte 4Mantenere le Web Shells sotto copertura - parte 3Introduzione alle web shell - parte 2: 101 Uso di PHPIntroduzione alle web shell - parte 1Debunking 5 miti sulla postura della sicurezza informaticaIniezioni di NoSQL e come evitarleConfigurazione passo passo di Acunetix con JenkinsCosa sono i riferimenti a oggetti diretti non sicuriAnche il più forte cade: un'iniezione SQL in Sophos XG FirewallAcunetix rilascia Business Logic RecorderCome recuperare un sito Web compromessoCome difendersi dagli hacker Black Hat durante la pandemia COVID-19Che cos'è l'inclusione remota dei file (RFI)?Apache Security - 10 consigli per un'installazione sicuraUn nuovo sguardo sugli attacchi correlati al proxy inversoVulnerabilità delle password comuni e come evitarleTutto quello che devi sapere sugli attacchi Man-in-the-MiddleChe cosa sono le iniezioni HTMLRed Teaming – 5 consigli su come farlo in modo sicuroTesta le tue competenze XSS utilizzando siti vulnerabiliPerché hacker malintenzionati hanno messo gli occhi sugli ospedaliPratiche di codifica sicura – I tre principi chiaveLa maledizione delle vecchie librerie JavaMutation XSS nella ricerca GoogleIgnorare SOP utilizzando la cache del browserCome e perché evitare reindirizzamenti e inoltri non convalidati?Dirottamento di sessione e altri attacchi di sessioneCome abbiamo trovato un altro XSS in Google con AcunetixChe cos'è un buffer overflowChe cos'è l'overflow di IntegerChe cos'è HSTS e perché dovrei usarlo?Che cosa è OS Command InjectionVulnerabilità delle entità esterne XML in Internet ExplorerCoreTech assicura protezione dei siti Web con AcunetixCoreTech distributore Acunetix a fianco dei partner per la CyberSecurityCyberSecurity applicativa, nuova opportunità per voi!