Le calepin du geek
Geek : Personne s’intéressant à des domaines pointus, avec une once de créativité.

Ceci est un site perso, dans le pur esprit web 1.0, compilant des notes diverses sur des thèmes d’intérêt. (Informatique, programmation, voyage à vélo, réflexions)

Comment protéger un répertoire sous Windows

Un article assez technique et fouillé traitant de chiffrage, montage de partition et compilation d’un service SYSTEM en C.

Article mis en ligne le 19 août 2014
par aldoniel
Imprimer cet article logo imprimer

Article un peu obsolète car écrit en 2012 prenant l’exemple de truecrypt (retiré du marché en 2014 [1]), et de windows XP (même si l’astuce en compatible avec les versions ultérieures, il doit être possible de faire plus simple).

 But

 Critique

  • Pourquoi voudrait-on protéger quelque chose sans chiffrer ? c’est idiot, c’est une fausse sécurité puisqu’il "suffit" d’obtenir les privilèges admin en bootant sur un liveCD quelconque.
  • j’ai écrit ça sous XP, mais ça s’applique à mon avis à Seven et Vista

 Avantages

  • On peut contrer la critique ci-dessus en chiffrant tout le disque dur (et en mettant un mot de passe sur le bios tant qu’à faire).
  • C’est très geek de monter un disque secret sous sa session...
    • un malware quelconque (web based attacks ; USB autorun attack ; session laissée ouverte...) aura du mal à voler des fichiers que le système d’exploitation ne voit pas.
  • Comme le disque est déjà chiffré, je ne vais quand même pas créer un container truecrypt pour le même résultat : le double chiffrage prend vraiment trois plombes. (Déjà, le simple chiffrage, c’est très perceptible sur les usages intensifs du disque : sortie d’hibernation par ex.)

 Comment (théorie) ?

 En pratique

  • votre session principale windows doit être utilisateur ; vous devez avoir accès à un compte administrateur
  • créez une partition primaire (les partitions étendues sont incompatibles sous XP avec truecrypt whole disk encryption ; mais ça passe sous Vista/Seven)
    • cf Paragon Partition Manager™ 11 Free par ex., c’est mieux que Partition Magic.
    • ne lui donnez pas de point de montage (si c’est déjà le cas, ça se supprime avec le "Gestion des disques" de windows (C:\WINDOWS\system32\diskmgmt.msc)
  • lancez une console avec les droits admin (ex, créez un raccourci sur cmd.exe, faites clic-droit "éxécuter en tant que", utlilisateur suivant, compte admin) (ou faites le depuis le compte admin)
    • tappez montvol /?
      PNG - 16.7 ko
    • "aucun point de montage", c’est votre disque secret normalement. Copiez-coller votre ligne ( \\ ?\Volumebbc6926a-8348-11e1-ab7f-080027003cfb\ ici) quelque part, ça va servir (clic droit, sélection, enter).
    • faites un test en console
      • montage : mountvol  h: \\?\Volume{bbc6926a-8348-11e1-ab7f-080027003cfb}\ (où h : est le point de montage ; on peut mettre un répertoire NTFS vide à la place)
      • démontage : mountvol  h: /d

 Version manuelle (didactique...)

  • créez un raccourci sur le bureau avec les commandes ci-dessus (ça tombe bien, il y a des icones de cadenas dans %SystemRoot%\system32\SHELL32.dll )
    • dans (clic droit icone) les options, on peut cocher une touche de raccourci (hotkey) et demander les droits admin (pas très pratique)
  • créez une icône de démontage de même (mountvol  h: /d)

 Version automatisée

Un jour j’écrirai un installeur... (bon ok, jamais).

 Démonter automatiquement à chaque redémarrage du système

Je discute là différentes pistes, mais j’ai retenu celle de l’écriture d’un service, ce qui marche très bien.

  • utiliser l’éditeur de stratégie du groupe local gpedit.msc pour lancer la commande de démontage
    • nécessite une version "pro" de windows
    • cf ressources en bas de page
  • 2e essai : on peut exécuter un service avec les privilèges "system" en pré-logon... (c’est à dire que windows utilisera le plus haut niveau de privilèges pour exécuter notre commande, avant même qu’un utilisateur tape un mot de passe)
    • le plus simple est de le lancer via l’outil de microsoft Srvany.exe
    • mais c’est plus geek power d’écrire un service
      • tutoriel en c http://www.devx.com/cplus/Article/9857
      • ce tutoriel est très clair, de grande qualité (et il est indispensable d’en lire les pages 4 et 5 qui expliquent comment installer le service compilé)
        • code modifié : cf annexe).
        • Ce code est celui du tutoriel dont j’ai mis en commentaires la fonction de logging inutile en pratique, et ajouté la commande d’intérêt.
        • la commande qui démonte notre partition est system("mountvol.exe  h: /d"), où system en c est la fonction qui exécute une commande comme dans la console windows.
        • n’importe quel compilateur c fera l’affaire, il en existe même en ligne si on tape "online c compiler"
        • dans regedit.exe, HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[nom du service], créer la valeur Description = le msg de description, permet d’avoir un nom explicite dans la liste des services du panneau de configuration.

 Usage

 FAQ

  • que se passe-t-il si le volume est démonté pendant une écriture de fichier ?
    • windows, c’est bien fait pour une fois... : le point de montage est supprimé immédiatement sans avertissement, mais l’écriture se poursuit jusqu’à sa fin sans perte.

 Ressources diverses

 Annexes : Commandes pour monter démonter des volumes truecrypt

