
Apache Traffic Server 10.2.0 - Élevé - Local - Résidu de privilèges - Socket unix JSON-RPC en mode non restreint 0777
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · ats-jsonrpc-unrestricted
Classe : Privilège résiduel (reconnaissance) Portée : Locale
Apache Traffic Server 10.2.0 (b1df7334) - Apache Software Foundation
Le socket unix JSON-RPC est par défaut à restricted_api false. Le fichier jsonrpc.yaml livré ne contient que des commentaires, donc l'initialiseur C++ l'emporte. Le mode de bind SO_PEERCRED sous Linux est 0777. Tout uid local capable d'atteindre l'inode du rundir se connecte sans jeton et extrait les enregistrements actifs (y compris les chemins de clés SSL) ainsi que les 5-uplets du connection-tracker. Les écritures restent protégées par SO_PEERCRED (euid == 0 ou euid d'ATS). Le tableau de la documentation indique true / 0700 ; le code et l'exemple commenté indiquent false / 0777.
Il ne s'agit pas de CVE-2026-58159 (ACL du listener UDS HTTP). Il n'y a pas de JSON-RPC TCP/HTTP. Le chargement de plugins et l'écriture de configuration restent refusés pour un uid étranger.
| ID | pas encore de CVE |
| Classe | Privilège résiduel (reconnaissance) |
| Portée | Locale (uid non privilégié sur l'hôte ATS) |
| CWE | CWE-276, CWE-284 |
| CVSS | Élevé : 7.1 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| Produit | Apache Traffic Server |
| Affecté | 10.2.0 (b1df7334b39a878971c376da849e8da4984918b6) unix JSON-RPC par défaut |
| Auth | aucune sur les méthodes non restreintes. Accès au système de fichiers local du rundir. |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1:18720 uniquement. Image ats-10.2.0-lab:local. |
J'ai épinglé le tag 10.2.0, commit b1df7334b39a878971c376da849e8da4984918b6. Image construite depuis les sources.
Uid local sur l'hôte ATS (pas root, pas l'euid d'ATS). RPC activé. JSON-RPC unix activé. Rundir typique 0755 appartenant à ATS. Socket $RUNTIMEDIR/jsonrpc20.sock.
| Méthode | Cible | Privilège |
|---|---|---|
admin_lookup_records en tant qu'uid 10000 sur jsonrpc20.sock en 0777 | JSON-RPC non restreint (RpcAdminPubHandlers.cc) | Reconnaissance (prouvé en lab) : proxy.config.proxy_name=ATS-JSONRPC-UNRESTRICTED-WITNESS actif, chemins de clés SSL etc/trafficserver, proxy.config.admin.user_id=nobody. Les octets des clés ne figurent pas dans les enregistrements. |
get_connection_tracker_info | même socket | Reconnaissance (prouvé en lab) : tables de tracker entrant/sortant (vides sans charge). |
get_server_status, admin_host_get_status, admin_storage_get_device_status, filemanager.get_files_registry | même bit non restreint | Reconnaissance (déduit) : état de drain, markdown d'hôte, chemins de disques de cache, chemins de configuration absolus. |
admin_config_set_records en tant qu'uid 10000 | restreint par SO_PEERCRED | Intégrité : fermée (prouvé en lab). Erreur JSON-RPC 10 Unauthorized, Denied privileged API access for uid=10000. Enregistrement témoin inchangé. |
| drain / vidage de cache / mise hors ligne du stockage | méthodes restreintes | Disponibilité : fermée pour un uid étranger (source). |
Prouvé en lab vs déduit : socket 0777, lookup par uid 10000 de proxy_name / chemins de clés SSL, tables de tracker, écriture refusée, absence de JSON-RPC TCP : lab. Autres méthodes de lecture non restreintes : déduites du même contrôle.
Nécessite : un uid local sur l'hôte ATS. JSON-RPC unix activé (par défaut). SO_PEERCRED sous Linux pour que le bind non restreint soit en 0777. Rundir accessible (typiquement 0755).
| Surface | Lab |
|---|---|
admin_config_set_records en tant qu'uid 10000 | Non autorisé ; enregistrement témoin inchangé |
| TCP / HTTP JSON-RPC | absent ; HTTP 8080 / 18080 uniquement |
Chargement de plugin .so via RPC | SO_PEERCRED |
traffic_ctl de même uid | admin prévu |
umask+bind atomique quand restricted_api est vrai | 0700, correctif CHANGELOG maintenu |
| ACL du listener HTTP UDS CVE-2026-58159 | pas ce socket |
RPC est actif sauf si rpc.enabled: false. Seul CommType::UNIX existe. Le fichier jsonrpc.yaml.default fourni ne contient que des commentaires. Le décodage YAML n'écrit restrictedAccessApi que lorsque la clé est présente. Sinon :
bool restrictedAccessApi{
NON_RESTRICTED_API}; // ... 0700(default) or 0777
NON_RESTRICTED_API vaut false (IPCSocketServer.h:128-129). Le commentaire indique que 0700 est la valeur par défaut. L'initialiseur est la constante non restreinte.
Bind (IPCSocketServer.cc:310-342) : restricted_api à false plus SO_PEERCRED -> mode 0777. La dernière phrase du tableau de la documentation indique true par défaut. Le code et l'exemple commenté suivent false.
Fausses pistes : considérer le true de la documentation comme la valeur par défaut ; qualifier cela de RCE (écritures refusées) ; considérer que CVE-2026-58159 couvre le JSON-RPC de mgmt ; chercher un reliquat TCP de l'ancien XMLRPC de traffic_manager.
Mise en scène : une écriture en uid 10000. L'oracle est un proxy_name implanté plus des chaînes de chemin de clé SSL, puis un ensemble refusé.
python3 ats-jsonrpc-unrestricted-Abraxas-Labs.py
ou
cd lab
./run.sh
Loopback 127.0.0.1:18720. Projet Compose ats-jsonrpc-unrestricted. Image ats-10.2.0-lab:local. uid du labo 10000. Mode du socket 0777. Témoin ATS-JSONRPC-UNRESTRICTED-WITNESS. Dernière ligne :
SUCCESS ats-jsonrpc-unrestricted how=uds-0777-unrestricted-jsonrpc uid=10000 sock-mode=0777 lookup-proxy_name=ATS-JSONRPC-UNRESTRICTED-WITNESS ssl-key-path=etc/trafficserver tracker=ok write=unauthorized tcp-jsonrpc=absent ATS-JSONRPC-UNRESTRICTED-WITNESS
Définir restricted_api sur true par défaut et lier en 0700, conformément au tableau de la documentation. Aligner l'exemple commenté de jsonrpc.yaml. Maintenir les lectures non restreintes derrière une activation explicite. Les écritures nécessitent déjà SO_PEERCRED ; ne pas les ouvrir.