Bloquer les attaques proc/self/environ%00 via les virtualhosts de Apache2

Un truc que j’ai pu constater en regardant les logs d’accès Apache sur le site : chaque jour, j’ai une vingtaine de tentatives d’injections via l’URL, qui ressemble à ça (celle-là date d’aujourd’hui) :

220.194.62.53 – – [12/May/2010:01:23:17 +0200] « GET /323-vtigercrm-procedure-dinstallation-et-de-changement-de-langage?module=Accounts&action=../../../../../../../../../../../../../../../proc/self/environ%00 HTTP/1.0 » 200 46444 « – » « libwww-perl/5.805 »

Heureusement, et d’après ce que j’ai pu comprendre, cette commande ne fais pas grand chose chez moi dans la mesure où le rewrite de l’URL mis en place sur Apache met un peu par terre la tentative. Cela dit, je suis curieux, et ce que j’ai pu voir sur le web à propos de ce genre d’attaque ne me fait pas beaucoup plaisir.

On peut voir notamment que quand on tape sur Google « ../../../../../../../../../../../../../../../proc/self/environ%00 », on tombe sur environ 1150000 résultats, ce qui montre que le phénomène n’est pas isolé.

Qu’à cela ne tienne, je continue mes recherches, et je tombe sur un thread à propos de Joomla qui dit notamment :

Effectivement, à la racine du site, j’ai trouvé les fichiers else.php et CREDIT.php.
En les téléchargeant sur mon PC, mon anti-virus à trouvé le virus Backdoor:PHP/Phricbot.A.

J’ai supprimé ces fichiers.

J’ai ensuite installé crawltrack et crawlprotect pour surveiller les attaques et les limiter.

« Oùlààà », me dis-je. Donc comme je ne sais pas si la tentative a fonctionné, je teste sur mon serveur si je trouve un else.php et un CREDIT.php (avec un locate else.php par exemple), ce qui ne me renvoie rien. Ouf.

Mais je ne m’arrête pas là. Après une ou deux recherches sur le net, j’ai trouvé un super post sur les .htaccess, ce qui m’a permit de rajouter les lignes suivantes dans mon fichier virtualhost gérant le blog. Notez que par rapport aux lignes fournies dans le billet, j’ai enlevé la ligne « RewriteCond %{QUERY_STRING} CONFIG_EXT([|%20|%5B).*= [NC,OR] » car celle-ci n’était pas reconnue par Apache2 lors du reload. Notez également que j’ai préféré mettre ces lignes dans le virtualhost gérant mon site dans la mesure où c’est mieux pour les performances d’Apache2 (en fait, si j’ai bien compris, le virtualhost est chargé au reload d’Apache2 et pour toutes les requêtes suivantes, alors que le .htaccess est chargé à chaque requête, ce qui présente une redondance inutile).

Voilà les lignes ajoutées :

RewriteCond %{REQUEST_METHOD} (GET|POST) [NC] RewriteCond %{QUERY_STRING} ^(.*)(%3C|<)/?script(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%3D|=)?javascript(%3A|:)(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)document\.location\.href(.*)$ [OR]
#the following rules can block some off your url, in case of problem try to suppress them one per one until you solve it
RewriteCond %{QUERY_STRING} ^(.*)(%3D|=|%3A|%09)http%3a(%3A|:)(/|%2F){2}(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%3D|=|%3A|%09)ftp(%3A|:)(/|%2F){2}(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%3D|=|%3A|%09)ht%20tp(%3A|:)(/|%2F){2}(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%3D|=|%3A|%09)htt%20p(%3A|:)(/|%2F){2}(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%3D|=|%3A|%09)http%20(%3A|:)(/|%2F){2}(.*)$ [NC,OR]
RewriteCond %{QUERY_STRING} ^(.*)(%3D|=|%3A|%09)h%20ttp(%3A|:)(/|%2F){2}(.*)$ [NC,OR]
#end of potential issue rules
RewriteCond %{QUERY_STRING} ^(.*)base64_encode(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)GLOBALS(=|[|%[0-9A-Z]{0,2})(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)_REQUEST(=|[|%[0-9A-Z]{0,2})(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)_vti(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)MSOffice(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)/etc/passwd(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)//(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)ShellAdresi.TXT(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)\[evil_root\]?(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)\.\./\.\./\.\./(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)/proc/self/environ(.*)$ [OR] RewriteCond %{QUERY_STRING} ^(.*)(SELECT|INSERT|DELETE|CHAR\(|UPDATE|REPLACE)(.*)$ [NC]
 #Block out any script trying to set a mosConfig value through the URL
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|%3D) [OR]
# Block out any script trying to base64_encode crap to send via URL
RewriteCond %{QUERY_STRING} base64_encode.*(.*) [OR]
# Block out any script that includes a < script> tag in URL
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2}) [OR]
# Block out any script that tries to set sbp or sb_authorname via URL (simpleboard)
RewriteCond %{QUERY_STRING} sbp(=|%20|%3D) [OR]
RewriteCond %{QUERY_STRING} sb_authorname(=|%20|%3D)
# Send all blocked request to homepage with 403 Forbidden error!