PNG - 18.2 ko
Pour faire des icônes sur le bureau...

 Monter

  • "C:\Program Files\TrueCrypt\TrueCrypt.exe" /v \Device\Harddisk0\Partition3 /l H  /q background
  • affiche juste la boîte de mot de passe.
  • \Device\Harddisk0\Partition3 à remplacer par votre partition chiffrée / container

 Tout démonter

  • "C:\Program Files\TrueCrypt\TrueCrypt.exe"  /dismount  /quit

 code service.c

#include <windows.h> #include <stdio.h> #include <stdlib.h> #define SLEEP_TIME 5000 //#define LOGFILE "d:\\temp\\runassvc.txt" SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE hStatus; void ServiceMain(int argc, char** argv); void ControlHandler(DWORD request); int InitService(); /* int WriteToLog(char* str) { FILE* log; log = fopen(LOGFILE, "a+"); if (log == NULL) return -1; fprintf(log, "%s\n", str); fclose(log); return 0; } */ void main() { SERVICE_TABLE_ENTRY ServiceTable[2]; ServiceTable[0].lpServiceName = "MemoryStatus"; ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[1].lpServiceName = NULL; ServiceTable[1].lpServiceProc = NULL; // Start the control dispatcher thread for our service StartServiceCtrlDispatcher(ServiceTable); } void ServiceMain(int argc, char** argv) { //int error; ServiceStatus.dwServiceType = SERVICE_WIN32; ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; hStatus = RegisterServiceCtrlHandler( "MemoryStatus", (LPHANDLER_FUNCTION)ControlHandler); if (hStatus == (SERVICE_STATUS_HANDLE)0) { // Registering Control Handler failed return; } // Initialize Service /* error = InitService(); if (error) { // Initialization failed ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = -1; SetServiceStatus(hStatus, &ServiceStatus); return; } */ // We report the running status to SCM. ServiceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus (hStatus, &ServiceStatus); /* int ecrire=1; int result=0; char pchar[10]; */ //MEMORYSTATUS memory; // The worker loop of a service while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) { // if (ecrire) { //------------------------ c'est ici le code !! --------------------------------- /* result=*/system("mountvol.exe h: /d"); ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = 0; SetServiceStatus(hStatus, &ServiceStatus); return; //------------------------ /c'est ici le code !! -------------------------------- // sprintf(pchar,"%d",result); // WriteToLog(pchar); // ecrire=0; } /* char buffer[16]; GlobalMemoryStatus(&memory); sprintf(buffer, "%d", memory.dwAvailPhys); int result = WriteToLog(buffer); if (result) { ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = -1; SetServiceStatus(hStatus, &ServiceStatus); return; } Sleep(SLEEP_TIME); */ } return; } // Service initialization /* int InitService() { int result; result = WriteToLog("Monitoring started."); return(result); } */ // Control handler function void ControlHandler(DWORD request) { switch(request) { case SERVICE_CONTROL_STOP: // WriteToLog("Monitoring stopped."); ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus (hStatus, &ServiceStatus); return; case SERVICE_CONTROL_SHUTDOWN: // WriteToLog("Monitoring stopped."); ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus (hStatus, &ServiceStatus); return; default: break; } // Report current status SetServiceStatus (hStatus, &ServiceStatus); return; }
Notes :

[1mais dont l’expertise en cours ce jour orientera peut être plus sur une pression politique qu’un défaut du logiciel

A télécharger

Pas de documents à télécharger pour cet article


Site réalisé sous SPIP
avec le squelette ESCAL-V3
Version : 3.70.61