samedi, janvier 25 2014

Hash of a file using a built-in Windows tool

Calculating or verifying the hash of a file should be a common task to ensure file integrity - e.g. a file you just downloaded over a http connection. Unfortunately, there is no well-known tool under Windows to perform such a task, and most forums suggest writing their own PowerShell script, C# program or download further third party tools.

I recently stumbled across a little known but powerful tool shipped by Windows (at least since Windows 7, probably since Vista), which performs exactly this task: certutil:

certutil -hashfile <file> [MD5|SHA1|SHA256|SHA512]

Usage example – compute the SHA512 hash of a given file

C:\temp>certutil -hashfile iso_dl_over_http.iso SHA512
Hachage SHA512 du fichier iso_dl_over_http.iso :
f7 fe 44 29 17 9b dd 4c d3 01 77 ce 66 39 60 f1 53 bb 5d dd 8d 22 7b ef b6 69 29
28 16 38 ff bb a6 58 57 b4 b4 3a 60 65 dc 96 23 8a 2a 0a 9e 5f ca c4 fe 40 ec 9
8 74 05 f9 95 6f 78 bd 7f 7e 15
CertUtil: -hashfile La commande s'est terminée correctement.

jeudi, mars 1 2012

SPAM dans les commentaires de blog

Avoir des spams sur son blog, c’est malheureusement inévitable de nos jours, surtout si on laisse les commentaires ouverts indéfiniment comme c’est le cas sur ce blog.

Avec DotClear, les commentaires sur les articles sont fermés au bout de plusieurs semaines. Mais comme je souhaitais “jouer” un peu avec mon blog, j’ai décidé de laisser les commentaires ouverts de manière permanente.

Afin d’éviter de servir de caisse de résonnance pour les spameurs de tout poils, j’ai cependant pris quelques précautions. Tout d’abord, j’ai vérifié que les extensions anti-spam de DotClear suivantes étaient bien actives:

  • IP Filter – permet de définir une liste noire ou blanche
  • Bad Words – évite de devoir se poser la question en cas de commentaires avec certains mots clés douteux
  • IP Lookup
  • Links Lookup
  • Fair Trackbacks

A vrai dire, les trois derniers filtres sont peu sollicités, car après avoir créé une liste IP de spameurs (filtrage non seulement sur l’IP mais sur tout le range de l’opérateur en question), il n’y a plus de grandes surprises qui nous attendent.

Ci-dessous se trouve une liste des derniers spams reçu, où il apparait très clairement que l’article Limits of not having Visual Studio when developing attire énormément de commentaires non sollicités:

image

Pourquoi donc ce grand intérêt pour cette page? Il s’avère que cet hiver, 3 commentaires étranges ont été postés précisément sur cette article, avec comme site référant http://google.com, comme adresse email hellojohnatan@aol.com et provenant tous de l’adresse IP 81.25.45.63:

image

Curieux de voir un lien vers Google, j’ai laissé le commentaire en ligne. Le résultat – plusieurs dizaines de spams sur le même article est sans commentaire. Un élément de reconnaissance - la présence de 08)) et une URL pointant vers http://google.com permet au spameur de retrouver les blogs acceptant des commentaires. Une recherche exacte sur le terme, marqueur y compris, retourne plusieurs dizaines de pages:

image

Finalement, je me suis intéressé au parcours et logs laissé par ces visiteurs récurent. Est-ce qu’ils voient au moins mes publicités ou augmentent mes statistiques? Cela semble malheureusement peu probable, vu que le peu d’interactions avec le site – juste:

  • Un GET sur la page, avec comme referal la page elle-même et aucun user-agent
  • Immédiatement un POST avec le commentaire publicitaire – aucune autre ressource du site n’est chargée
  • Finalement le suivi du redirect vers la page de confirmation
89.33.1.174 - - [20/Feb/2012:01:09:11 +0100] "GET /misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing HTTP/1.1" 200 12463 "https://www.ness.ch/misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing" "-"
89.33.1.174 - - [20/Feb/2012:01:09:12 +0100] "POST /misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing#pr HTTP/1.1" 302 12613 "https://www.ness.ch/misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing" "-"

89.33.1.174 - - [20/Feb/2012:01:09:13 +0100] "GET /misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing&pub=0 HTTP/1.1" 200 12577 "https://www.ness.ch/misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing&pub=0" "-"
89.33.1.174 - - [20/Feb/2012:01:09:13 +0100] "GET /misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing HTTP/1.1" 200 12463 "https://www.ness.ch/misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing" "-"
89.33.1.174 - - [20/Feb/2012:01:09:30 +0100] "POST /misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing#pr HTTP/1.1" 302 12615 "https://www.ness.ch/misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing" "-"
89.33.1.174 - - [20/Feb/2012:01:09:30 +0100] "GET /misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing&pub=0 HTTP/1.1" 200 12577 "https://www.ness.ch/misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing&pub=0" "-"
89.33.1.174 - - [20/Feb/2012:01:09:31 +0100] "GET /misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing HTTP/1.1" 200 12463 "https://www.ness.ch/misc/?post/2011/02/07/Limits-of-not-having-Visual-Studio-when-developing" "-"