Donc, au final, je ne dis pas que cela protègera le serveur de toute attaque (surtout des attaques type DoS de toute façon), mais bon c’est déjà un cran de sécurité supplémentaire.

8 réflexions sur « Bloquer les attaques proc/self/environ%00 via les virtualhosts de Apache2 »

  1. Salut,

    Sinon pour éviter des ajouts de regle qui peuvent faire planter ton vhost ou foutre en l’air ton référencent ( limitation du scan de Google etc.. ) , car j’en fait fais les frais à de multiple reprise, je te conseille de mettre à la place de tes règles le module mod_security de apache2 qui permet de bloquer bcp de type d’intrusion.

    Il y a meme des sites qui proposent des filtres à jours comme http://www.gotroot.com.

    Voila mon ptit retour d’expérience 😉

    RépondreRépondre
  2. @Nil: Justement, là je vois que j’ai pleins de codes de réponse 304 (= NOT MODIFIED) pour les requêtes du Google Bot. Tu sais si ça impactes le référencement ? (mes recherches sur le web ne sont pas super fructueuses pour la 304…)

    RépondreRépondre
  3. @Nil: A ce que j’ai pu trouver sur la doc de Google Webmaster Tools, l’erreur 304 est plutôt « conseillé » qu’autre chose :

    304 (Not modified)

    The requested page hasn’t been modified since the last request. When the server returns this response, it doesn’t return the contents of the page.

    You should configure your server to return this response (called the If-Modified-Since HTTP header) when a page hasn’t changed since the last time the requestor asked for it. This saves you bandwidth and overhead because your server can tell Googlebot that a page hasn’t changed since the last time it was crawled

    C’est là : http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=40132

    RépondreRépondre
  4. Lol tu ne m’as pas bien compris 🙂

    Je n’ai jamais dit que tes règles étaient fausses mais utiliser un mod de apache2 permet de faire se genre de chose automatiquement et en évitant des erreurs frappes qui peuvent amener des probs de référencement ou de scan de Google.

    RépondreRépondre
  5. @Nil: Ah ok je n’avais pas saisi le coup de la faute de frappe 😀

    Pas grave, je vais tester ma configuration. Si Google me désindexe, je virerai et je passerai en mode « mod_security ».

    RépondreRépondre
  6. @Nicolas: Ah oui pas mal non plus ça. Je l’utilisais un temps, mais n’ayant pas la main sur ce qui était effectué, je n’avais pas vraiment confiance dans l’étendue de ses capacités. Au final, je pense que ça reste une bonne solution surtout qu’on n’a pas toujours la main sur la conf Apache, de toute façon.

    RépondreRépondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.