
lighttpd 1.4.85 - Élevé - À distance - Chemin - Win32 natif GET /..%20/ lit en dehors de la racine du document
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · lighttpd-win32-dotdot-space
Classe : Lecture de fichier Portée : Distante
lighttpd 1.4.85 (4852959) - lighttpd
Le staticfile natif _WIN32 joint document-root à rel_path après buffer_path_simplify. Simplify ne replie ../ que lorsque le troisième octet est /. http_response_prepare_physical supprime les espaces et points de fin uniquement sur le chemin entier. GET /..%20/windows/win.ini reste donc /.. /windows/win.ini. _wstati64 / _wopen sans préfixe \\?\ laissent alors Win32 supprimer l'espace par composant et traiter ce segment comme ...
Un GET/HEAD non authentifié sur lighttpd natif Windows lit un fichier régulier en dehors de document-root que le compte worker peut ouvrir. Unix/Linux n'est pas concerné par ce reliquat. Lecture de fichier, pas RCE.
Le lab est un gadget de ces fonctions épinglées. Ce n'est pas un worker Win32 natif réel. La dernière ligne utilise how=gadget.
| ID | pas encore de CVE |
| Classe | Lecture de fichier (path traversal, natif Win32 ..%20/) |
| Portée | Distante (GET/HEAD non authentifié) |
| CWE | CWE-22 |
| CVSS | Élevé : 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Produit | lighttpd1.4 |
| Affecté | 1.4.85 (4852959e67ef51ea68084984400d3264b854c97d) natif _WIN32 |
| Auth | aucune. mod_staticfile par défaut |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement, how=gadget |
Nécessite un lighttpd natif Windows servant des fichiers statiques. Le compte worker doit pouvoir ouvrir le fichier régulier cible.
| Privilège | Méthode / sink | Prouvé en lab ou déduit |
|---|---|---|
Lire un fichier en dehors de document-root | GET /..%20/<name> non authentifié | Prouvé en lab (gadget). Le corps HTTP 200 est le secret parent |
Même classe pour un autre espace/point ASCII de fin sur un composant .. non final | url-decode puis simplify conserve .. | Prouvé en lab pour %20. Déduit pour un autre espace/point de fin |
| HEAD sur le même chemin | staticfile HEAD | Déduit. Le lab a utilisé GET |
Négatif : vrai /../ | buffer_path_simplify replie ../ | Prouvé en lab. 404, /windows/win.ini simplifié, aucun témoin |
| Négatif : open POSIX Unix de la chaîne physique non simplifiée | open("/srv/htdocs/.. /windows/win.ini") | Prouvé en lab. ENOENT |
Fermé sur ce reliquat : staticfile Unix/Linux ; Cygwin (même suppression, open POSIX) ; parseopt %5C de 1.4.85 ; alias CVE-2018-19052 ; Host CVE-2014-2324. Pas de RCE. Pas une écriture.
J'ai épinglé le tag lighttpd-1.4.85. Vingt chasses. Staticfile Unix/Linux par défaut, FastCGI, proxy, TLS, auth, HTTP/2, alias/rewrite : rien à ce niveau. La vague de parseurs 1.4.81-1.4.85 avait déjà fermé les trailers, les conflits d'en-têtes CGI et les Content-Length de backend invalides.
buffer_path_simplify ne replie ../ que lorsque walk[2] == '/'. La suppression WIN32 dans http_response_prepare_physical (src/response.c 334-360) est la queue du chemin entier. _wstati64 / _wopen (src/fs_win32.c 24-77) passent de l'UTF-16 sans \\?\, donc Win32 supprime les espaces de fin par composant et .. devient ... La jointure physique est doc_root + rel_path sans vérification de basedir après stat.
Fausses pistes déjà consignées : traiter l'ENOENT Unix comme « pas un bug » (c'est le contrôle négatif) ; qualifier Cygwin de natif Win32 ; prétendre que le %5C de 1.4.85 est ce reliquat ; gonfler la lecture de fichier en RCE. Théâtre : un reverse shell. L'oracle est un corps 200 provenant du parent de document-root.
python3 lighttpd-win32-dotdot-space-Abraxas-Labs.py
ou
cd lab
./run.sh
Le lab est un gadget fidèle de buffer_urldecode_path, buffer_path_simplify (mapping Win32 '\\'), la suppression de queue de response.c, et _wstati64 sans \\?\. L'open POSIX Unix est le contrôle négatif. La résolution Win32 est implémentée comme la même suppression d'espaces de fin par composant, puis . / .., puis un open POSIX du chemin résolu. HTTP loopback 127.0.0.1:19400.
/index.html -> 200 public-index, aucun témoin./../windows/win.ini -> 404, /windows/win.ini simplifié./..%20/windows/win.ini -> décodé /.. /windows/win.ini, simplify a conservé l'espace, ENOENT Unix, Win32 a résolu /srv/windows/win.ini, témoin 200.SUCCESS lighttpd-win32-dotdot-space how=gadget win32-get=200 unix-open=enoent simplify-kept-dotdot-space=yes LIGHTTPD-WIN32-DOTDOT-SPACE-WITNESS
Supprimer les espaces et points de fin par composant de chemin avant simplify, ou préfixer les opens Win32 avec \\?\ et rejeter un chemin physique qui ne reste pas sous document-root.
4852959e67ef51ea68084984400d3264b854c97d)src/buffer.c · src/response.c · src/fs_win32.c%5C de 1.4.85 · alias CVE-2018-19052 · Host CVE-2014-2324GNU Affero GPL v3.0. Voir LICENSE. Lab loopback uniquement. Aucune garantie.