Bref, mis à part augmenter le nombre de commentaires dans les spams, ce type de visiteur n’apporte rien que des nuisances. J’ai décidé pour l’instant de conserver les 3 commentaires “balises” actifs, mais je risque de revoir ce choix dans un proche futur.

dimanche, octobre 2 2011

Sauvegarde journalière de logs sur un WD MyBookWorld

Mon hébergeur de site Internet met à disposition via FTP plusieurs générations de logs web et FTP. Ces logs pouvant être plus qu’intéressants, voici comment les sauvegarder automatiquement sur un disque dur réseau MyBookWorld:

 1. Script en lui-même

Le script en lui-même - getLogsFtps.php - est écrit en PHP et contient les éléments suivants:

  • Aucune limite de temps n’est définie, afin que le script puisse tourner en boucle en continu
  • Trois variables principales sont utilisées:
    • $BASEPATHFTPS pour indiquer le chemin pour le téléchargement FTPS, y compris le username et password
    • $BASEPATHLOCAL pour définir dans quel répertoire les logs seront sauvés
    • $listOfFiles pour la liste des fichiers à télécharger. PHP n’arrivant pas à lire la liste des fichiers présents dans un répertoire, il faut explicitement définir quels fichiers téléchargés. Ce n’est pas un grand problème dans ce cas, car les fichiers ont toujours la même structure, à savoir web.log, web.log.0, web.log.1.gz à web.log.6.gz, ftp.log et finalement ftp.log.0 à ftp.log.30
  • Chaque fichier dans la variable $listOfFiles sera téléchargé et sauvé dans un sous-répertoire de $BASEPATHLOCAL
  • A la fin de la boucle, le script PHP se met en veille (fonction sleep) jusqu’au lendemain à 9h00

<?php

    set_time_limit(0);
   
    while (true) {
        $BASEPATHFTPS = 'ftps://USER:PASSWORD@HOSTNAME/logs/';
        $BASEPATHLOCAL = '/shares/PathTo/Logs/SiteX/';
        $stream_options = array('ssl' => array('verify_peer' => false, 'ciphers' => 'HIGH'));
        $stream_context = stream_context_create($stream_options);
       
        $listOfFiles = array_merge(
                            array('web.log', 'web.log.0', 'ftp.log'),
                            generateFilenameRange('web.log.', 1, 7, '.gz'),
                            generateFilenameRange('ftp.log.', 0, 31, '')
                        );
       
        $currTimeFolder = strftime('%Y-%m-%d_%H-%M-%S');
        mkdir($BASEPATHLOCAL . $currTimeFolder);
        foreach ($listOfFiles as $f)
            downloadFile($BASEPATHLOCAL . $currTimeFolder . '/', $f);
           
        sleepUntilNextDay();
    }
   
    function generateFilenameRange($basename, $fromIncluded, $toExcluded, $suffix) {
        $diff = $toExcluded - $fromIncluded;
        $result = array();
       
        for($i = 0; $i < $diff; $i++) {
            $result[$i] = $basename . ($i + $fromIncluded) . $suffix;
        }
       
        return $result;
    }
   
    function downloadFile($saveDir, $dlFile) {
        global $BASEPATHFTPS, $stream_options, $stream_context;

        $fsave = fopen($saveDir . $dlFile, 'w', 0);
        if ($fdl = fopen($BASEPATHFTPS . $dlFile, 'r', 0, $stream_context))
        {
            while (!feof($fdl)) {
                fwrite($fsave, fread($fdl, 8192));
            }
          
            // Closes the file handle
            fclose($fdl);
            fclose($fsave);
        }
        else
        {
            die('Could not open file.');
        }
    }
   
    function sleepUntilNextDay() {
        $nextDay = strtotime('next day 9am');
        $sleepTime = ($nextDay-time());
        sleep($sleepTime);
    }
?> 

2. Mise en place du script

Le script peut être lancé très facilement via la commande suivante:

php -q getLogsFtps.php &

Pour une solution légèrement plus élégante, j’ai préféré créer dans le répertoire /root/ un sous-dossier /root/scripts/ où tous les scripts sont stockés. /root/scripts/getLogsFtps.php n’est cependant qu’un lien symbolique vers /share/logs/scripts/getLogsFtps.php où le fichier original est conservé.

3. Problèmes restants

Malheureusement ce script contient encore quelques imperfections tels que la non-vérification du certificat SSL ('verify_peer' = false).

Bien qu’au début je pensais que le problème venait du certificat SSL servi (un certificat *.infomaniak.ch valide étant présenté pour l’accès à ftp.mondomain.ch), un second test en référençant directement le hostname du provider (imuXX.infomaniak.ch) affichait la même erreur. Il s’avère qu’aucune liste de certificats approuvée (CAs) n’est présent sur le NAS MyBookWorld, ce qui fait qu’aucune vérification ne peut avoir lieu!

Bien que la non-validation n’est pas belle, cela évite néanmoins qu’un attaquant seulement capable de lire le trafic puisse intercepter mon mot de passe.

- page 1 de 2